passenger 4.0.20 → 4.0.21

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (496) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.gitignore +1 -0
  5. data/.travis.yml +1 -1
  6. data/NEWS +15 -0
  7. data/README.md +5 -3
  8. data/Rakefile +1 -0
  9. data/bin/passenger-config +1 -5
  10. data/bin/passenger-install-apache2-module +53 -5
  11. data/bin/passenger-install-nginx-module +19 -6
  12. data/bin/passenger-memory-stats +3 -3
  13. data/build/agents.rb +11 -8
  14. data/build/apache2.rb +9 -5
  15. data/build/basics.rb +15 -21
  16. data/build/common_library.rb +16 -6
  17. data/build/cplusplus_support.rb +5 -5
  18. data/build/cxx_tests.rb +3 -3
  19. data/build/documentation.rb +1 -1
  20. data/build/misc.rb +4 -37
  21. data/build/node_tests.rb +29 -0
  22. data/build/oxt_tests.rb +1 -1
  23. data/build/packaging.rb +29 -10
  24. data/build/preprocessor.rb +2 -1
  25. data/build/test_basics.rb +15 -6
  26. data/debian.template/locations.ini.template +1 -0
  27. data/debian.template/passenger.install.template +1 -0
  28. data/dev/copy_boost_headers.rb +7 -3
  29. data/dev/run_travis.sh +32 -16
  30. data/doc/Users guide Apache.idmap.txt +22 -34
  31. data/doc/Users guide Apache.txt +20 -234
  32. data/doc/Users guide Nginx.idmap.txt +84 -66
  33. data/doc/Users guide Nginx.txt +50 -1
  34. data/doc/Users guide Standalone.idmap.txt +74 -0
  35. data/doc/Users guide Standalone.txt +22 -9
  36. data/doc/Users guide.txt +51 -0
  37. data/doc/users_guide_snippets/environment_variables.txt +0 -3
  38. data/doc/users_guide_snippets/installation.txt +337 -380
  39. data/doc/users_guide_snippets/installation/run_installer.txt +58 -0
  40. data/doc/users_guide_snippets/installation/verify_running_epilogue.txt +6 -0
  41. data/doc/users_guide_snippets/support_information.txt +2 -9
  42. data/doc/users_guide_snippets/troubleshooting/default.txt +112 -0
  43. data/doc/users_guide_snippets/troubleshooting/rails.txt +56 -0
  44. data/doc/users_guide_snippets/where_to_get_support.txt +9 -0
  45. data/ext/apache2/Bucket.h +1 -1
  46. data/ext/apache2/Configuration.hpp +0 -44
  47. data/ext/apache2/CreateDirConfig.cpp +1 -1
  48. data/ext/apache2/CreateDirConfig.cpp.erb +1 -1
  49. data/ext/apache2/Hooks.cpp +28 -21
  50. data/ext/apache2/MergeDirConfig.cpp +1 -0
  51. data/ext/apache2/MergeDirConfig.cpp.erb +1 -1
  52. data/ext/apache2/SetHeaders.cpp +73 -0
  53. data/ext/apache2/SetHeaders.cpp.erb +88 -0
  54. data/ext/boost/algorithm/string/detail/find_format.hpp +5 -5
  55. data/ext/boost/algorithm/string/detail/find_format_all.hpp +5 -5
  56. data/ext/boost/algorithm/string/detail/finder.hpp +1 -1
  57. data/ext/boost/algorithm/string/formatter.hpp +2 -2
  58. data/ext/boost/assert.hpp +6 -1
  59. data/ext/boost/atomic.hpp +18 -0
  60. data/ext/boost/atomic/atomic.hpp +241 -0
  61. data/ext/boost/atomic/detail/base.hpp +585 -0
  62. data/ext/boost/atomic/detail/cas32strong.hpp +885 -0
  63. data/ext/boost/atomic/detail/cas32weak.hpp +947 -0
  64. data/ext/boost/atomic/detail/cas64strong.hpp +443 -0
  65. data/ext/boost/atomic/detail/config.hpp +54 -0
  66. data/ext/boost/atomic/detail/gcc-alpha.hpp +368 -0
  67. data/ext/boost/atomic/detail/gcc-armv6plus.hpp +252 -0
  68. data/ext/boost/atomic/detail/gcc-cas.hpp +157 -0
  69. data/ext/boost/atomic/detail/gcc-ppc.hpp +2850 -0
  70. data/ext/boost/atomic/detail/gcc-sparcv9.hpp +1259 -0
  71. data/ext/boost/atomic/detail/gcc-x86.hpp +1766 -0
  72. data/ext/boost/atomic/detail/generic-cas.hpp +206 -0
  73. data/ext/boost/atomic/detail/interlocked.hpp +200 -0
  74. data/ext/boost/atomic/detail/linux-arm.hpp +189 -0
  75. data/ext/boost/atomic/detail/lockpool.hpp +97 -0
  76. data/ext/boost/atomic/detail/platform.hpp +62 -0
  77. data/ext/boost/atomic/detail/type-classification.hpp +45 -0
  78. data/ext/boost/chrono/config.hpp +8 -3
  79. data/ext/boost/chrono/duration.hpp +9 -10
  80. data/ext/boost/chrono/system_clocks.hpp +1 -1
  81. data/ext/boost/chrono/time_point.hpp +4 -3
  82. data/ext/boost/config/auto_link.hpp +53 -52
  83. data/ext/boost/config/compiler/borland.hpp +1 -0
  84. data/ext/boost/config/compiler/clang.hpp +24 -1
  85. data/ext/boost/config/compiler/codegear.hpp +1 -0
  86. data/ext/boost/config/compiler/common_edg.hpp +1 -0
  87. data/ext/boost/config/compiler/cray.hpp +1 -0
  88. data/ext/boost/config/compiler/digitalmars.hpp +1 -0
  89. data/ext/boost/config/compiler/gcc.hpp +29 -3
  90. data/ext/boost/config/compiler/gcc_xml.hpp +2 -1
  91. data/ext/boost/config/compiler/hp_acc.hpp +1 -0
  92. data/ext/boost/config/compiler/intel.hpp +1 -1
  93. data/ext/boost/config/compiler/metrowerks.hpp +1 -0
  94. data/ext/boost/config/compiler/mpw.hpp +1 -0
  95. data/ext/boost/config/compiler/pathscale.hpp +1 -0
  96. data/ext/boost/config/compiler/pgi.hpp +1 -0
  97. data/ext/boost/config/compiler/sunpro_cc.hpp +1 -0
  98. data/ext/boost/config/compiler/vacpp.hpp +3 -2
  99. data/ext/boost/config/compiler/visualc.hpp +25 -11
  100. data/ext/boost/config/platform/vxworks.hpp +353 -15
  101. data/ext/boost/config/select_compiler_config.hpp +4 -4
  102. data/ext/boost/config/stdlib/dinkumware.hpp +10 -3
  103. data/ext/boost/config/stdlib/libstdcpp3.hpp +2 -1
  104. data/ext/boost/config/suffix.hpp +45 -19
  105. data/ext/boost/date_time/format_date_parser.hpp +1 -11
  106. data/ext/boost/date_time/strings_from_facet.hpp +5 -3
  107. data/ext/boost/detail/atomic_redef_macros.hpp +19 -0
  108. data/ext/boost/detail/atomic_undef_macros.hpp +39 -0
  109. data/ext/boost/detail/endian.hpp +52 -4
  110. data/ext/boost/detail/scoped_enum_emulation.hpp +10 -10
  111. data/ext/boost/detail/select_type.hpp +36 -0
  112. data/ext/boost/exception/current_exception_cast.hpp +1 -1
  113. data/ext/boost/exception/detail/error_info_impl.hpp +3 -5
  114. data/ext/boost/exception/detail/exception_ptr.hpp +3 -3
  115. data/ext/boost/exception/detail/is_output_streamable.hpp +1 -1
  116. data/ext/boost/exception/detail/object_hex_dump.hpp +1 -1
  117. data/ext/boost/exception/detail/type_info.hpp +1 -1
  118. data/ext/boost/exception/diagnostic_information.hpp +15 -14
  119. data/ext/boost/exception/exception.hpp +1 -1
  120. data/ext/boost/exception/get_error_info.hpp +1 -1
  121. data/ext/boost/exception/info.hpp +12 -13
  122. data/ext/boost/exception/to_string.hpp +6 -1
  123. data/ext/boost/exception/to_string_stub.hpp +9 -1
  124. data/ext/boost/foreach.hpp +5 -5
  125. data/ext/boost/function/function_template.hpp +6 -6
  126. data/ext/boost/functional/hash/detail/float_functions.hpp +90 -0
  127. data/ext/boost/functional/hash/detail/hash_float.hpp +11 -2
  128. data/ext/boost/functional/hash/extensions.hpp +14 -2
  129. data/ext/boost/functional/hash/hash.hpp +26 -5
  130. data/ext/boost/get_pointer.hpp +17 -2
  131. data/ext/boost/integer_traits.hpp +1 -1
  132. data/ext/boost/lexical_cast.hpp +615 -395
  133. data/ext/boost/libs/atomic/lockpool.cpp +24 -0
  134. data/ext/boost/libs/system/src/error_code.cpp +25 -18
  135. data/ext/boost/libs/thread/src/future.cpp +7 -5
  136. data/ext/boost/libs/thread/src/pthread/once.cpp +9 -3
  137. data/ext/boost/libs/thread/src/pthread/once_atomic.cpp +90 -0
  138. data/ext/boost/libs/thread/src/pthread/thread.cpp +129 -95
  139. data/ext/boost/libs/thread/src/pthread/timeconv.inl +20 -1
  140. data/ext/boost/limits.hpp +1 -1
  141. data/ext/boost/math/policies/policy.hpp +10 -0
  142. data/ext/boost/math/special_functions/detail/round_fwd.hpp +17 -4
  143. data/ext/boost/math/special_functions/fpclassify.hpp +114 -45
  144. data/ext/boost/math/special_functions/math_fwd.hpp +195 -83
  145. data/ext/boost/math/special_functions/sign.hpp +13 -8
  146. data/ext/boost/math/tools/config.hpp +38 -16
  147. data/ext/boost/move/algorithm.hpp +275 -0
  148. data/ext/boost/move/core.hpp +332 -0
  149. data/ext/boost/move/detail/config_begin.hpp +23 -0
  150. data/ext/boost/move/detail/config_end.hpp +20 -0
  151. data/ext/boost/move/detail/meta_utils.hpp +158 -0
  152. data/ext/boost/move/iterator.hpp +298 -0
  153. data/ext/boost/move/move.hpp +10 -1256
  154. data/ext/boost/move/traits.hpp +142 -0
  155. data/ext/boost/move/utility.hpp +194 -0
  156. data/ext/boost/mpl/assert.hpp +72 -4
  157. data/ext/boost/noncopyable.hpp +15 -3
  158. data/ext/boost/pointer_to_other.hpp +55 -0
  159. data/ext/boost/range/concepts.hpp +4 -4
  160. data/ext/boost/range/detail/extract_optional_type.hpp +1 -1
  161. data/ext/boost/range/empty.hpp +1 -1
  162. data/ext/boost/range/iterator_range_core.hpp +4 -1
  163. data/ext/boost/range/iterator_range_io.hpp +2 -2
  164. data/ext/boost/ratio/config.hpp +6 -0
  165. data/ext/boost/ratio/detail/overflow_helpers.hpp +2 -2
  166. data/ext/boost/smart_ptr/allocate_shared_array.hpp +250 -0
  167. data/ext/boost/smart_ptr/detail/allocate_array_helper.hpp +169 -0
  168. data/ext/boost/smart_ptr/detail/array_deleter.hpp +124 -0
  169. data/ext/boost/smart_ptr/detail/array_traits.hpp +53 -0
  170. data/ext/boost/smart_ptr/detail/array_utility.hpp +178 -0
  171. data/ext/boost/smart_ptr/detail/make_array_helper.hpp +157 -0
  172. data/ext/boost/smart_ptr/detail/operator_bool.hpp +16 -9
  173. data/ext/boost/smart_ptr/detail/shared_count.hpp +78 -7
  174. data/ext/boost/smart_ptr/detail/sp_convertible.hpp +15 -0
  175. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +12 -6
  176. data/ext/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +1 -0
  177. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +1 -0
  178. data/ext/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +1 -0
  179. data/ext/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +1 -0
  180. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +1 -0
  181. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +1 -0
  182. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +1 -0
  183. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +1 -0
  184. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +1 -0
  185. data/ext/boost/smart_ptr/detail/sp_counted_base_nt.hpp +1 -0
  186. data/ext/boost/smart_ptr/detail/sp_counted_base_pt.hpp +1 -0
  187. data/ext/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +162 -0
  188. data/ext/boost/smart_ptr/detail/sp_counted_base_solaris.hpp +1 -0
  189. data/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp +1 -0
  190. data/ext/boost/smart_ptr/detail/sp_counted_base_sync.hpp +1 -0
  191. data/ext/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +1 -0
  192. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +15 -0
  193. data/ext/boost/smart_ptr/detail/sp_forward.hpp +39 -0
  194. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +19 -3
  195. data/ext/boost/smart_ptr/detail/sp_if_array.hpp +31 -0
  196. data/ext/boost/smart_ptr/detail/sp_nullptr_t.hpp +45 -0
  197. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +5 -12
  198. data/ext/boost/smart_ptr/enable_shared_from_this.hpp +4 -4
  199. data/ext/boost/smart_ptr/make_shared.hpp +5 -1060
  200. data/ext/boost/smart_ptr/make_shared_array.hpp +247 -0
  201. data/ext/boost/smart_ptr/make_shared_object.hpp +1128 -0
  202. data/ext/boost/smart_ptr/scoped_array.hpp +32 -7
  203. data/ext/boost/smart_ptr/scoped_ptr.hpp +31 -5
  204. data/ext/boost/smart_ptr/shared_array.hpp +135 -20
  205. data/ext/boost/smart_ptr/shared_ptr.hpp +444 -126
  206. data/ext/boost/smart_ptr/weak_ptr.hpp +39 -28
  207. data/ext/boost/static_assert.hpp +74 -17
  208. data/ext/boost/system/error_code.hpp +76 -68
  209. data/ext/boost/system/system_error.hpp +5 -1
  210. data/ext/boost/thread/barrier.hpp +6 -2
  211. data/ext/boost/thread/completion_latch.hpp +233 -0
  212. data/ext/boost/thread/condition.hpp +6 -1
  213. data/ext/boost/thread/detail/async_func.hpp +571 -0
  214. data/ext/boost/thread/detail/config.hpp +248 -40
  215. data/ext/boost/thread/detail/counter.hpp +93 -0
  216. data/ext/boost/thread/detail/delete.hpp +12 -0
  217. data/ext/boost/thread/detail/invoke.hpp +1351 -0
  218. data/ext/boost/thread/detail/is_convertible.hpp +48 -0
  219. data/ext/boost/thread/detail/lockable_wrapper.hpp +45 -0
  220. data/ext/boost/thread/detail/log.hpp +83 -0
  221. data/ext/boost/thread/detail/make_tuple_indices.hpp +224 -0
  222. data/ext/boost/thread/detail/move.hpp +32 -16
  223. data/ext/boost/thread/detail/thread.hpp +236 -41
  224. data/ext/boost/thread/detail/thread_group.hpp +55 -9
  225. data/ext/boost/thread/detail/thread_interruption.hpp +4 -1
  226. data/ext/boost/thread/exceptions.hpp +2 -0
  227. data/ext/boost/thread/externally_locked.hpp +351 -0
  228. data/ext/boost/thread/externally_locked_stream.hpp +170 -0
  229. data/ext/boost/thread/future.hpp +2517 -455
  230. data/ext/boost/thread/future_error_code.hpp +61 -0
  231. data/ext/boost/thread/is_locked_by_this_thread.hpp +39 -0
  232. data/ext/boost/thread/latch.hpp +142 -0
  233. data/ext/boost/thread/lock_algorithms.hpp +468 -0
  234. data/ext/boost/thread/lock_concepts.hpp +197 -0
  235. data/ext/boost/thread/lock_factories.hpp +78 -0
  236. data/ext/boost/thread/lock_guard.hpp +88 -0
  237. data/ext/boost/thread/lock_options.hpp +31 -0
  238. data/ext/boost/thread/lock_traits.hpp +45 -0
  239. data/ext/boost/thread/lock_types.hpp +1226 -0
  240. data/ext/boost/thread/lockable_adapter.hpp +226 -0
  241. data/ext/boost/thread/lockable_concepts.hpp +157 -0
  242. data/ext/boost/thread/lockable_traits.hpp +207 -0
  243. data/ext/boost/thread/locks.hpp +5 -1816
  244. data/ext/boost/thread/mutex.hpp +33 -1
  245. data/ext/boost/thread/null_mutex.hpp +243 -0
  246. data/ext/boost/thread/once.hpp +10 -1
  247. data/ext/boost/thread/poly_lockable.hpp +68 -0
  248. data/ext/boost/thread/poly_lockable_adapter.hpp +89 -0
  249. data/ext/boost/thread/poly_shared_lockable.hpp +135 -0
  250. data/ext/boost/thread/poly_shared_lockable_adapter.hpp +170 -0
  251. data/ext/boost/thread/pthread/condition_variable.hpp +74 -26
  252. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +54 -27
  253. data/ext/boost/thread/pthread/mutex.hpp +101 -38
  254. data/ext/boost/thread/pthread/once.hpp +459 -44
  255. data/ext/boost/thread/pthread/once_atomic.hpp +313 -0
  256. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -10
  257. data/ext/boost/thread/pthread/shared_mutex.hpp +226 -61
  258. data/ext/boost/thread/pthread/shared_mutex_assert.hpp +724 -0
  259. data/ext/boost/thread/pthread/thread_data.hpp +53 -50
  260. data/ext/boost/thread/pthread/timespec.hpp +96 -12
  261. data/ext/boost/thread/recursive_mutex.hpp +44 -1
  262. data/ext/boost/thread/reverse_lock.hpp +3 -2
  263. data/ext/boost/thread/scoped_thread.hpp +285 -0
  264. data/ext/boost/thread/shared_lock_guard.hpp +2 -1
  265. data/ext/boost/thread/shared_mutex.hpp +23 -0
  266. data/ext/boost/thread/strict_lock.hpp +235 -0
  267. data/ext/boost/thread/sync_bounded_queue.hpp +594 -0
  268. data/ext/boost/thread/sync_queue.hpp +516 -0
  269. data/ext/boost/thread/synchronized_value.hpp +1001 -0
  270. data/ext/boost/thread/testable_mutex.hpp +148 -0
  271. data/ext/boost/thread/thread.hpp +1 -13
  272. data/ext/boost/thread/thread_functors.hpp +57 -0
  273. data/ext/boost/thread/thread_guard.hpp +46 -0
  274. data/ext/boost/thread/thread_only.hpp +29 -0
  275. data/ext/boost/thread/v2/shared_mutex.hpp +1062 -0
  276. data/ext/boost/thread/v2/thread.hpp +37 -10
  277. data/ext/boost/thread/xtime.hpp +2 -1
  278. data/ext/boost/token_functions.hpp +16 -16
  279. data/ext/boost/type_traits/add_lvalue_reference.hpp +26 -0
  280. data/ext/boost/type_traits/add_reference.hpp +1 -1
  281. data/ext/boost/type_traits/add_rvalue_reference.hpp +4 -4
  282. data/ext/boost/type_traits/aligned_storage.hpp +13 -0
  283. data/ext/boost/type_traits/common_type.hpp +11 -12
  284. data/ext/boost/type_traits/config.hpp +1 -1
  285. data/ext/boost/type_traits/detail/common_type_imp.hpp +1 -1
  286. data/ext/boost/type_traits/detail/has_binary_operator.hpp +1 -1
  287. data/ext/boost/type_traits/detail/is_function_ptr_tester.hpp +1 -1
  288. data/ext/boost/type_traits/has_left_shift.hpp +49 -0
  289. data/ext/boost/type_traits/has_right_shift.hpp +49 -0
  290. data/ext/boost/type_traits/has_trivial_move_assign.hpp +57 -0
  291. data/ext/boost/type_traits/has_trivial_move_constructor.hpp +57 -0
  292. data/ext/boost/type_traits/intrinsics.hpp +18 -2
  293. data/ext/boost/type_traits/is_abstract.hpp +1 -1
  294. data/ext/boost/type_traits/is_array.hpp +1 -1
  295. data/ext/boost/type_traits/is_const.hpp +1 -1
  296. data/ext/boost/type_traits/is_convertible.hpp +78 -17
  297. data/ext/boost/type_traits/is_function.hpp +6 -1
  298. data/ext/boost/type_traits/is_integral.hpp +6 -1
  299. data/ext/boost/type_traits/is_nothrow_move_assignable.hpp +84 -0
  300. data/ext/boost/type_traits/is_nothrow_move_constructible.hpp +84 -0
  301. data/ext/boost/type_traits/is_pod.hpp +3 -1
  302. data/ext/boost/type_traits/is_rvalue_reference.hpp +1 -1
  303. data/ext/boost/type_traits/is_volatile.hpp +1 -1
  304. data/ext/boost/type_traits/make_signed.hpp +153 -0
  305. data/ext/boost/type_traits/make_unsigned.hpp +16 -0
  306. data/ext/boost/type_traits/remove_const.hpp +1 -1
  307. data/ext/boost/type_traits/remove_cv.hpp +1 -1
  308. data/ext/boost/type_traits/remove_reference.hpp +1 -1
  309. data/ext/boost/type_traits/remove_volatile.hpp +1 -1
  310. data/ext/boost/unordered/detail/allocate.hpp +1120 -0
  311. data/ext/boost/unordered/detail/buckets.hpp +876 -0
  312. data/ext/boost/unordered/detail/equivalent.hpp +680 -0
  313. data/ext/boost/unordered/detail/extract_key.hpp +183 -0
  314. data/ext/boost/unordered/detail/fwd.hpp +23 -0
  315. data/ext/boost/unordered/detail/table.hpp +861 -0
  316. data/ext/boost/unordered/detail/unique.hpp +622 -0
  317. data/ext/boost/unordered/detail/util.hpp +260 -0
  318. data/ext/boost/unordered/unordered_map.hpp +1652 -0
  319. data/ext/boost/unordered/unordered_map_fwd.hpp +65 -0
  320. data/ext/boost/unordered/unordered_set.hpp +1549 -0
  321. data/ext/boost/unordered/unordered_set_fwd.hpp +63 -0
  322. data/ext/boost/unordered_map.hpp +18 -0
  323. data/ext/boost/unordered_set.hpp +18 -0
  324. data/ext/boost/utility/addressof.hpp +2 -2
  325. data/ext/boost/utility/result_of.hpp +8 -1
  326. data/ext/boost/version.hpp +2 -2
  327. data/ext/common/Account.h +1 -1
  328. data/ext/common/AccountsDatabase.h +1 -1
  329. data/ext/common/AgentsStarter.cpp +3 -1
  330. data/ext/common/AgentsStarter.h +2 -2
  331. data/ext/common/ApplicationPool2/AppTypes.cpp +24 -6
  332. data/ext/common/ApplicationPool2/AppTypes.h +17 -8
  333. data/ext/common/ApplicationPool2/Common.h +12 -12
  334. data/ext/common/ApplicationPool2/DirectSpawner.h +2 -2
  335. data/ext/common/ApplicationPool2/DummySpawner.h +3 -3
  336. data/ext/common/ApplicationPool2/Group.h +6 -6
  337. data/ext/common/ApplicationPool2/Implementation.cpp +19 -19
  338. data/ext/common/ApplicationPool2/PipeWatcher.h +5 -5
  339. data/ext/common/ApplicationPool2/Pool.h +21 -21
  340. data/ext/common/ApplicationPool2/Process.h +6 -6
  341. data/ext/common/ApplicationPool2/Session.h +1 -1
  342. data/ext/common/ApplicationPool2/SmartSpawner.h +24 -12
  343. data/ext/common/ApplicationPool2/Socket.h +2 -2
  344. data/ext/common/ApplicationPool2/Spawner.h +64 -14
  345. data/ext/common/ApplicationPool2/SpawnerFactory.h +7 -7
  346. data/ext/common/ApplicationPool2/SuperGroup.h +5 -5
  347. data/ext/common/BackgroundEventLoop.cpp +4 -4
  348. data/ext/common/BackgroundEventLoop.h +1 -1
  349. data/ext/common/Constants.h +13 -1
  350. data/ext/common/EventedBufferedInput.h +8 -8
  351. data/ext/common/Exceptions.cpp +71 -0
  352. data/ext/common/Exceptions.h +60 -7
  353. data/ext/common/FileDescriptor.h +4 -4
  354. data/ext/common/MessageClient.h +1 -1
  355. data/ext/common/MessageServer.h +5 -5
  356. data/ext/common/MultiLibeio.cpp +3 -3
  357. data/ext/common/MultiLibeio.h +2 -2
  358. data/ext/common/RandomGenerator.h +11 -11
  359. data/ext/common/ResourceLocator.h +8 -1
  360. data/ext/common/SafeLibev.h +12 -12
  361. data/ext/common/ServerInstanceDir.h +11 -3
  362. data/ext/common/UnionStation.h +10 -10
  363. data/ext/common/Utils.cpp +11 -13
  364. data/ext/common/Utils.h +9 -9
  365. data/ext/common/Utils/BlockingQueue.h +10 -10
  366. data/ext/common/Utils/BufferedIO.h +1 -1
  367. data/ext/common/Utils/CachedFileStat.hpp +2 -2
  368. data/ext/common/Utils/FileChangeChecker.h +1 -1
  369. data/ext/common/Utils/HashMap.h +13 -4
  370. data/ext/common/Utils/IOUtils.cpp +33 -10
  371. data/ext/common/Utils/IniFile.h +3 -3
  372. data/ext/common/Utils/Lock.h +2 -2
  373. data/ext/common/Utils/MessagePassing.h +10 -10
  374. data/ext/common/Utils/ProcessMetricsCollector.h +24 -6
  375. data/ext/common/Utils/ScopeGuard.h +5 -5
  376. data/ext/common/Utils/jsoncpp.cpp +2 -0
  377. data/ext/common/agents/HelperAgent/FileBackedPipe.h +26 -26
  378. data/ext/common/agents/HelperAgent/Main.cpp +18 -18
  379. data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
  380. data/ext/common/agents/HelperAgent/RequestHandler.h +30 -21
  381. data/ext/common/agents/LoggingAgent/AdminController.h +1 -1
  382. data/ext/common/agents/LoggingAgent/FilterSupport.h +13 -11
  383. data/ext/common/agents/LoggingAgent/LoggingServer.h +11 -11
  384. data/ext/common/agents/LoggingAgent/Main.cpp +9 -9
  385. data/ext/common/agents/LoggingAgent/RemoteSender.h +3 -3
  386. data/ext/common/agents/SpawnPreparer.cpp +1 -0
  387. data/ext/common/agents/Watchdog/AgentWatcher.cpp +8 -7
  388. data/ext/common/agents/Watchdog/Main.cpp +81 -73
  389. data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +1 -1
  390. data/ext/libev/Changes +57 -0
  391. data/ext/libev/LICENSE +2 -1
  392. data/ext/libev/Makefile.in +110 -50
  393. data/ext/libev/README +8 -8
  394. data/ext/libev/aclocal.m4 +1503 -861
  395. data/ext/libev/config.guess +290 -304
  396. data/ext/libev/config.sub +77 -198
  397. data/ext/libev/configure +1735 -890
  398. data/ext/libev/configure.ac +3 -2
  399. data/ext/libev/ev++.h +6 -6
  400. data/ext/libev/ev.c +541 -214
  401. data/ext/libev/ev.h +106 -100
  402. data/ext/libev/ev_epoll.c +1 -1
  403. data/ext/libev/ev_kqueue.c +20 -4
  404. data/ext/libev/ev_vars.h +15 -16
  405. data/ext/libev/ev_win32.c +12 -2
  406. data/ext/libev/ev_wrap.h +162 -160
  407. data/ext/libev/event.c +29 -6
  408. data/ext/libev/event.h +9 -2
  409. data/ext/libev/ltmain.sh +2632 -1384
  410. data/ext/nginx/ConfigurationCommands.c +1 -1
  411. data/ext/nginx/ConfigurationCommands.c.erb +3 -1
  412. data/ext/nginx/ContentHandler.c +25 -2
  413. data/ext/nginx/CreateLocationConfig.c +1 -0
  414. data/ext/nginx/CreateLocationConfig.c.erb +1 -1
  415. data/ext/nginx/MergeLocationConfig.c +1 -0
  416. data/ext/nginx/MergeLocationConfig.c.erb +1 -1
  417. data/ext/nginx/config +12 -0
  418. data/ext/oxt/dynamic_thread_group.hpp +7 -4
  419. data/ext/oxt/system_calls.cpp +5 -1
  420. data/ext/oxt/system_calls.hpp +3 -0
  421. data/helper-scripts/node-loader.js +117 -249
  422. data/lib/phusion_passenger.rb +27 -5
  423. data/lib/phusion_passenger/abstract_installer.rb +104 -9
  424. data/lib/phusion_passenger/admin_tools/memory_stats.rb +10 -9
  425. data/lib/phusion_passenger/apache2/config_options.rb +6 -3
  426. data/lib/phusion_passenger/common_library.rb +7 -1
  427. data/lib/phusion_passenger/constants.rb +6 -0
  428. data/lib/phusion_passenger/loader_shared_helpers.rb +7 -4
  429. data/lib/phusion_passenger/nginx/config_options.rb +2 -1
  430. data/lib/phusion_passenger/packaging.rb +3 -0
  431. data/lib/phusion_passenger/platform_info/apache.rb +43 -6
  432. data/lib/phusion_passenger/platform_info/apache_detector.rb +15 -5
  433. data/lib/phusion_passenger/platform_info/compiler.rb +167 -32
  434. data/lib/phusion_passenger/platform_info/cxx_portability.rb +133 -77
  435. data/lib/phusion_passenger/platform_info/depcheck.rb +17 -7
  436. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +3 -3
  437. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
  438. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -6
  439. data/lib/phusion_passenger/platform_info/linux.rb +2 -1
  440. data/lib/phusion_passenger/platform_info/operating_system.rb +1 -1
  441. data/lib/phusion_passenger/platform_info/ruby.rb +18 -3
  442. data/lib/phusion_passenger/standalone/runtime_installer.rb +6 -2
  443. data/lib/phusion_passenger/standalone/start_command.rb +8 -2
  444. data/lib/phusion_passenger/utils/ansi_colors.rb +9 -0
  445. data/lib/phusion_passenger/utils/hosts_file_parser.rb +4 -2
  446. data/node_lib/phusion_passenger/httplib_emulation.js +141 -0
  447. data/node_lib/phusion_passenger/line_reader.js +154 -0
  448. data/node_lib/phusion_passenger/request_handler.js +65 -0
  449. data/node_lib/phusion_passenger/session_protocol_parser.js +113 -0
  450. data/resources/templates/apache2/deployment_example.txt.erb +2 -1
  451. data/resources/templates/apache2/installing_against_a_different_apache.txt.erb +14 -0
  452. data/resources/templates/apache2/multiple_apache_installations_detected.txt.erb +15 -0
  453. data/resources/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
  454. data/resources/templates/general_error_with_html.html.template +1 -1
  455. data/resources/templates/installer_common/gem_install_permission_problems.txt.erb +17 -0
  456. data/resources/templates/installer_common/low_amount_of_memory_warning.txt.erb +6 -4
  457. data/resources/templates/installer_common/world_inaccessible_directories.txt.erb +16 -0
  458. data/resources/templates/nginx/deployment_example.txt.erb +2 -1
  459. data/resources/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
  460. data/resources/templates/standalone/config.erb +1 -0
  461. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +3 -3
  462. data/test/cxx/ApplicationPool2/PoolTest.cpp +4 -4
  463. data/test/cxx/ApplicationPool2/ProcessTest.cpp +5 -5
  464. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +5 -5
  465. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +1 -1
  466. data/test/cxx/EventedBufferedInputTest.cpp +6 -6
  467. data/test/cxx/FileBackedPipeTest.cpp +1 -1
  468. data/test/cxx/MessagePassingTest.cpp +1 -1
  469. data/test/cxx/MessageServerTest.cpp +4 -4
  470. data/test/cxx/RequestHandlerTest.cpp +7 -7
  471. data/test/cxx/UnionStationTest.cpp +2 -2
  472. data/test/node/line_reader_spec.js +338 -0
  473. data/test/node/spec_helper.js +27 -0
  474. data/test/ruby/standalone/runtime_installer_spec.rb +2 -1
  475. metadata +131 -22
  476. metadata.gz.asc +7 -7
  477. data/ext/boost/functional/hash/detail/container_fwd_0x.hpp +0 -29
  478. data/ext/boost/lambda/core.hpp +0 -79
  479. data/ext/boost/lambda/detail/actions.hpp +0 -174
  480. data/ext/boost/lambda/detail/arity_code.hpp +0 -110
  481. data/ext/boost/lambda/detail/function_adaptors.hpp +0 -789
  482. data/ext/boost/lambda/detail/is_instance_of.hpp +0 -104
  483. data/ext/boost/lambda/detail/lambda_config.hpp +0 -48
  484. data/ext/boost/lambda/detail/lambda_functor_base.hpp +0 -615
  485. data/ext/boost/lambda/detail/lambda_functors.hpp +0 -324
  486. data/ext/boost/lambda/detail/lambda_fwd.hpp +0 -74
  487. data/ext/boost/lambda/detail/lambda_traits.hpp +0 -578
  488. data/ext/boost/lambda/detail/member_ptr.hpp +0 -737
  489. data/ext/boost/lambda/detail/operator_actions.hpp +0 -139
  490. data/ext/boost/lambda/detail/operator_lambda_func_base.hpp +0 -271
  491. data/ext/boost/lambda/detail/operator_return_type_traits.hpp +0 -917
  492. data/ext/boost/lambda/detail/operators.hpp +0 -370
  493. data/ext/boost/lambda/detail/ret.hpp +0 -325
  494. data/ext/boost/lambda/detail/return_type_traits.hpp +0 -282
  495. data/ext/boost/lambda/detail/select_functions.hpp +0 -74
  496. data/ext/boost/lambda/lambda.hpp +0 -34
@@ -35,7 +35,7 @@ namespace tut {
35
35
  resetOnData = false;
36
36
  consumeCallbackCount = 0;
37
37
  ended = false;
38
- pipe = make_shared<FileBackedPipe>("tmp.pipe");
38
+ pipe = boost::make_shared<FileBackedPipe>("tmp.pipe");
39
39
  pipe->userData = this;
40
40
  pipe->onData = onData;
41
41
  pipe->onEnd = onEnd;
@@ -11,7 +11,7 @@ namespace tut {
11
11
  MessageBoxPtr box;
12
12
 
13
13
  MessagePassingTest() {
14
- box = make_shared<MessageBox>();
14
+ box = boost::make_shared<MessageBox>();
15
15
  }
16
16
 
17
17
  void sendMessagesLater() {
@@ -23,8 +23,8 @@ namespace tut {
23
23
  string socketAddress;
24
24
  AccountsDatabasePtr accountsDatabase;
25
25
  AccountPtr clientAccount;
26
- shared_ptr<MessageServer> server;
27
- shared_ptr<oxt::thread> serverThread;
26
+ boost::shared_ptr<MessageServer> server;
27
+ boost::shared_ptr<oxt::thread> serverThread;
28
28
 
29
29
  MessageServerTest() {
30
30
  createServerInstanceDirAndGeneration(serverInstanceDir, generation);
@@ -94,7 +94,7 @@ namespace tut {
94
94
  }
95
95
  };
96
96
 
97
- typedef shared_ptr<SpecificContext> SpecificContextPtr;
97
+ typedef boost::shared_ptr<SpecificContext> SpecificContextPtr;
98
98
 
99
99
  boost::mutex mutex;
100
100
  volatile int clientsAccepted;
@@ -134,7 +134,7 @@ namespace tut {
134
134
  }
135
135
  };
136
136
 
137
- typedef shared_ptr<LoggingHandler> LoggingHandlerPtr;
137
+ typedef boost::shared_ptr<LoggingHandler> LoggingHandlerPtr;
138
138
 
139
139
  class ProcessMessageReturnsFalseHandler: public MessageServer::Handler {
140
140
  public:
@@ -32,7 +32,7 @@ namespace tut {
32
32
  SpawnerFactoryPtr spawnerFactory;
33
33
  PoolPtr pool;
34
34
  Pool::DebugSupportPtr debug;
35
- shared_ptr<RequestHandler> handler;
35
+ boost::shared_ptr<RequestHandler> handler;
36
36
  FileDescriptor connection;
37
37
  map<string, string> defaultHeaders;
38
38
 
@@ -41,8 +41,8 @@ namespace tut {
41
41
 
42
42
  RequestHandlerTest() {
43
43
  createServerInstanceDirAndGeneration(serverInstanceDir, generation);
44
- spawnerFactory = make_shared<SpawnerFactory>(bg.safe, *resourceLocator, generation);
45
- pool = make_shared<Pool>(bg.safe.get(), spawnerFactory);
44
+ spawnerFactory = boost::make_shared<SpawnerFactory>(bg.safe, *resourceLocator, generation);
45
+ pool = boost::make_shared<Pool>(bg.safe.get(), spawnerFactory);
46
46
  pool->initialize();
47
47
  serverFilename = generation->getPath() + "/server";
48
48
  requestSocket = createUnixServer(serverFilename);
@@ -72,7 +72,7 @@ namespace tut {
72
72
  }
73
73
 
74
74
  void init() {
75
- handler = make_shared<RequestHandler>(bg.safe, requestSocket, pool, agentOptions);
75
+ handler = boost::make_shared<RequestHandler>(bg.safe, requestSocket, pool, agentOptions);
76
76
  bg.start();
77
77
  }
78
78
 
@@ -270,7 +270,7 @@ namespace tut {
270
270
  // It disconnects us if the connect password is not sent within a certain time.
271
271
  agentOptions.requestSocketPassword = "hello world";
272
272
  setLogLevel(-1);
273
- handler = make_shared<RequestHandler>(bg.safe, requestSocket, pool, agentOptions);
273
+ handler = boost::make_shared<RequestHandler>(bg.safe, requestSocket, pool, agentOptions);
274
274
  handler->connectPasswordTimeout = 40;
275
275
  bg.start();
276
276
 
@@ -839,13 +839,13 @@ namespace tut {
839
839
 
840
840
  // Wait for the original process to finish oobw request.
841
841
  EVENTUALLY(2,
842
- unique_lock<boost::mutex> lock(pool->syncher);
842
+ boost::unique_lock<boost::mutex> lock(pool->syncher);
843
843
  result = origProcess->oobwStatus == Process::OOBW_NOT_ACTIVE;
844
844
  );
845
845
 
846
846
  // Final asserts.
847
847
  {
848
- unique_lock<boost::mutex> lock(pool->syncher);
848
+ boost::unique_lock<boost::mutex> lock(pool->syncher);
849
849
  ensure_equals("2 enabled processes", pool->superGroups.get(wsgiAppPath)->defaultGroup->enabledProcesses.size(), 2u);
850
850
  ensure_equals("oobw is reset", origProcess->oobwStatus, Process::OOBW_NOT_ACTIVE);
851
851
  ensure_equals("process is enabled", origProcess->enabled, Process::ENABLED);
@@ -31,7 +31,7 @@ namespace tut {
31
31
  ev::dynamic_loop eventLoop;
32
32
  FileDescriptor serverFd;
33
33
  LoggingServerPtr server;
34
- shared_ptr<oxt::thread> serverThread;
34
+ boost::shared_ptr<oxt::thread> serverThread;
35
35
  LoggerFactoryPtr factory, factory2, factory3, factory4;
36
36
 
37
37
  UnionStationTest() {
@@ -60,7 +60,7 @@ namespace tut {
60
60
  setLogLevel(0);
61
61
  }
62
62
 
63
- void startLoggingServer(const function<void ()> &initFunc = function<void ()>()) {
63
+ void startLoggingServer(const boost::function<void ()> &initFunc = boost::function<void ()>()) {
64
64
  VariantMap options;
65
65
  options.set("analytics_dump_file", dumpFile);
66
66
  serverFd = createUnixServer(socketFilename.c_str());
@@ -0,0 +1,338 @@
1
+ var Helper = require('./spec_helper').Helper;
2
+ var FakeStream = require('./spec_helper').FakeStream;
3
+ var sinon = require('sinon');
4
+ var should = require('should');
5
+ var assert = require('assert');
6
+ var LineReader = require('phusion_passenger/line_reader').LineReader;
7
+
8
+ describe('LineReader', function() {
9
+ this.timeout(1000);
10
+
11
+ beforeEach(function() {
12
+ this.stream = new FakeStream();
13
+ this.reader = new LineReader(this.stream);
14
+ });
15
+
16
+ it('does nothing when the stream is idle', function(done) {
17
+ var finished;
18
+ this.reader.readLine(function(line) {
19
+ if (!finished) {
20
+ finished = true;
21
+ assert.fail();
22
+ }
23
+ });
24
+ setTimeout(function() {
25
+ if (!finished) {
26
+ finished = true;
27
+ done();
28
+ }
29
+ }, 50);
30
+ });
31
+
32
+ describe('when one partial line has been received', function() {
33
+ beforeEach(function() {
34
+ this.stream.emit('data', 'hello');
35
+ });
36
+
37
+ it('buffers the data', function() {
38
+ this.reader.buffer.should.equal('hello');
39
+ });
40
+
41
+ it('resumes the stream', function() {
42
+ this.stream.paused.should.be.false;
43
+ this.reader.paused.should.be.false;
44
+ });
45
+
46
+ describe('when the rest of the line is received later', function() {
47
+ beforeEach(function() {
48
+ this.stream.emit('data', " world\n");
49
+ });
50
+
51
+ it('memorizes a line', function() {
52
+ this.reader.lines.should.eql(["hello world\n"]);
53
+ });
54
+
55
+ it('empties the buffer', function() {
56
+ this.reader.buffer.should.eql('');
57
+ });
58
+
59
+ it('pauses the stream', function() {
60
+ this.stream.paused.should.be.true;
61
+ this.reader.paused.should.be.true;
62
+ });
63
+ });
64
+
65
+ describe('when the rest of the line, plus a partial line, is received later', function() {
66
+ beforeEach(function() {
67
+ this.stream.emit('data', " world\nhey");
68
+ });
69
+
70
+ it('memorizes a line', function() {
71
+ this.reader.lines.should.eql(["hello world\n"]);
72
+ });
73
+
74
+ it('buffers the partial line', function() {
75
+ this.reader.buffer.should.eql('hey');
76
+ });
77
+
78
+ it('pauses the stream', function() {
79
+ this.stream.paused.should.be.true;
80
+ this.reader.paused.should.be.true;
81
+ });
82
+ });
83
+
84
+ describe('when the rest of the line, plus a full line, is received later', function() {
85
+ beforeEach(function() {
86
+ this.stream.emit('data', " world\nhey\n");
87
+ });
88
+
89
+ it('memorizes two lines', function() {
90
+ this.reader.lines.should.eql(["hello world\n", "hey\n"]);
91
+ });
92
+
93
+ it('empties the buffer', function() {
94
+ this.reader.buffer.should.eql('');
95
+ });
96
+
97
+ it('pauses the stream', function() {
98
+ this.stream.paused.should.be.true;
99
+ this.reader.paused.should.be.true;
100
+ });
101
+ });
102
+ });
103
+
104
+ describe('when one full line has been received', function() {
105
+ beforeEach(function() {
106
+ this.stream.emit('data', "hello world\n");
107
+ });
108
+
109
+ it('memorizes the line', function() {
110
+ this.reader.lines.should.eql(["hello world\n"]);
111
+ });
112
+
113
+ it('empties the buffer', function() {
114
+ this.reader.buffer.should.eql('');
115
+ });
116
+
117
+ it('pauses the stream', function() {
118
+ this.stream.paused.should.be.true;
119
+ this.reader.paused.should.be.true;
120
+ });
121
+ });
122
+
123
+ describe('when multiple full lines have been received', function() {
124
+ beforeEach(function() {
125
+ this.stream.emit('data', "hello world\nhey\n");
126
+ });
127
+
128
+ it('memorizes all lines', function() {
129
+ this.reader.lines.should.eql(["hello world\n", "hey\n"]);
130
+ });
131
+
132
+ it('empties the buffer', function() {
133
+ this.reader.buffer.should.eql('');
134
+ });
135
+
136
+ it('pauses the stream', function() {
137
+ this.stream.paused.should.be.true;
138
+ this.reader.paused.should.be.true;
139
+ });
140
+ });
141
+
142
+ describe('when multiple full lines and one partial line have been received', function() {
143
+ beforeEach(function() {
144
+ this.stream.emit('data', "hello world\nhey\nfoo");
145
+ });
146
+
147
+ it('memorizes all full lines', function() {
148
+ this.reader.lines.should.eql(["hello world\n", "hey\n"]);
149
+ });
150
+
151
+ it('buffers the partial line', function() {
152
+ this.reader.buffer.should.eql('foo');
153
+ });
154
+
155
+ it('pauses the stream', function() {
156
+ this.stream.paused.should.be.true;
157
+ this.reader.paused.should.be.true;
158
+ });
159
+ });
160
+
161
+ describe('on EOF', function() {
162
+ describe('if the buffer is non-empty', function() {
163
+ beforeEach(function() {
164
+ this.reader.buffer = 'hello';
165
+ this.stream.emit('end');
166
+ });
167
+
168
+ it('memorizes the buffer contents as a line', function() {
169
+ this.reader.lines.should.eql(["hello"]);
170
+ });
171
+ });
172
+
173
+ it('marks the reader as having reached EOF', function() {
174
+ this.stream.emit('end');
175
+ this.reader.endReached().should.be.true;
176
+ });
177
+
178
+ it('pauses the stream', function() {
179
+ this.stream.emit('end');
180
+ this.stream.paused.should.be.true;
181
+ this.reader.paused.should.be.true;
182
+ })
183
+ });
184
+
185
+ describe('.readLine', function() {
186
+ describe('if there is at least one line in memory', function() {
187
+ beforeEach(function() {
188
+ this.reader.lines = ["hello\n", "world\n"];
189
+ });
190
+
191
+ it('pops the first line in memory', function(done) {
192
+ this.reader.readLine(function(line) {
193
+ line.should.eql("hello\n");
194
+ done();
195
+ });
196
+ });
197
+
198
+ describe('if the line memory is non-empty after reading', function() {
199
+ it('pauses the stream', function(done) {
200
+ var self = this;
201
+ this.reader.readLine(function(line) {
202
+ line.should.eql("hello\n");
203
+ process.nextTick(function() {
204
+ self.stream.paused.should.be.true;
205
+ self.reader.paused.should.be.true;
206
+ done();
207
+ });
208
+ });
209
+ });
210
+ });
211
+
212
+ describe('if the line memory is empty after reading', function() {
213
+ beforeEach(function() {
214
+ this.reader.lines = ["hello\n"];
215
+ });
216
+
217
+ it('resumes the stream', function(done) {
218
+ var self = this;
219
+ this.reader.readLine(function(line) {
220
+ line.should.eql("hello\n");
221
+ process.nextTick(function() {
222
+ self.stream.paused.should.be.false;
223
+ self.reader.paused.should.be.false;
224
+ done();
225
+ });
226
+ });
227
+ });
228
+ });
229
+
230
+ describe('if the stream had already reached EOF', function() {
231
+ beforeEach(function() {
232
+ this.reader.eof = true;
233
+ this.reader.lines = ["hello\n"];
234
+ });
235
+
236
+ it('yields the line upon first call', function(done) {
237
+ this.reader.readLine(function(line) {
238
+ line.should.eql("hello\n");
239
+ done();
240
+ });
241
+ });
242
+
243
+ it('yields undefined once the line memory has become empty', function(done) {
244
+ var self = this;
245
+ this.reader.readLine(function(line) {
246
+ line.should.eql("hello\n");
247
+ self.reader.readLine(function(line2) {
248
+ should(line2).equal(undefined);
249
+ self.reader.readLine(function(line3) {
250
+ should(line3).equal(undefined);
251
+ done();
252
+ });
253
+ });
254
+ });
255
+ });
256
+ });
257
+
258
+ describe('when calling readLine again in the callback', function() {
259
+ beforeEach(function() {
260
+ this.reader.lines = ["hello\n"];
261
+ });
262
+
263
+ it('waits until another line has been memorized', function(done) {
264
+ var self = this;
265
+ var finished;
266
+ this.reader.readLine(function(line) {
267
+ line.should.eql("hello\n");
268
+ self.reader.readLine(function(line2) {
269
+ if (!finished) {
270
+ finished = true;
271
+ line2.should.eql("world\n");
272
+ done();
273
+ }
274
+ });
275
+ setTimeout(function() {
276
+ if (!finished) {
277
+ finished = true;
278
+ self.stream.emit('data', "world\n");
279
+ done();
280
+ }
281
+ }, 50);
282
+ });
283
+ });
284
+
285
+ it('resumes the stream', function(done) {
286
+ var self = this;
287
+ var finished;
288
+ this.reader.readLine(function(line) {
289
+ line.should.eql("hello\n");
290
+ self.reader.readLine(function(line2) {
291
+ if (!finished) {
292
+ finished = true;
293
+ assert.fail("never reached");
294
+ }
295
+ });
296
+ process.nextTick(function() {
297
+ if (!finished) {
298
+ finished = true;
299
+ self.stream.paused.should.be.false;
300
+ self.reader.paused.should.be.false;
301
+ done();
302
+ }
303
+ });
304
+ });
305
+ });
306
+ });
307
+ });
308
+
309
+ describe('if there is no line in memory', function() {
310
+ it('waits until a line has been memorized', function(done) {
311
+ var state = 'waiting';
312
+ var self = this;
313
+ this.reader.readLine(function(line) {
314
+ state.should.eql('line fed');
315
+ line.should.eql("hello\n");
316
+ done();
317
+ });
318
+ setTimeout(function() {
319
+ state.should.eql('waiting');
320
+ state = 'line fed';
321
+ self.stream.emit('data', "hello\n");
322
+ }, 50);
323
+ });
324
+
325
+ describe('if the stream had already reached EOF', function(done) {
326
+ beforeEach(function() {
327
+ this.reader.eof = true;
328
+ })
329
+
330
+ it('yields undefined', function() {
331
+ this.reader.readLine(function(line) {
332
+ should(line).equal(undefined);
333
+ });
334
+ });
335
+ });
336
+ });
337
+ });
338
+ });