passenger 3.0.21 → 3.9.1.beta

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 (835) hide show
  1. data/DEVELOPERS.TXT +4 -10
  2. data/NEWS +19 -27
  3. data/Rakefile +20 -19
  4. data/bin/passenger +3 -2
  5. data/bin/passenger-config +35 -5
  6. data/bin/passenger-install-apache2-module +12 -12
  7. data/bin/passenger-install-nginx-module +55 -38
  8. data/bin/passenger-memory-stats +3 -1
  9. data/bin/passenger-status +7 -35
  10. data/build/agents.rb +107 -21
  11. data/build/apache2.rb +11 -46
  12. data/build/basics.rb +61 -9
  13. data/build/common_library.rb +59 -142
  14. data/build/cxx_tests.rb +111 -110
  15. data/build/documentation.rb +33 -0
  16. data/build/misc.rb +30 -12
  17. data/build/nginx.rb +10 -39
  18. data/build/oxt_tests.rb +1 -0
  19. data/build/ruby_extension.rb +1 -5
  20. data/build/test_basics.rb +3 -2
  21. data/dev/copy_boost_headers.rb +2 -1
  22. data/doc/Architectural overview.html +49 -90
  23. data/doc/DebuggingAndStressTesting.txt.md +49 -0
  24. data/doc/Packaging.txt.md +254 -0
  25. data/doc/Security of user switching support.html +35 -66
  26. data/doc/Users guide Apache.html +588 -758
  27. data/doc/Users guide Apache.idmap.txt +253 -136
  28. data/doc/Users guide Apache.txt +154 -109
  29. data/doc/Users guide Nginx.html +544 -660
  30. data/doc/Users guide Nginx.idmap.txt +179 -91
  31. data/doc/Users guide Nginx.txt +192 -118
  32. data/doc/Users guide Standalone.html +65 -48
  33. data/doc/Users guide Standalone.idmap.txt +10 -2
  34. data/doc/Users guide Standalone.txt +4 -0
  35. data/doc/images/glyphicons-halflings-white.png +0 -0
  36. data/doc/images/glyphicons-halflings.png +0 -0
  37. data/doc/images/phusion_banner_small.png +0 -0
  38. data/doc/images/{smart-lv2.png → smart.png} +0 -0
  39. data/doc/images/{smart-lv2.svg → smart.svg} +0 -0
  40. data/doc/templates/bootstrap.min.css +397 -0
  41. data/doc/templates/markdown.html.erb +117 -0
  42. data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +2 -1
  43. data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +26 -48
  44. data/doc/users_guide_snippets/passenger_spawn_method.txt +18 -30
  45. data/doc/users_guide_snippets/support_information.txt +30 -0
  46. data/ext/apache2/Bucket.cpp +9 -26
  47. data/ext/apache2/Bucket.h +13 -10
  48. data/ext/apache2/Configuration.cpp +70 -58
  49. data/ext/apache2/Configuration.hpp +19 -47
  50. data/ext/apache2/DirectoryMapper.h +7 -7
  51. data/ext/apache2/Hooks.cpp +150 -313
  52. data/ext/boost/algorithm/string/detail/case_conv.hpp +4 -2
  53. data/ext/boost/algorithm/string/detail/find_format.hpp +20 -20
  54. data/ext/boost/algorithm/string/detail/find_format_all.hpp +23 -23
  55. data/ext/boost/algorithm/string/detail/find_format_store.hpp +2 -2
  56. data/ext/boost/algorithm/string/detail/formatter.hpp +25 -0
  57. data/ext/boost/algorithm/string/formatter.hpp +20 -3
  58. data/ext/boost/assert.hpp +85 -4
  59. data/ext/boost/bind/bind.hpp +1 -1
  60. data/ext/boost/concept/detail/backward_compatibility.hpp +1 -1
  61. data/ext/boost/concept_check.hpp +140 -64
  62. data/ext/boost/config.hpp +1 -1
  63. data/ext/boost/config/auto_link.hpp +8 -6
  64. data/ext/boost/config/compiler/borland.hpp +12 -2
  65. data/ext/boost/config/compiler/clang.hpp +89 -30
  66. data/ext/boost/config/compiler/codegear.hpp +3 -2
  67. data/ext/boost/config/compiler/common_edg.hpp +7 -5
  68. data/ext/boost/config/compiler/cray.hpp +61 -0
  69. data/ext/boost/config/compiler/digitalmars.hpp +9 -1
  70. data/ext/boost/config/compiler/gcc.hpp +33 -24
  71. data/ext/boost/config/compiler/gcc_xml.hpp +4 -0
  72. data/ext/boost/config/compiler/hp_acc.hpp +12 -1
  73. data/ext/boost/config/compiler/intel.hpp +78 -4
  74. data/ext/boost/config/compiler/metrowerks.hpp +4 -1
  75. data/ext/boost/config/compiler/mpw.hpp +4 -1
  76. data/ext/boost/config/compiler/nvcc.hpp +8 -66
  77. data/ext/boost/config/compiler/pathscale.hpp +80 -0
  78. data/ext/boost/config/compiler/pgi.hpp +5 -5
  79. data/ext/boost/config/compiler/sunpro_cc.hpp +4 -1
  80. data/ext/boost/config/compiler/vacpp.hpp +37 -13
  81. data/ext/boost/config/compiler/visualc.hpp +24 -11
  82. data/ext/boost/config/platform/bsd.hpp +1 -1
  83. data/ext/boost/config/platform/cray.hpp +18 -0
  84. data/ext/boost/config/platform/cygwin.hpp +10 -0
  85. data/ext/boost/config/platform/linux.hpp +5 -0
  86. data/ext/boost/config/platform/macos.hpp +5 -4
  87. data/ext/boost/config/platform/symbian.hpp +5 -2
  88. data/ext/boost/config/platform/vms.hpp +25 -0
  89. data/ext/boost/config/platform/win32.hpp +7 -1
  90. data/ext/boost/config/select_compiler_config.hpp +8 -25
  91. data/ext/boost/config/select_platform_config.hpp +8 -1
  92. data/ext/boost/config/select_stdlib_config.hpp +9 -1
  93. data/ext/boost/config/stdlib/dinkumware.hpp +6 -9
  94. data/ext/boost/config/stdlib/libcomo.hpp +1 -4
  95. data/ext/boost/config/stdlib/libcpp.hpp +36 -0
  96. data/ext/boost/config/stdlib/libstdcpp3.hpp +37 -11
  97. data/ext/boost/config/stdlib/modena.hpp +1 -4
  98. data/ext/boost/config/stdlib/msl.hpp +1 -4
  99. data/ext/boost/config/stdlib/roguewave.hpp +9 -6
  100. data/ext/boost/config/stdlib/sgi.hpp +12 -4
  101. data/ext/boost/config/stdlib/stlport.hpp +11 -4
  102. data/ext/boost/config/stdlib/vacpp.hpp +11 -4
  103. data/ext/boost/config/suffix.hpp +71 -6
  104. data/ext/boost/config/warning_disable.hpp +1 -1
  105. data/ext/boost/container/container_fwd.hpp +177 -0
  106. data/ext/boost/cstdint.hpp +17 -12
  107. data/ext/boost/current_function.hpp +2 -1
  108. data/ext/boost/date_time/c_time.hpp +17 -1
  109. data/ext/boost/date_time/compiler_config.hpp +13 -15
  110. data/ext/boost/date_time/date_formatting.hpp +7 -1
  111. data/ext/boost/date_time/filetime_functions.hpp +4 -4
  112. data/ext/boost/date_time/gregorian_calendar.ipp +2 -2
  113. data/ext/boost/date_time/strings_from_facet.hpp +3 -3
  114. data/ext/boost/date_time/time_facet.hpp +101 -101
  115. data/ext/boost/detail/endian.hpp +4 -2
  116. data/ext/boost/detail/fenv.hpp +74 -0
  117. data/ext/boost/detail/sp_typeinfo.hpp +6 -0
  118. data/ext/boost/exception/detail/clone_current_exception.hpp +47 -0
  119. data/ext/boost/exception/detail/exception_ptr.hpp +194 -122
  120. data/ext/boost/exception/detail/type_info.hpp +3 -3
  121. data/ext/boost/exception/diagnostic_information.hpp +37 -21
  122. data/ext/boost/exception/exception.hpp +21 -1
  123. data/ext/boost/exception/info.hpp +0 -1
  124. data/ext/boost/function.hpp +2 -2
  125. data/ext/boost/function/function_base.hpp +15 -9
  126. data/ext/boost/function/function_template.hpp +26 -48
  127. data/ext/boost/integer_fwd.hpp +0 -16
  128. data/ext/boost/integer_traits.hpp +2 -2
  129. data/ext/boost/iterator.hpp +1 -1
  130. data/ext/boost/iterator/iterator_adaptor.hpp +1 -7
  131. data/ext/boost/iterator/iterator_facade.hpp +13 -13
  132. data/ext/boost/iterator/transform_iterator.hpp +5 -20
  133. data/ext/boost/lexical_cast.hpp +1655 -673
  134. data/ext/boost/math/policies/policy.hpp +982 -0
  135. data/ext/boost/math/special_functions/detail/fp_traits.hpp +570 -0
  136. data/ext/boost/math/special_functions/detail/round_fwd.hpp +80 -0
  137. data/ext/boost/math/special_functions/fpclassify.hpp +533 -0
  138. data/ext/boost/math/special_functions/math_fwd.hpp +1070 -0
  139. data/ext/boost/math/special_functions/sign.hpp +145 -0
  140. data/ext/boost/math/tools/config.hpp +321 -0
  141. data/ext/boost/math/tools/promotion.hpp +150 -0
  142. data/ext/boost/math/tools/real_cast.hpp +29 -0
  143. data/ext/boost/math/tools/user.hpp +97 -0
  144. data/ext/boost/move/move.hpp +1222 -0
  145. data/ext/boost/mpl/O1_size.hpp +40 -0
  146. data/ext/boost/mpl/O1_size_fwd.hpp +24 -0
  147. data/ext/boost/mpl/advance.hpp +76 -0
  148. data/ext/boost/mpl/advance_fwd.hpp +28 -0
  149. data/ext/boost/mpl/at.hpp +52 -0
  150. data/ext/boost/mpl/at_fwd.hpp +24 -0
  151. data/ext/boost/mpl/aux_/O1_size_impl.hpp +87 -0
  152. data/ext/boost/mpl/aux_/advance_backward.hpp +128 -0
  153. data/ext/boost/mpl/aux_/advance_forward.hpp +127 -0
  154. data/ext/boost/mpl/aux_/arithmetic_op.hpp +92 -0
  155. data/ext/boost/mpl/aux_/at_impl.hpp +45 -0
  156. data/ext/boost/mpl/aux_/begin_end_impl.hpp +101 -0
  157. data/ext/boost/mpl/aux_/clear_impl.hpp +35 -0
  158. data/ext/boost/mpl/aux_/comparison_op.hpp +83 -0
  159. data/ext/boost/mpl/aux_/config/forwarding.hpp +27 -0
  160. data/ext/boost/mpl/aux_/config/typeof.hpp +38 -0
  161. data/ext/boost/mpl/aux_/contains_impl.hpp +61 -0
  162. data/ext/boost/mpl/aux_/find_if_pred.hpp +31 -0
  163. data/ext/boost/mpl/aux_/fold_impl.hpp +43 -0
  164. data/ext/boost/mpl/aux_/has_begin.hpp +23 -0
  165. data/ext/boost/mpl/aux_/has_size.hpp +23 -0
  166. data/ext/boost/mpl/aux_/has_tag.hpp +23 -0
  167. data/ext/boost/mpl/aux_/inserter_algorithm.hpp +159 -0
  168. data/ext/boost/mpl/aux_/is_msvc_eti_arg.hpp +64 -0
  169. data/ext/boost/mpl/aux_/iter_apply.hpp +47 -0
  170. data/ext/boost/mpl/aux_/iter_fold_if_impl.hpp +210 -0
  171. data/ext/boost/mpl/aux_/iter_fold_impl.hpp +42 -0
  172. data/ext/boost/mpl/aux_/lambda_spec.hpp +49 -0
  173. data/ext/boost/mpl/aux_/largest_int.hpp +63 -0
  174. data/ext/boost/mpl/aux_/msvc_eti_base.hpp +77 -0
  175. data/ext/boost/mpl/aux_/msvc_type.hpp +62 -0
  176. data/ext/boost/mpl/aux_/numeric_cast_utils.hpp +77 -0
  177. data/ext/boost/mpl/aux_/numeric_op.hpp +315 -0
  178. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp +97 -0
  179. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp +97 -0
  180. data/ext/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp +94 -0
  181. data/ext/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp +180 -0
  182. data/ext/boost/mpl/aux_/preprocessed/gcc/greater.hpp +94 -0
  183. data/ext/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp +94 -0
  184. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp +133 -0
  185. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp +180 -0
  186. data/ext/boost/mpl/aux_/preprocessed/gcc/less.hpp +94 -0
  187. data/ext/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp +94 -0
  188. data/ext/boost/mpl/aux_/preprocessed/gcc/list.hpp +323 -0
  189. data/ext/boost/mpl/aux_/preprocessed/gcc/minus.hpp +146 -0
  190. data/ext/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp +94 -0
  191. data/ext/boost/mpl/aux_/preprocessed/gcc/plus.hpp +146 -0
  192. data/ext/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp +231 -0
  193. data/ext/boost/mpl/aux_/preprocessed/gcc/times.hpp +146 -0
  194. data/ext/boost/mpl/aux_/preprocessed/gcc/vector.hpp +323 -0
  195. data/ext/boost/mpl/aux_/preprocessor/default_params.hpp +67 -0
  196. data/ext/boost/mpl/aux_/push_back_impl.hpp +70 -0
  197. data/ext/boost/mpl/aux_/push_front_impl.hpp +71 -0
  198. data/ext/boost/mpl/aux_/reverse_fold_impl.hpp +44 -0
  199. data/ext/boost/mpl/aux_/size_impl.hpp +52 -0
  200. data/ext/boost/mpl/aux_/traits_lambda_spec.hpp +63 -0
  201. data/ext/boost/mpl/back_fwd.hpp +24 -0
  202. data/ext/boost/mpl/back_inserter.hpp +34 -0
  203. data/ext/boost/mpl/begin_end.hpp +57 -0
  204. data/ext/boost/mpl/begin_end_fwd.hpp +27 -0
  205. data/ext/boost/mpl/clear.hpp +39 -0
  206. data/ext/boost/mpl/clear_fwd.hpp +24 -0
  207. data/ext/boost/mpl/comparison.hpp +24 -0
  208. data/ext/boost/mpl/contains.hpp +41 -0
  209. data/ext/boost/mpl/contains_fwd.hpp +25 -0
  210. data/ext/boost/mpl/deref.hpp +41 -0
  211. data/ext/boost/mpl/distance.hpp +78 -0
  212. data/ext/boost/mpl/distance_fwd.hpp +28 -0
  213. data/ext/boost/mpl/empty_fwd.hpp +24 -0
  214. data/ext/boost/mpl/equal_to.hpp +21 -0
  215. data/ext/boost/mpl/find.hpp +38 -0
  216. data/ext/boost/mpl/find_if.hpp +50 -0
  217. data/ext/boost/mpl/fold.hpp +48 -0
  218. data/ext/boost/mpl/front_fwd.hpp +24 -0
  219. data/ext/boost/mpl/front_inserter.hpp +33 -0
  220. data/ext/boost/mpl/greater.hpp +21 -0
  221. data/ext/boost/mpl/greater_equal.hpp +21 -0
  222. data/ext/boost/mpl/inserter.hpp +32 -0
  223. data/ext/boost/mpl/iter_fold.hpp +49 -0
  224. data/ext/boost/mpl/iter_fold_if.hpp +117 -0
  225. data/ext/boost/mpl/iterator_range.hpp +42 -0
  226. data/ext/boost/mpl/iterator_tags.hpp +27 -0
  227. data/ext/boost/mpl/less.hpp +21 -0
  228. data/ext/boost/mpl/less_equal.hpp +21 -0
  229. data/ext/boost/mpl/limits/list.hpp +21 -0
  230. data/ext/boost/mpl/limits/vector.hpp +21 -0
  231. data/ext/boost/mpl/list.hpp +57 -0
  232. data/ext/boost/mpl/list/aux_/O1_size.hpp +33 -0
  233. data/ext/boost/mpl/list/aux_/begin_end.hpp +44 -0
  234. data/ext/boost/mpl/list/aux_/clear.hpp +34 -0
  235. data/ext/boost/mpl/list/aux_/empty.hpp +34 -0
  236. data/ext/boost/mpl/list/aux_/front.hpp +33 -0
  237. data/ext/boost/mpl/list/aux_/include_preprocessed.hpp +35 -0
  238. data/ext/boost/mpl/list/aux_/item.hpp +55 -0
  239. data/ext/boost/mpl/list/aux_/iterator.hpp +76 -0
  240. data/ext/boost/mpl/list/aux_/pop_front.hpp +34 -0
  241. data/ext/boost/mpl/list/aux_/preprocessed/plain/list10.hpp +149 -0
  242. data/ext/boost/mpl/list/aux_/preprocessed/plain/list20.hpp +169 -0
  243. data/ext/boost/mpl/list/aux_/push_back.hpp +36 -0
  244. data/ext/boost/mpl/list/aux_/push_front.hpp +39 -0
  245. data/ext/boost/mpl/list/aux_/size.hpp +33 -0
  246. data/ext/boost/mpl/list/aux_/tag.hpp +24 -0
  247. data/ext/boost/mpl/list/list0.hpp +42 -0
  248. data/ext/boost/mpl/list/list10.hpp +43 -0
  249. data/ext/boost/mpl/list/list20.hpp +43 -0
  250. data/ext/boost/mpl/long.hpp +22 -0
  251. data/ext/boost/mpl/long_fwd.hpp +27 -0
  252. data/ext/boost/mpl/minus.hpp +21 -0
  253. data/ext/boost/mpl/multiplies.hpp +53 -0
  254. data/ext/boost/mpl/negate.hpp +81 -0
  255. data/ext/boost/mpl/not_equal_to.hpp +21 -0
  256. data/ext/boost/mpl/numeric_cast.hpp +41 -0
  257. data/ext/boost/mpl/pair.hpp +70 -0
  258. data/ext/boost/mpl/plus.hpp +21 -0
  259. data/ext/boost/mpl/pop_back_fwd.hpp +24 -0
  260. data/ext/boost/mpl/pop_front_fwd.hpp +24 -0
  261. data/ext/boost/mpl/prior.hpp +19 -0
  262. data/ext/boost/mpl/push_back.hpp +53 -0
  263. data/ext/boost/mpl/push_back_fwd.hpp +24 -0
  264. data/ext/boost/mpl/push_front.hpp +52 -0
  265. data/ext/boost/mpl/push_front_fwd.hpp +24 -0
  266. data/ext/boost/mpl/remove_if.hpp +83 -0
  267. data/ext/boost/mpl/reverse_fold.hpp +50 -0
  268. data/ext/boost/mpl/same_as.hpp +55 -0
  269. data/ext/boost/mpl/sequence_tag.hpp +124 -0
  270. data/ext/boost/mpl/sequence_tag_fwd.hpp +26 -0
  271. data/ext/boost/mpl/size.hpp +42 -0
  272. data/ext/boost/mpl/size_fwd.hpp +24 -0
  273. data/ext/boost/mpl/tag.hpp +52 -0
  274. data/ext/boost/mpl/times.hpp +21 -0
  275. data/ext/boost/mpl/vector.hpp +57 -0
  276. data/ext/boost/mpl/vector/aux_/O1_size.hpp +56 -0
  277. data/ext/boost/mpl/vector/aux_/at.hpp +116 -0
  278. data/ext/boost/mpl/vector/aux_/back.hpp +59 -0
  279. data/ext/boost/mpl/vector/aux_/begin_end.hpp +49 -0
  280. data/ext/boost/mpl/vector/aux_/clear.hpp +55 -0
  281. data/ext/boost/mpl/vector/aux_/empty.hpp +68 -0
  282. data/ext/boost/mpl/vector/aux_/front.hpp +56 -0
  283. data/ext/boost/mpl/vector/aux_/include_preprocessed.hpp +55 -0
  284. data/ext/boost/mpl/vector/aux_/item.hpp +103 -0
  285. data/ext/boost/mpl/vector/aux_/iterator.hpp +130 -0
  286. data/ext/boost/mpl/vector/aux_/pop_back.hpp +40 -0
  287. data/ext/boost/mpl/vector/aux_/pop_front.hpp +40 -0
  288. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp +829 -0
  289. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp +1144 -0
  290. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp +139 -0
  291. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp +159 -0
  292. data/ext/boost/mpl/vector/aux_/push_back.hpp +40 -0
  293. data/ext/boost/mpl/vector/aux_/push_front.hpp +40 -0
  294. data/ext/boost/mpl/vector/aux_/size.hpp +49 -0
  295. data/ext/boost/mpl/vector/aux_/tag.hpp +32 -0
  296. data/ext/boost/mpl/vector/aux_/vector0.hpp +52 -0
  297. data/ext/boost/mpl/vector/vector0.hpp +34 -0
  298. data/ext/boost/mpl/vector/vector10.hpp +45 -0
  299. data/ext/boost/mpl/vector/vector20.hpp +45 -0
  300. data/ext/boost/none.hpp +1 -1
  301. data/ext/boost/numeric/conversion/bounds.hpp +24 -0
  302. data/ext/boost/numeric/conversion/cast.hpp +61 -0
  303. data/ext/boost/numeric/conversion/conversion_traits.hpp +39 -0
  304. data/ext/boost/numeric/conversion/converter.hpp +68 -0
  305. data/ext/boost/numeric/conversion/converter_policies.hpp +186 -0
  306. data/ext/boost/numeric/conversion/detail/bounds.hpp +58 -0
  307. data/ext/boost/numeric/conversion/detail/conversion_traits.hpp +97 -0
  308. data/ext/boost/numeric/conversion/detail/converter.hpp +602 -0
  309. data/ext/boost/numeric/conversion/detail/int_float_mixture.hpp +72 -0
  310. data/ext/boost/numeric/conversion/detail/is_subranged.hpp +234 -0
  311. data/ext/boost/numeric/conversion/detail/meta.hpp +120 -0
  312. data/ext/boost/numeric/conversion/detail/numeric_cast_traits.hpp +138 -0
  313. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp +1741 -0
  314. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp +347 -0
  315. data/ext/boost/numeric/conversion/detail/sign_mixture.hpp +72 -0
  316. data/ext/boost/numeric/conversion/detail/udt_builtin_mixture.hpp +69 -0
  317. data/ext/boost/numeric/conversion/int_float_mixture_enum.hpp +29 -0
  318. data/ext/boost/numeric/conversion/numeric_cast_traits.hpp +31 -0
  319. data/ext/boost/numeric/conversion/sign_mixture_enum.hpp +29 -0
  320. data/ext/boost/numeric/conversion/udt_builtin_mixture_enum.hpp +26 -0
  321. data/ext/boost/operators.hpp +3 -1
  322. data/ext/boost/optional/optional.hpp +146 -79
  323. data/ext/boost/optional/optional_fwd.hpp +8 -1
  324. data/ext/boost/preprocessor/cat.hpp +2 -2
  325. data/ext/boost/preprocessor/config/config.hpp +39 -4
  326. data/ext/boost/preprocessor/facilities/intercept.hpp +277 -0
  327. data/ext/boost/preprocessor/facilities/overload.hpp +25 -0
  328. data/ext/boost/preprocessor/iteration/detail/iter/forward1.hpp +3 -3
  329. data/ext/boost/preprocessor/iteration/iterate.hpp +3 -3
  330. data/ext/boost/preprocessor/punctuation/paren.hpp +23 -0
  331. data/ext/boost/preprocessor/repetition/enum_shifted_params.hpp +44 -0
  332. data/ext/boost/preprocessor/seq/cat.hpp +5 -4
  333. data/ext/boost/preprocessor/seq/size.hpp +0 -1
  334. data/ext/boost/preprocessor/tuple/eat.hpp +83 -34
  335. data/ext/boost/preprocessor/tuple/elem.hpp +161 -355
  336. data/ext/boost/preprocessor/tuple/rem.hpp +110 -48
  337. data/ext/boost/preprocessor/tuple/to_list.hpp +90 -36
  338. data/ext/boost/preprocessor/variadic/elem.hpp +94 -0
  339. data/ext/boost/preprocessor/variadic/size.hpp +30 -0
  340. data/ext/boost/range/begin.hpp +17 -6
  341. data/ext/boost/range/concepts.hpp +37 -2
  342. data/ext/boost/range/detail/safe_bool.hpp +72 -0
  343. data/ext/boost/range/end.hpp +14 -9
  344. data/ext/boost/range/iterator_range_core.hpp +120 -12
  345. data/ext/boost/range/size.hpp +21 -5
  346. data/ext/boost/smart_ptr/detail/shared_count.hpp +88 -0
  347. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +3 -0
  348. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +142 -0
  349. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +9 -0
  350. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +10 -2
  351. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +5 -1
  352. data/ext/boost/smart_ptr/detail/spinlock.hpp +4 -1
  353. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +20 -3
  354. data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +4 -0
  355. data/ext/boost/smart_ptr/make_shared.hpp +591 -22
  356. data/ext/boost/smart_ptr/shared_array.hpp +29 -1
  357. data/ext/boost/smart_ptr/shared_ptr.hpp +29 -13
  358. data/ext/boost/smart_ptr/weak_ptr.hpp +24 -12
  359. data/ext/boost/src/pthread/once.cpp +9 -7
  360. data/ext/boost/src/pthread/thread.cpp +32 -28
  361. data/ext/boost/src/pthread/timeconv.inl +4 -5
  362. data/ext/boost/src/tss_null.cpp +5 -1
  363. data/ext/boost/static_assert.hpp +8 -2
  364. data/ext/boost/thread/detail/config.hpp +19 -4
  365. data/ext/boost/thread/detail/move.hpp +11 -5
  366. data/ext/boost/thread/detail/thread.hpp +59 -43
  367. data/ext/boost/thread/exceptions.hpp +9 -9
  368. data/ext/boost/thread/future.hpp +150 -82
  369. data/ext/boost/thread/locks.hpp +101 -60
  370. data/ext/boost/thread/pthread/condition_variable.hpp +79 -32
  371. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +12 -3
  372. data/ext/boost/thread/pthread/mutex.hpp +17 -14
  373. data/ext/boost/thread/pthread/once.hpp +3 -4
  374. data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +12 -2
  375. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -19
  376. data/ext/boost/thread/pthread/shared_mutex.hpp +13 -13
  377. data/ext/boost/thread/pthread/thread_data.hpp +40 -12
  378. data/ext/boost/thread/thread_time.hpp +5 -0
  379. data/ext/boost/throw_exception.hpp +1 -1
  380. data/ext/boost/token_functions.hpp +34 -10
  381. data/ext/boost/type_traits/add_rvalue_reference.hpp +66 -0
  382. data/ext/boost/type_traits/alignment_of.hpp +1 -1
  383. data/ext/boost/type_traits/detail/bool_trait_def.hpp +26 -3
  384. data/ext/boost/type_traits/detail/bool_trait_undef.hpp +3 -2
  385. data/ext/boost/type_traits/detail/cv_traits_impl.hpp +1 -1
  386. data/ext/boost/type_traits/detail/size_t_trait_def.hpp +6 -4
  387. data/ext/boost/type_traits/detail/type_trait_def.hpp +8 -2
  388. data/ext/boost/type_traits/function_traits.hpp +1 -1
  389. data/ext/boost/type_traits/has_nothrow_constructor.hpp +53 -0
  390. data/ext/boost/type_traits/has_nothrow_copy.hpp +19 -5
  391. data/ext/boost/type_traits/has_trivial_constructor.hpp +51 -0
  392. data/ext/boost/type_traits/has_trivial_copy.hpp +20 -5
  393. data/ext/boost/type_traits/has_trivial_destructor.hpp +12 -5
  394. data/ext/boost/type_traits/intrinsics.hpp +119 -71
  395. data/ext/boost/type_traits/is_const.hpp +5 -5
  396. data/ext/boost/type_traits/is_convertible.hpp +14 -13
  397. data/ext/boost/type_traits/is_enum.hpp +1 -1
  398. data/ext/boost/type_traits/is_floating_point.hpp +27 -0
  399. data/ext/boost/type_traits/is_function.hpp +3 -3
  400. data/ext/boost/type_traits/is_fundamental.hpp +1 -1
  401. data/ext/boost/type_traits/is_member_function_pointer.hpp +2 -2
  402. data/ext/boost/type_traits/is_member_pointer.hpp +2 -2
  403. data/ext/boost/type_traits/is_pod.hpp +11 -3
  404. data/ext/boost/type_traits/is_pointer.hpp +2 -2
  405. data/ext/boost/type_traits/is_signed.hpp +8 -3
  406. data/ext/boost/type_traits/is_union.hpp +8 -0
  407. data/ext/boost/type_traits/is_unsigned.hpp +9 -4
  408. data/ext/boost/type_traits/is_volatile.hpp +5 -5
  409. data/ext/boost/type_traits/remove_cv.hpp +4 -3
  410. data/ext/boost/type_traits/remove_pointer.hpp +51 -2
  411. data/ext/boost/type_traits/remove_reference.hpp +2 -2
  412. data/ext/boost/type_traits/type_with_alignment.hpp +8 -2
  413. data/ext/boost/utility/declval.hpp +44 -0
  414. data/ext/boost/utility/detail/in_place_factory_prefix.hpp +36 -0
  415. data/ext/boost/utility/detail/in_place_factory_suffix.hpp +23 -0
  416. data/ext/boost/utility/detail/result_of_iterate.hpp +142 -0
  417. data/ext/boost/utility/in_place_factory.hpp +88 -0
  418. data/ext/boost/utility/result_of.hpp +103 -0
  419. data/ext/boost/utility/swap.hpp +55 -0
  420. data/ext/common/AnsiColorConstants.h +36 -0
  421. data/ext/common/ApplicationPool2/Common.h +87 -0
  422. data/ext/common/ApplicationPool2/ComponentInfo.h +53 -0
  423. data/ext/common/ApplicationPool2/Group.h +648 -0
  424. data/ext/common/ApplicationPool2/Implementation.cpp +580 -0
  425. data/ext/common/ApplicationPool2/Options.h +576 -0
  426. data/ext/common/ApplicationPool2/PipeWatcher.h +61 -0
  427. data/ext/common/ApplicationPool2/Pool.h +1181 -0
  428. data/ext/common/ApplicationPool2/Process.h +425 -0
  429. data/ext/common/ApplicationPool2/README.md +96 -0
  430. data/ext/common/ApplicationPool2/Session.h +158 -0
  431. data/ext/common/ApplicationPool2/Socket.h +246 -0
  432. data/ext/common/ApplicationPool2/Spawner.h +2212 -0
  433. data/ext/common/ApplicationPool2/SuperGroup.h +749 -0
  434. data/ext/common/BackgroundEventLoop.cpp +129 -0
  435. data/ext/common/BackgroundEventLoop.h +61 -0
  436. data/ext/common/Constants.h +3 -1
  437. data/ext/common/EventedBufferedInput.h +331 -0
  438. data/ext/common/EventedMessageServer.h +17 -34
  439. data/ext/common/EventedServer.h +2 -2
  440. data/ext/common/Exceptions.h +71 -19
  441. data/ext/common/FileDescriptor.h +8 -6
  442. data/ext/common/HttpConstants.h +167 -0
  443. data/ext/common/IniFile.h +24 -0
  444. data/ext/common/Logging.h +62 -849
  445. data/ext/common/MessageReadersWriters.h +19 -0
  446. data/ext/common/MessageServer.h +11 -14
  447. data/ext/common/MultiLibeio.cpp +198 -0
  448. data/ext/common/MultiLibeio.h +67 -0
  449. data/ext/common/ResourceLocator.h +24 -41
  450. data/ext/common/SafeLibev.h +186 -14
  451. data/ext/common/StaticString.h +23 -3
  452. data/ext/common/UnionStation.h +972 -0
  453. data/ext/common/Utils.cpp +168 -24
  454. data/ext/common/Utils.h +25 -3
  455. data/ext/common/Utils/CachedFileStat.hpp +4 -3
  456. data/ext/common/Utils/FileChangeChecker.h +2 -2
  457. data/ext/common/Utils/HashMap.h +50 -0
  458. data/ext/common/Utils/IOUtils.cpp +229 -68
  459. data/ext/common/Utils/IOUtils.h +134 -3
  460. data/ext/common/Utils/Lock.h +28 -0
  461. data/ext/common/Utils/MemoryBarrier.h +52 -0
  462. data/ext/common/Utils/PriorityQueue.h +54 -0
  463. data/ext/common/Utils/ProcessMetricsCollector.h +9 -11
  464. data/ext/common/Utils/ScopeGuard.h +50 -1
  465. data/ext/common/Utils/SmallVector.h +653 -0
  466. data/ext/common/Utils/StrIntUtils.cpp +26 -2
  467. data/ext/common/Utils/StrIntUtils.h +18 -2
  468. data/ext/common/Utils/StringMap.h +125 -8
  469. data/ext/common/Utils/Template.h +212 -0
  470. data/ext/common/Utils/fib.c +699 -0
  471. data/ext/common/Utils/fib.h +101 -0
  472. data/ext/common/Utils/fibpriv.h +67 -0
  473. data/ext/common/Utils/json-forwards.h +249 -0
  474. data/ext/common/Utils/json.h +1855 -0
  475. data/ext/common/Utils/jsoncpp.cpp +4230 -0
  476. data/ext/common/agents/Base.cpp +1126 -0
  477. data/ext/common/{AgentBase.h → agents/Base.h} +5 -1
  478. data/ext/common/agents/EnvPrinter.c +16 -0
  479. data/ext/common/agents/HelperAgent/AgentOptions.h +81 -0
  480. data/ext/common/{HelperAgent → agents/HelperAgent}/BacktracesServer.h +3 -2
  481. data/ext/common/agents/HelperAgent/FileBackedPipe.h +732 -0
  482. data/ext/common/agents/HelperAgent/Main.cpp +497 -0
  483. data/ext/common/agents/HelperAgent/RequestHandler.cpp +283 -0
  484. data/ext/common/agents/HelperAgent/RequestHandler.h +2139 -0
  485. data/ext/common/agents/HelperAgent/ScgiRequestParser.h +451 -0
  486. data/ext/common/{LoggingAgent → agents/LoggingAgent}/DataStoreId.h +1 -1
  487. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.cpp +1 -1
  488. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.h +0 -0
  489. data/ext/common/{LoggingAgent → agents/LoggingAgent}/LoggingServer.h +18 -16
  490. data/ext/common/{LoggingAgent → agents/LoggingAgent}/Main.cpp +15 -13
  491. data/ext/common/{LoggingAgent → agents/LoggingAgent}/RemoteSender.h +6 -6
  492. data/ext/common/agents/SpawnPreparer.cpp +127 -0
  493. data/ext/common/{Watchdog.cpp → agents/Watchdog/Main.cpp} +63 -25
  494. data/ext/libeio/Changes +72 -0
  495. data/ext/{google/COPYING → libeio/LICENSE} +17 -9
  496. data/ext/libeio/Makefile.am +15 -0
  497. data/ext/libeio/Makefile.in +694 -0
  498. data/ext/libeio/aclocal.m4 +9418 -0
  499. data/ext/libeio/autogen.sh +3 -0
  500. data/ext/libeio/config.guess +1501 -0
  501. data/ext/libeio/config.h.in +136 -0
  502. data/ext/libeio/config.sub +1705 -0
  503. data/ext/libeio/configure +14822 -0
  504. data/ext/libeio/configure.ac +22 -0
  505. data/ext/libeio/demo.c +194 -0
  506. data/ext/libeio/ecb.h +457 -0
  507. data/ext/libeio/eio.c +2816 -0
  508. data/ext/libeio/eio.h +411 -0
  509. data/ext/libeio/install-sh +520 -0
  510. data/ext/libeio/libeio.m4 +211 -0
  511. data/ext/libeio/ltmain.sh +9636 -0
  512. data/ext/libeio/missing +376 -0
  513. data/ext/libeio/xthread.h +166 -0
  514. data/ext/libev/Changes +125 -7
  515. data/ext/libev/Makefile.am +5 -3
  516. data/ext/libev/Makefile.in +209 -120
  517. data/ext/libev/aclocal.m4 +6027 -4619
  518. data/ext/libev/autogen.sh +1 -4
  519. data/ext/libev/config.h.in +11 -7
  520. data/ext/libev/configure +7312 -14993
  521. data/ext/libev/configure.ac +12 -5
  522. data/ext/libev/depcomp +630 -0
  523. data/ext/libev/ev++.h +48 -32
  524. data/ext/libev/ev.c +1173 -391
  525. data/ext/libev/ev.h +315 -181
  526. data/ext/libev/ev_epoll.c +66 -15
  527. data/ext/libev/ev_kqueue.c +20 -18
  528. data/ext/libev/ev_poll.c +27 -23
  529. data/ext/libev/ev_port.c +39 -19
  530. data/ext/libev/ev_select.c +23 -17
  531. data/ext/libev/ev_vars.h +25 -8
  532. data/ext/libev/ev_win32.c +6 -6
  533. data/ext/libev/ev_wrap.h +22 -2
  534. data/ext/libev/event.c +18 -17
  535. data/ext/libev/event.h +16 -4
  536. data/ext/libev/libev.m4 +10 -6
  537. data/ext/libev/ltmain.sh +7353 -5811
  538. data/ext/nginx/Configuration.c +74 -42
  539. data/ext/nginx/Configuration.h +3 -5
  540. data/ext/nginx/ContentHandler.c +26 -83
  541. data/ext/nginx/ContentHandler.h +1 -1
  542. data/ext/nginx/config +13 -9
  543. data/ext/nginx/ngx_http_passenger_module.c +3 -7
  544. data/ext/oxt/detail/backtrace_enabled.hpp +5 -102
  545. data/ext/oxt/detail/context.hpp +90 -0
  546. data/ext/oxt/detail/spin_lock_darwin.hpp +4 -0
  547. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +4 -0
  548. data/ext/oxt/detail/spin_lock_pthreads.hpp +14 -0
  549. data/ext/oxt/detail/tracable_exception_enabled.hpp +2 -2
  550. data/ext/oxt/dynamic_thread_group.hpp +27 -1
  551. data/ext/oxt/implementation.cpp +415 -0
  552. data/ext/oxt/{thread.cpp → initialize.hpp} +13 -6
  553. data/ext/oxt/macros.hpp +32 -1
  554. data/ext/oxt/spin_lock.hpp +6 -11
  555. data/ext/oxt/system_calls.cpp +204 -16
  556. data/ext/oxt/system_calls.hpp +85 -45
  557. data/ext/oxt/thread.hpp +13 -117
  558. data/ext/ruby/passenger_native_support.c +82 -237
  559. data/helper-scripts/backtrace-sanitizer.rb +114 -0
  560. data/helper-scripts/classic-rails-loader.rb +135 -0
  561. data/helper-scripts/classic-rails-preloader.rb +161 -0
  562. data/helper-scripts/node-loader.js +314 -0
  563. data/helper-scripts/rack-loader.rb +104 -0
  564. data/helper-scripts/rack-preloader.rb +132 -0
  565. data/helper-scripts/wsgi-loader.py +231 -0
  566. data/helper-scripts/wsgi-preloader.py +1 -0
  567. data/lib/phusion_passenger.rb +159 -61
  568. data/lib/phusion_passenger/abstract_installer.rb +182 -87
  569. data/lib/phusion_passenger/admin_tools/server_instance.rb +25 -19
  570. data/lib/phusion_passenger/analytics_logger.rb +5 -4
  571. data/lib/phusion_passenger/classic_rails/{request_handler.rb → thread_handler_extension.rb} +4 -40
  572. data/lib/phusion_passenger/classic_rails_extensions/init.rb +5 -3
  573. data/lib/phusion_passenger/common_library.rb +441 -0
  574. data/lib/phusion_passenger/console_text_template.rb +4 -16
  575. data/lib/phusion_passenger/constants.rb +1 -8
  576. data/lib/phusion_passenger/debug_logging.rb +5 -2
  577. data/lib/phusion_passenger/dependencies.rb +51 -13
  578. data/lib/phusion_passenger/loader_shared_helpers.rb +318 -0
  579. data/lib/phusion_passenger/message_channel.rb +3 -47
  580. data/lib/phusion_passenger/message_client.rb +2 -2
  581. data/lib/phusion_passenger/native_support.rb +36 -15
  582. data/lib/phusion_passenger/packaging.rb +8 -11
  583. data/lib/phusion_passenger/platform_info.rb +25 -17
  584. data/lib/phusion_passenger/platform_info/apache.rb +10 -7
  585. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +10 -30
  586. data/lib/phusion_passenger/platform_info/compiler.rb +93 -34
  587. data/lib/phusion_passenger/platform_info/ruby.rb +37 -97
  588. data/lib/phusion_passenger/preloader_shared_helpers.rb +121 -0
  589. data/lib/phusion_passenger/public_api.rb +1 -4
  590. data/lib/phusion_passenger/rack/{request_handler.rb → thread_handler_extension.rb} +14 -63
  591. data/lib/phusion_passenger/rails3_extensions/init.rb +9 -8
  592. data/lib/phusion_passenger/request_handler.rb +500 -0
  593. data/lib/phusion_passenger/request_handler/thread_handler.rb +360 -0
  594. data/lib/phusion_passenger/ruby_core_enhancements.rb +142 -0
  595. data/lib/phusion_passenger/standalone/command.rb +36 -15
  596. data/lib/phusion_passenger/standalone/package_runtime_command.rb +16 -8
  597. data/lib/phusion_passenger/standalone/runtime_installer.rb +169 -72
  598. data/lib/phusion_passenger/standalone/start_command.rb +44 -39
  599. data/lib/phusion_passenger/standalone/utils.rb +5 -5
  600. data/lib/phusion_passenger/utils.rb +35 -914
  601. data/lib/phusion_passenger/utils/ansi_colors.rb +59 -0
  602. data/lib/phusion_passenger/utils/file_system_watcher.rb +1 -1
  603. data/lib/phusion_passenger/utils/robust_interruption.rb +134 -0
  604. data/lib/phusion_passenger/utils/tee_input.rb +174 -0
  605. data/lib/phusion_passenger/utils/tmpio.rb +33 -0
  606. data/lib/phusion_passenger/utils/unseekable_socket.rb +6 -0
  607. data/resources/mime.types +5 -1
  608. data/{lib/phusion_passenger/templates → resources}/standalone_default_root/index.html +0 -0
  609. data/{lib/phusion_passenger → resources}/templates/apache2/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  610. data/{lib/phusion_passenger → resources}/templates/apache2/config_snippets.txt.erb +0 -0
  611. data/{lib/phusion_passenger → resources}/templates/apache2/deployment_example.txt.erb +0 -0
  612. data/{lib/phusion_passenger → resources}/templates/apache2/no_write_permission_to_passenger_root.txt.erb +0 -0
  613. data/{lib/phusion_passenger → resources}/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  614. data/{lib/phusion_passenger → resources}/templates/apache2/run_installer_as_root.txt.erb +0 -0
  615. data/{lib/phusion_passenger → resources}/templates/apache2/welcome.txt.erb +0 -0
  616. data/{lib/phusion_passenger → resources}/templates/error_layout.css +6 -0
  617. data/resources/templates/error_layout.html.template +89 -0
  618. data/resources/templates/general_error.html.template +1 -0
  619. data/resources/templates/general_error_with_html.html.template +1 -0
  620. data/{lib/phusion_passenger → resources}/templates/nginx/ask_for_extra_configure_flags.txt.erb +0 -0
  621. data/{lib/phusion_passenger → resources}/templates/nginx/cannot_write_to_dir.txt.erb +0 -0
  622. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets.txt.erb +0 -0
  623. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets_inserted.txt.erb +0 -0
  624. data/{lib/phusion_passenger → resources}/templates/nginx/confirm_extra_configure_flags.txt.erb +0 -0
  625. data/{lib/phusion_passenger → resources}/templates/nginx/deployment_example.txt.erb +0 -0
  626. data/resources/templates/nginx/not_available_when_natively_packaged.txt.erb +8 -0
  627. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_downloaded.txt.erb +0 -0
  628. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_extracted.txt.erb +0 -0
  629. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  630. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  631. data/{lib/phusion_passenger → resources}/templates/nginx/query_download_and_install.txt.erb +0 -0
  632. data/{lib/phusion_passenger → resources}/templates/nginx/run_installer_as_root.txt.erb +0 -0
  633. data/{lib/phusion_passenger → resources}/templates/nginx/welcome.txt.erb +0 -0
  634. data/{lib/phusion_passenger → resources}/templates/standalone/cannot_write_to_dir.txt.erb +0 -0
  635. data/{lib/phusion_passenger → resources}/templates/standalone/config.erb +26 -5
  636. data/{lib/phusion_passenger → resources}/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  637. data/{lib/phusion_passenger → resources}/templates/standalone/run_installer_as_root.txt.erb +0 -0
  638. data/{lib/phusion_passenger → resources}/templates/standalone/welcome.txt.erb +0 -0
  639. data/resources/templates/undisclosed_error.html.template +25 -0
  640. data/test/config.json.example +42 -0
  641. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +86 -0
  642. data/test/cxx/ApplicationPool2/OptionsTest.cpp +44 -0
  643. data/test/cxx/ApplicationPool2/PoolTest.cpp +1234 -0
  644. data/test/cxx/ApplicationPool2/ProcessTest.cpp +131 -0
  645. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +229 -0
  646. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +744 -0
  647. data/test/cxx/BufferedIOTest.cpp +7 -7
  648. data/test/cxx/CxxTestMain.cpp +65 -2
  649. data/test/cxx/FileBackedPipeTest.cpp +626 -0
  650. data/test/cxx/FileChangeCheckerTest.cpp +20 -18
  651. data/test/cxx/FilterSupportTest.cpp +5 -5
  652. data/test/cxx/IOUtilsTest.cpp +11 -4
  653. data/test/cxx/MessageReadersWritersTest.cpp +1 -1
  654. data/test/cxx/MessageServerTest.cpp +31 -30
  655. data/test/cxx/RequestHandlerTest.cpp +777 -0
  656. data/test/cxx/ScgiRequestParserTest.cpp +36 -16
  657. data/test/cxx/ServerInstanceDirTest.cpp +1 -1
  658. data/test/cxx/StringMapTest.cpp +61 -0
  659. data/test/cxx/TemplateTest.cpp +118 -0
  660. data/test/cxx/TestSupport.cpp +25 -68
  661. data/test/cxx/TestSupport.h +81 -41
  662. data/test/cxx/{LoggingTest.cpp → UnionStationTest.cpp} +79 -74
  663. data/test/cxx/UtilsTest.cpp +59 -5
  664. data/test/integration_tests/apache2_tests.rb +2 -2
  665. data/test/integration_tests/nginx_tests.rb +1 -1
  666. data/test/integration_tests/spec_helper.rb +7 -5
  667. data/test/oxt/oxt_test_main.cpp +2 -0
  668. data/test/oxt/syscall_interruption_test.cpp +1 -0
  669. data/test/ruby/classic_rails/loader_spec.rb +48 -0
  670. data/test/ruby/classic_rails/preloader_spec.rb +54 -0
  671. data/test/ruby/rack/loader_spec.rb +62 -0
  672. data/test/ruby/rack/preloader_spec.rb +74 -0
  673. data/test/ruby/{abstract_request_handler_spec.rb → request_handler_spec.rb} +31 -68
  674. data/test/ruby/shared/loader_spec.rb +241 -0
  675. data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +141 -182
  676. data/test/ruby/shared/ruby_loader_spec.rb +55 -0
  677. data/test/ruby/spec_helper.rb +8 -53
  678. data/test/ruby/utils/file_system_watcher_spec.rb +9 -1
  679. data/test/ruby/utils_spec.rb +10 -683
  680. data/test/stub/rack/config.ru +28 -3
  681. data/test/stub/rack/start.rb +47 -0
  682. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/Rakefile +0 -0
  683. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/application_controller.rb +0 -2
  684. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_1.rb +0 -0
  685. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_2.rb +0 -0
  686. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/foo_controller.rb +0 -0
  687. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/helpers/application_helper.rb +0 -0
  688. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/boot.rb +0 -0
  689. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/database.yml +3 -3
  690. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environment.rb +5 -2
  691. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/development.rb +0 -0
  692. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/production.rb +0 -0
  693. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/staging.rb +0 -0
  694. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/inflections.rb +0 -0
  695. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/mime_types.rb +0 -0
  696. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/routes.rb +1 -0
  697. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/about +0 -0
  698. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/console +0 -0
  699. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/dbconsole +0 -0
  700. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/destroy +0 -0
  701. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/generate +0 -0
  702. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/benchmarker +0 -0
  703. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/profiler +0 -0
  704. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/request +0 -0
  705. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/plugin +0 -0
  706. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/inspector +0 -0
  707. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/reaper +0 -0
  708. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/spawner +0 -0
  709. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/runner +0 -0
  710. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/server +0 -0
  711. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Gemfile +0 -0
  712. data/test/stub/rails3.0/Gemfile.lock +80 -0
  713. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Rakefile +0 -0
  714. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/controllers/application_controller.rb +0 -0
  715. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/helpers/application_helper.rb +0 -0
  716. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/views/layouts/application.html.erb +0 -0
  717. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config.ru +0 -0
  718. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/application.rb +0 -0
  719. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/boot.rb +0 -0
  720. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/database.yml +0 -0
  721. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environment.rb +0 -0
  722. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/development.rb +0 -0
  723. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/production.rb +0 -0
  724. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/test.rb +0 -0
  725. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/backtrace_silencers.rb +0 -0
  726. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/inflections.rb +0 -0
  727. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/mime_types.rb +0 -0
  728. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/passenger.rb +0 -0
  729. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/secret_token.rb +0 -0
  730. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/session_store.rb +0 -0
  731. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/locales/en.yml +0 -0
  732. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/routes.rb +0 -0
  733. data/test/stub/{rails_apps/3.0/empty → rails3.0}/db/seeds.rb +0 -0
  734. data/test/stub/{rails_apps/3.0/empty → rails3.0}/doc/README_FOR_APP +0 -0
  735. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/404.html +0 -0
  736. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/422.html +0 -0
  737. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/500.html +0 -0
  738. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/favicon.ico +0 -0
  739. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/index.html +0 -0
  740. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/robots.txt +0 -0
  741. data/test/stub/{rails_apps/3.0/empty → rails3.0}/script/rails +0 -0
  742. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/performance/browsing_test.rb +0 -0
  743. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/test_helper.rb +0 -0
  744. data/test/stub/start_error.pl +24 -0
  745. data/test/stub/wsgi/passenger_wsgi.py +71 -3
  746. data/test/support/apache2_controller.rb +2 -2
  747. data/test/support/placebo-preloader.rb +88 -0
  748. data/test/support/test_helper.rb +1 -14
  749. data/test/tut/tut.h +11 -4
  750. metadata +590 -326
  751. data.tar.gz.asc +0 -12
  752. data/PACKAGING.TXT +0 -25
  753. data/build/config.rb +0 -46
  754. data/ext/apache2/HelperAgent.cpp +0 -364
  755. data/ext/boost/call_traits.hpp +0 -24
  756. data/ext/boost/detail/call_traits.hpp +0 -164
  757. data/ext/common/AbstractSpawnManager.h +0 -110
  758. data/ext/common/AgentBase.cpp +0 -432
  759. data/ext/common/ApplicationPool/Client.h +0 -788
  760. data/ext/common/ApplicationPool/Interface.h +0 -295
  761. data/ext/common/ApplicationPool/Pool.h +0 -1327
  762. data/ext/common/ApplicationPool/Server.h +0 -479
  763. data/ext/common/MessageChannel.h +0 -494
  764. data/ext/common/PoolOptions.h +0 -518
  765. data/ext/common/Process.h +0 -253
  766. data/ext/common/Session.h +0 -436
  767. data/ext/common/SpawnManager.h +0 -611
  768. data/ext/google/ChangeLog +0 -167
  769. data/ext/google/dense_hash_map +0 -310
  770. data/ext/google/dense_hash_set +0 -287
  771. data/ext/google/sparse_hash_map +0 -294
  772. data/ext/google/sparse_hash_set +0 -275
  773. data/ext/google/sparsehash/densehashtable.h +0 -1062
  774. data/ext/google/sparsehash/sparseconfig.h +0 -55
  775. data/ext/google/sparsehash/sparsehashtable.h +0 -1015
  776. data/ext/google/sparsetable +0 -1468
  777. data/ext/google/type_traits.h +0 -250
  778. data/ext/nginx/HelperAgent.cpp +0 -1355
  779. data/ext/nginx/ScgiRequestParser.h +0 -375
  780. data/ext/oxt/backtrace.cpp +0 -185
  781. data/ext/oxt/tracable_exception.cpp +0 -89
  782. data/helper-scripts/passenger-spawn-server +0 -106
  783. data/lib/phusion_passenger/abstract_request_handler.rb +0 -766
  784. data/lib/phusion_passenger/abstract_server.rb +0 -372
  785. data/lib/phusion_passenger/abstract_server_collection.rb +0 -335
  786. data/lib/phusion_passenger/app_process.rb +0 -174
  787. data/lib/phusion_passenger/classic_rails/application_spawner.rb +0 -344
  788. data/lib/phusion_passenger/classic_rails/framework_spawner.rb +0 -311
  789. data/lib/phusion_passenger/exceptions.rb +0 -103
  790. data/lib/phusion_passenger/html_template.rb +0 -107
  791. data/lib/phusion_passenger/rack/application_spawner.rb +0 -231
  792. data/lib/phusion_passenger/spawn_manager.rb +0 -359
  793. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +0 -38
  794. data/lib/phusion_passenger/templates/app_init_error.html.erb +0 -64
  795. data/lib/phusion_passenger/templates/database_error.html.erb +0 -66
  796. data/lib/phusion_passenger/templates/error_layout.html.erb +0 -39
  797. data/lib/phusion_passenger/templates/framework_init_error.html.erb +0 -39
  798. data/lib/phusion_passenger/templates/general_error.html.erb +0 -22
  799. data/lib/phusion_passenger/templates/load_error.html.erb +0 -46
  800. data/lib/phusion_passenger/templates/version_not_found.html.erb +0 -34
  801. data/lib/phusion_passenger/utils/rewindable_input.rb +0 -125
  802. data/lib/phusion_passenger/wsgi/application_spawner.rb +0 -108
  803. data/test/config.yml.example +0 -41
  804. data/test/cxx/ApplicationPool_PoolTest.cpp +0 -33
  805. data/test/cxx/ApplicationPool_PoolTestCases.cpp +0 -1029
  806. data/test/cxx/ApplicationPool_ServerTest.cpp +0 -308
  807. data/test/cxx/ApplicationPool_Server_PoolTest.cpp +0 -80
  808. data/test/cxx/MessageChannelTest.cpp +0 -557
  809. data/test/cxx/PoolOptionsTest.cpp +0 -116
  810. data/test/cxx/SpawnManagerTest.cpp +0 -161
  811. data/test/ruby/abstract_server_collection_spec.rb +0 -247
  812. data/test/ruby/abstract_server_spec.rb +0 -61
  813. data/test/ruby/app_process_spec.rb +0 -43
  814. data/test/ruby/classic_rails/application_spawner_spec.rb +0 -89
  815. data/test/ruby/classic_rails/framework_spawner_spec.rb +0 -92
  816. data/test/ruby/rack/application_spawner_spec.rb +0 -116
  817. data/test/ruby/shared/abstract_server_spec.rb +0 -23
  818. data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +0 -38
  819. data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +0 -19
  820. data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +0 -15
  821. data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +0 -27
  822. data/test/ruby/shared/spawners/preloading_spawner_spec.rb +0 -29
  823. data/test/ruby/shared/spawners/reload_all_spec.rb +0 -36
  824. data/test/ruby/shared/spawners/reload_single_spec.rb +0 -52
  825. data/test/ruby/shared/spawners/spawn_server_spec.rb +0 -28
  826. data/test/ruby/shared/spawners/spawner_spec.rb +0 -273
  827. data/test/ruby/shared/utils/pseudo_io_spec.rb +0 -60
  828. data/test/ruby/spawn_manager_spec.rb +0 -134
  829. data/test/ruby/wsgi/application_spawner_spec.rb +0 -50
  830. data/test/stub/message_channel.rb +0 -11
  831. data/test/stub/message_channel_2.rb +0 -12
  832. data/test/stub/message_channel_3.rb +0 -19
  833. data/test/stub/rails_apps/3.0/empty/Gemfile.lock +0 -73
  834. data/test/stub/spawn_server.rb +0 -22
  835. metadata.gz.asc +0 -12
@@ -1,108 +0,0 @@
1
- # Phusion Passenger - http://www.modrails.com/
2
- # Copyright (c) 2010 Phusion
3
- #
4
- # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
5
- #
6
- # Permission is hereby granted, free of charge, to any person obtaining a copy
7
- # of this software and associated documentation files (the "Software"), to deal
8
- # in the Software without restriction, including without limitation the rights
9
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- # copies of the Software, and to permit persons to whom the Software is
11
- # furnished to do so, subject to the following conditions:
12
- #
13
- # The above copyright notice and this permission notice shall be included in
14
- # all copies or substantial portions of the Software.
15
- #
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- # THE SOFTWARE.
23
-
24
- require 'socket'
25
- require 'phusion_passenger/app_process'
26
- require 'phusion_passenger/message_channel'
27
- require 'phusion_passenger/public_api'
28
- require 'phusion_passenger/utils'
29
- require 'phusion_passenger/utils/tmpdir'
30
- require 'phusion_passenger/native_support'
31
-
32
- module PhusionPassenger
33
- module WSGI
34
-
35
- # Class for spawning WSGI applications.
36
- class ApplicationSpawner
37
- include Utils
38
- REQUEST_HANDLER = File.expand_path(File.dirname(__FILE__) + "/request_handler.py")
39
-
40
- def self.spawn_application(*args)
41
- @@instance ||= ApplicationSpawner.new
42
- @@instance.spawn_application(*args)
43
- end
44
-
45
- # Spawn an instance of the given WSGI application. When successful, an
46
- # Application object will be returned, which represents the spawned
47
- # application.
48
- #
49
- # Raises:
50
- # - AppInitError: The WSGI application raised an exception or called
51
- # exit() during startup.
52
- # - SystemCallError, IOError, SocketError: Something went wrong.
53
- def spawn_application(options)
54
- a, b = UNIXSocket.pair
55
- pid = safe_fork(self.class.to_s, true) do
56
- a.close
57
-
58
- file_descriptors_to_leave_open = [0, 1, 2, b.fileno]
59
- NativeSupport.close_all_file_descriptors(file_descriptors_to_leave_open)
60
- close_all_io_objects_for_fds(file_descriptors_to_leave_open)
61
-
62
- run(MessageChannel.new(b), options)
63
- end
64
- b.close
65
- Process.waitpid(pid) rescue nil
66
-
67
- channel = MessageChannel.new(a)
68
- return AppProcess.read_from_channel(channel)
69
- end
70
-
71
- private
72
- def run(channel, options)
73
- $0 = "WSGI: #{options['app_group_name']}"
74
- prepare_app_process("passenger_wsgi.py", options)
75
- ENV['WSGI_ENV'] = options['environment']
76
-
77
- if defined?(NativeSupport)
78
- unix_path_max = NativeSupport::UNIX_PATH_MAX
79
- else
80
- unix_path_max = 100
81
- end
82
-
83
- socket_file = "#{passenger_tmpdir}/backends/wsgi.#{Process.pid}.#{rand 10000000}"
84
- socket_file = socket_file.slice(0, unix_path_max - 1)
85
- server = UNIXServer.new(socket_file)
86
- begin
87
- File.chmod(0666, socket_file)
88
- reader, writer = IO.pipe
89
- app_process = AppProcess.new(options["app_root"], Process.pid, writer,
90
- :main => [socket_file, 'unix'])
91
- app_process.write_to_channel(channel)
92
- writer.close
93
- channel.close
94
-
95
- NativeSupport.close_all_file_descriptors([0, 1, 2, server.fileno,
96
- reader.fileno])
97
- exec(REQUEST_HANDLER, socket_file, server.fileno.to_s,
98
- reader.fileno.to_s)
99
- rescue
100
- server.close
101
- File.unlink(socket_file)
102
- raise
103
- end
104
- end
105
- end
106
-
107
- end # module WSGI
108
- end # module PhusionPassenger
@@ -1,41 +0,0 @@
1
- ### This file contains system-specific configuration options that the test suite needs.
2
- ### Please customize it for your system.
3
-
4
- # These are the usernames and group names of normal, non-administrator
5
- # users and groups. Preferably, these are user and group accounts that
6
- # are normally not used.
7
- #
8
- # These users and groups MUST be able to access this 'test' directory,
9
- # otherwise the tests will fail.
10
-
11
- ### Good values for Linux and FreeBSD:
12
- normal_user_1: games
13
- normal_user_2: daemon
14
- # Must not be "nobody".
15
- default_user: man
16
- # Must not be normal_user_1's primary group.
17
- normal_group_1: daemon
18
- # Must not be normal_user_2's primary group.
19
- normal_group_2: man
20
- # Must not be default_user's primary group. Must not be "nobody".
21
- default_group: games
22
-
23
- ### Good values for OS X. Same restrictions apply.
24
- # normal_user_1: _www
25
- # normal_user_2: daemon
26
- # default_user: _sandbox
27
- # normal_group_1: daemon
28
- # normal_group_2: _sandbox
29
- # default_group: _www
30
-
31
- # A nonexistant username, group name, user ID and group ID.
32
- nonexistant_user: xxxxxxxxxxxxxxxxxxx
33
- nonexistant_group: xxxxxxxxxxxxxxxxxxx
34
- nonexistant_uid: 9999
35
- nonexistant_gid: 9999
36
-
37
-
38
- # If you want to run the Nginx integration tests, then set the following
39
- # config option to the full path of the Nginx binary. This Nginx binary *must*
40
- # be compiled with Phusion Passenger support!
41
- # nginx: /usr/local/sbin/nginx
@@ -1,33 +0,0 @@
1
- #include "TestSupport.h"
2
- #include "ApplicationPool/Pool.h"
3
- #include "Utils.h"
4
-
5
- using namespace Passenger;
6
-
7
- namespace tut {
8
- struct ApplicationPool_PoolTest {
9
- ServerInstanceDirPtr serverInstanceDir;
10
- ServerInstanceDir::GenerationPtr generation;
11
- ApplicationPool::Ptr pool, pool2;
12
-
13
- ApplicationPool_PoolTest() {
14
- createServerInstanceDirAndGeneration(serverInstanceDir, generation);
15
- pool = ptr(new ApplicationPool::Pool("../helper-scripts/passenger-spawn-server", generation));
16
- pool2 = pool;
17
- }
18
-
19
- ApplicationPool::Ptr newPoolConnection() {
20
- return pool;
21
- }
22
-
23
- void reinitializeWithSpawnManager(AbstractSpawnManagerPtr spawnManager) {
24
- pool = ptr(new ApplicationPool::Pool(spawnManager));
25
- pool2 = pool;
26
- }
27
- };
28
-
29
- DEFINE_TEST_GROUP(ApplicationPool_PoolTest);
30
-
31
- #define USE_TEMPLATE
32
- #include "ApplicationPool_PoolTestCases.cpp"
33
- }
@@ -1,1029 +0,0 @@
1
- #include <sys/types.h>
2
- #include <sys/stat.h>
3
- #include <unistd.h>
4
- #include <cstring>
5
- #include <cstdlib>
6
- #include <cerrno>
7
- #include <sys/types.h>
8
- #include <signal.h>
9
- #include <utime.h>
10
-
11
- /**
12
- * This file is used as a template to test the different ApplicationPool::Interface implementations.
13
- * It is #included in ApplicationPool_PoolTest.cpp and ApplicationPool_Server_PoolTest.cpp
14
- */
15
- #ifdef USE_TEMPLATE
16
- static void sendTestRequest(SessionPtr &session, const char *uri = "/foo/new") {
17
- string headers;
18
- #define ADD_HEADER(name, value) \
19
- headers.append(name); \
20
- headers.append(1, '\0'); \
21
- headers.append(value); \
22
- headers.append(1, '\0')
23
- ADD_HEADER("HTTP_HOST", "www.test.com");
24
- ADD_HEADER("QUERY_STRING", "");
25
- ADD_HEADER("REQUEST_URI", uri);
26
- ADD_HEADER("REQUEST_METHOD", "GET");
27
- ADD_HEADER("REMOTE_ADDR", "localhost");
28
- ADD_HEADER("SCRIPT_NAME", "");
29
- ADD_HEADER("PATH_INFO", uri);
30
- ADD_HEADER("PASSENGER_CONNECT_PASSWORD", session->getConnectPassword());
31
- session->sendHeaders(headers);
32
- }
33
-
34
- static SessionPtr spawnRackApp(ApplicationPool::Ptr pool, const char *appRoot) {
35
- PoolOptions options;
36
- options.appRoot = appRoot;
37
- options.appType = "rack";
38
- return pool->get(options);
39
- }
40
-
41
- static SessionPtr spawnWsgiApp(ApplicationPool::Ptr pool, const char *appRoot) {
42
- PoolOptions options;
43
- options.appRoot = appRoot;
44
- options.appType = "wsgi";
45
- return pool->get(options);
46
- }
47
-
48
- namespace {
49
- class ReloadLoggingSpawnManager: public SpawnManager {
50
- public:
51
- vector<string> reloadLog;
52
-
53
- ReloadLoggingSpawnManager(const string &spawnServerCommand,
54
- const ServerInstanceDir::GenerationPtr &generation,
55
- const AccountsDatabasePtr &accountsDatabase = AccountsDatabasePtr(),
56
- const string &rubyCommand = "ruby")
57
- : SpawnManager(spawnServerCommand, generation, accountsDatabase, rubyCommand)
58
- { }
59
-
60
- virtual void reload(const string &appRoot) {
61
- reloadLog.push_back(appRoot);
62
- SpawnManager::reload(appRoot);
63
- }
64
- };
65
-
66
- struct SpawnRackAppFunction {
67
- ApplicationPool::Ptr pool;
68
- bool *done;
69
- SessionPtr *session;
70
-
71
- SpawnRackAppFunction() {
72
- done = NULL;
73
- session = NULL;
74
- }
75
-
76
- void operator()() {
77
- PoolOptions options;
78
- options.appRoot = "stub/rack";
79
- options.appType = "rack";
80
- options.useGlobalQueue = true;
81
- SessionPtr session = pool->get(options);
82
- *done = true;
83
- if (this->session != NULL) {
84
- *this->session = session;
85
- }
86
- }
87
- };
88
- }
89
-
90
- TEST_METHOD(1) {
91
- // Calling ApplicationPool.get() once should return a valid Session.
92
- SessionPtr session(spawnRackApp(pool, "stub/rack"));
93
- sendTestRequest(session);
94
- session->shutdownWriter();
95
-
96
- int reader = session->getStream();
97
- string result(readAll(reader));
98
- session->closeStream();
99
- ensure(result.find("hello <b>world</b>") != string::npos);
100
- }
101
-
102
- TEST_METHOD(2) {
103
- // Verify that the pool spawns a new app, and that
104
- // after the session is closed, the app is kept around.
105
- SessionPtr session(spawnRackApp(pool, "stub/rack"));
106
- ensure_equals("Before the session was closed, the app was busy", pool->getActive(), 1u);
107
- ensure_equals("Before the session was closed, the app was in the pool", pool->getCount(), 1u);
108
- session.reset();
109
- ensure_equals("After the session is closed, the app is no longer busy", pool->getActive(), 0u);
110
- ensure_equals("After the session is closed, the app is kept around", pool->getCount(), 1u);
111
- }
112
-
113
- TEST_METHOD(3) {
114
- // If we call get() with an application root, then we close the session,
115
- // and then we call get() again with the same app group name,
116
- // then the pool should not have spawned more than 1 app in total.
117
- SessionPtr session(spawnRackApp(pool, "stub/rack"));
118
- session.reset();
119
- session = spawnRackApp(pool, "stub/rack");
120
- ensure_equals(pool->getCount(), 1u);
121
- }
122
-
123
- TEST_METHOD(4) {
124
- // If we call get() with an app group name, then we call get() again before closing
125
- // the session, then the pool will eventually have spawned 2 apps in total.
126
- SessionPtr session(spawnRackApp(pool, "stub/rack"));
127
- SessionPtr session2(spawnRackApp(pool2, "stub/rack"));
128
- EVENTUALLY(5,
129
- result = pool->getCount() == 2u;
130
- );
131
- }
132
-
133
- TEST_METHOD(5) {
134
- // If we call get() twice with different app group names,
135
- // then the pool should spawn two different apps.
136
- TempDirCopy c1("stub/rack", "rackapp1.tmp");
137
- TempDirCopy c2("stub/rack", "rackapp2.tmp");
138
- replaceStringInFile("rackapp2.tmp/config.ru", "world", "world 2");
139
- SessionPtr session = spawnRackApp(pool, "rackapp1.tmp");
140
- SessionPtr session2 = spawnRackApp(pool2, "rackapp2.tmp");
141
- ensure_equals("Before the sessions were closed, both apps were busy", pool->getActive(), 2u);
142
- ensure_equals("Before the sessions were closed, both apps were in the pool", pool->getCount(), 2u);
143
-
144
- sendTestRequest(session);
145
- string result = readAll(session->getStream());
146
- ensure("Session 1 belongs to the correct app", result.find("hello <b>world</b>") != string::npos);
147
- session.reset();
148
-
149
- sendTestRequest(session2);
150
- result = readAll(session2->getStream());
151
- ensure("Session 2 belongs to the correct app", result.find("hello <b>world 2</b>") != string::npos);
152
- session2.reset();
153
- }
154
-
155
- TEST_METHOD(6) {
156
- // If we call get() twice with different app group names,
157
- // and we close both sessions, then both 2 apps should still
158
- // be in the pool.
159
- TempDirCopy c1("stub/rack", "rackapp1.tmp");
160
- TempDirCopy c2("stub/rack", "rackapp2.tmp");
161
- SessionPtr session(spawnRackApp(pool, "rackapp1.tmp"));
162
- SessionPtr session2(spawnRackApp(pool, "rackapp2.tmp"));
163
- session.reset();
164
- session2.reset();
165
- ensure_equals("There are 0 active apps", pool->getActive(), 0u);
166
- ensure_equals("There are 2 apps in total", pool->getCount(), 2u);
167
- }
168
-
169
- TEST_METHOD(7) {
170
- // If we call get() even though the pool is already full
171
- // (active == max), and the app group name is already
172
- // in the pool, then the pool must wait until there's an
173
- // inactive application.
174
- pool->setMax(1);
175
- // TODO: How do we test this?
176
- }
177
-
178
- TEST_METHOD(8) {
179
- // If ApplicationPool spawns a new instance,
180
- // and we kill it, then the next get() with the
181
- // same application root should not throw an exception:
182
- // ApplicationPool should spawn a new instance
183
- // after detecting that the original one died.
184
- SessionPtr session = spawnRackApp(pool, "stub/rack");
185
- kill(session->getPid(), SIGKILL);
186
- session.reset();
187
- usleep(20000); // Give the process some time to exit.
188
- spawnRackApp(pool, "stub/rack"); // should not throw
189
- }
190
-
191
- struct PoolWaitTestThread {
192
- ApplicationPool::Ptr pool;
193
- SessionPtr &m_session;
194
- bool &m_done;
195
-
196
- PoolWaitTestThread(const ApplicationPool::Ptr &pool,
197
- SessionPtr &session,
198
- bool &done)
199
- : m_session(session), m_done(done) {
200
- this->pool = pool;
201
- done = false;
202
- }
203
-
204
- void operator()() {
205
- m_session = spawnWsgiApp(pool, "stub/wsgi");
206
- m_done = true;
207
- }
208
- };
209
-
210
- TEST_METHOD(9) {
211
- // If we call get() even though the pool is already full
212
- // (active == max), and the app group name is *not* already
213
- // in the pool, then the pool will wait until enough sessions
214
- // have been closed.
215
-
216
- // Make the pool full.
217
- pool->setMax(2);
218
- SessionPtr session1 = spawnRackApp(pool, "stub/rack");
219
- SessionPtr session2 = spawnRackApp(pool2, "stub/rack");
220
- EVENTUALLY(5,
221
- result = pool->getCount() == 2u;
222
- );
223
- session1.reset();
224
- session2.reset();
225
- EVENTUALLY(5,
226
- result = pool->getActive() == 0u;
227
- );
228
- session1 = spawnRackApp(pool, "stub/rack");
229
- session2 = spawnRackApp(pool2, "stub/rack");
230
- ensure_equals(pool->getActive(), 2u);
231
-
232
- // Now spawn an app with a different app root.
233
- SessionPtr session3;
234
- bool done;
235
- TempThread thr(PoolWaitTestThread(pool2, session3, done));
236
- usleep(500000);
237
- ensure("ApplicationPool is still waiting", !done);
238
- ensure_equals(pool->getActive(), 2u);
239
- ensure_equals(pool->getCount(), 2u);
240
-
241
- // Now release one slot from the pool.
242
- session1.reset();
243
-
244
- // Session 3 should eventually be opened.
245
- EVENTUALLY(10,
246
- result = done;
247
- );
248
- ensure_equals(pool->getActive(), 2u);
249
- ensure_equals(pool->getCount(), 2u);
250
- }
251
-
252
- TEST_METHOD(10) {
253
- // If we call get(), and:
254
- // * the pool is already full, but there are inactive apps
255
- // (active < count && count == max)
256
- // and
257
- // * the app group name for this get() is *not* already in the pool
258
- // then the an inactive app should be killed in order to
259
- // satisfy this get() command.
260
- TempDirCopy c1("stub/rack", "rackapp1.tmp");
261
- TempDirCopy c2("stub/rack", "rackapp2.tmp");
262
-
263
- // Make the pool full.
264
- pool->setMax(2);
265
- SessionPtr session1 = spawnRackApp(pool, "rackapp1.tmp");
266
- SessionPtr session2 = spawnRackApp(pool2, "rackapp1.tmp");
267
- EVENTUALLY(5,
268
- result = pool->getCount() == 2u;
269
- );
270
- session1.reset();
271
- session2.reset();
272
- EVENTUALLY(5,
273
- result = pool->getActive() == 0u;
274
- );
275
-
276
- // Now spawn a different app.
277
- session1 = spawnRackApp(pool, "rackapp2.tmp");
278
- ensure_equals(pool->getActive(), 1u);
279
- ensure_equals(pool->getCount(), 2u);
280
- }
281
-
282
- TEST_METHOD(11) {
283
- // A Session should still be usable after the pool has been destroyed.
284
- SessionPtr session = spawnRackApp(pool, "stub/rack");
285
- pool->clear();
286
- pool.reset();
287
- pool2.reset();
288
-
289
- sendTestRequest(session);
290
- session->shutdownWriter();
291
-
292
- int reader = session->getStream();
293
- string result = readAll(reader);
294
- session->closeStream();
295
- ensure(result.find("hello <b>world</b>") != string::npos);
296
- }
297
-
298
- TEST_METHOD(12) {
299
- // If tmp/restart.txt didn't exist but has now been created,
300
- // then the applications under app_root should be restarted.
301
- struct stat buf;
302
- TempDirCopy c("stub/rack", "rackapp.tmp");
303
- SessionPtr session1 = spawnRackApp(pool, "rackapp.tmp");
304
- SessionPtr session2 = spawnRackApp(pool2, "rackapp.tmp");
305
- session1.reset();
306
- session2.reset();
307
- EVENTUALLY(5,
308
- result = pool->getCount() == 2u;
309
- );
310
-
311
- touchFile("rackapp.tmp/tmp/restart.txt");
312
- spawnRackApp(pool, "rackapp.tmp");
313
-
314
- ensure_equals("No apps are active", pool->getActive(), 0u);
315
- ensure_equals("Both apps are killed, and a new one was spawned",
316
- pool->getCount(), 1u);
317
- ensure("Restart file still exists",
318
- stat("rackapp.tmp/tmp/restart.txt", &buf) == 0);
319
- }
320
-
321
- TEST_METHOD(13) {
322
- // If tmp/restart.txt was present, and its timestamp changed
323
- // since the last check, then the applications under the app group name
324
- // should still be restarted. However, a subsequent get()
325
- // should not result in a restart.
326
- pid_t old_pid;
327
- TempDirCopy c("stub/rack", "rackapp.tmp");
328
- TempDir d("rackapp.tmp/tmp/restart.txt");
329
- SessionPtr session = spawnRackApp(pool, "rackapp.tmp");
330
- old_pid = session->getPid();
331
- session.reset();
332
- EVENTUALLY(5,
333
- result = pool->getActive() == 0u;
334
- );
335
-
336
- touchFile("rackapp.tmp/tmp/restart.txt", 10);
337
-
338
- session = spawnRackApp(pool, "rackapp.tmp");
339
- ensure("The app was restarted", session->getPid() != old_pid);
340
- old_pid = session->getPid();
341
- session.reset();
342
- EVENTUALLY(5,
343
- result = pool->getActive() == 0u;
344
- );
345
-
346
- session = spawnRackApp(pool, "rackapp.tmp");
347
- ensure_equals("The app was not restarted",
348
- old_pid, session->getPid());
349
- }
350
-
351
- TEST_METHOD(15) {
352
- // Test whether restarting with restart.txt really results in code reload.
353
- TempDirCopy c("stub/rack", "rackapp.tmp");
354
- SessionPtr session = spawnRackApp(pool, "rackapp.tmp");
355
- sendTestRequest(session);
356
- string result = readAll(session->getStream());
357
- ensure(result.find("hello <b>world</b>") != string::npos);
358
- session.reset();
359
- EVENTUALLY(5,
360
- result = pool->getActive() == 0u;
361
- );
362
-
363
- touchFile("rackapp.tmp/tmp/restart.txt");
364
- replaceStringInFile("rackapp.tmp/config.ru", "world", "world 2");
365
-
366
- session = spawnRackApp(pool, "rackapp.tmp");
367
- sendTestRequest(session);
368
- result = readAll(session->getStream());
369
- ensure("App code has been reloaded", result.find("hello <b>world 2</b>") != string::npos);
370
- }
371
-
372
- TEST_METHOD(16) {
373
- // If tmp/always_restart.txt is present and is a file,
374
- // then the application under app_root should be always restarted.
375
- struct stat buf;
376
- pid_t old_pid;
377
- TempDirCopy c("stub/rack", "rackapp.tmp");
378
- SessionPtr session1 = spawnRackApp(pool, "rackapp.tmp");
379
- SessionPtr session2 = spawnRackApp(pool2, "rackapp.tmp");
380
- session1.reset();
381
- session2.reset();
382
- EVENTUALLY(5,
383
- result = pool->getActive() == 0u && pool->getCount() == 2u;
384
- );
385
-
386
- touchFile("rackapp.tmp/tmp/always_restart.txt");
387
-
388
- // This get() results in a restart.
389
- session1 = spawnRackApp(pool, "rackapp.tmp");
390
- old_pid = session1->getPid();
391
- session1.reset();
392
- EVENTUALLY(5,
393
- // First restart: no apps are active
394
- result = pool->getActive() == 0u;
395
- );
396
- ensure_equals("First restart: the first 2 apps were killed, and a new one was spawned",
397
- pool->getCount(), 1u);
398
- ensure("always_restart file has not been deleted",
399
- stat("rackapp.tmp/tmp/always_restart.txt", &buf) == 0);
400
-
401
- // This get() results in a restart as well.
402
- session1 = spawnRackApp(pool, "rackapp.tmp");
403
- ensure(old_pid != session1->getPid());
404
- session1.reset();
405
- EVENTUALLY(5,
406
- // Second restart: no apps are active
407
- result = pool->getActive() == 0u;
408
- );
409
- ensure_equals("Second restart: the last app was killed, and a new one was spawned",
410
- pool->getCount(), 1u);
411
- ensure("always_restart file has not been deleted",
412
- stat("rackapp.tmp/tmp/always_restart.txt", &buf) == 0);
413
- }
414
-
415
- TEST_METHOD(17) {
416
- // If tmp/always_restart.txt is present and is a directory,
417
- // then the application under app_root should be always restarted.
418
- struct stat buf;
419
- pid_t old_pid;
420
- TempDirCopy c("stub/rack", "rackapp.tmp");
421
- SessionPtr session1 = spawnRackApp(pool, "rackapp.tmp");
422
- SessionPtr session2 = spawnRackApp(pool2, "rackapp.tmp");
423
- session1.reset();
424
- session2.reset();
425
- EVENTUALLY(5,
426
- result = pool->getActive() == 0u && pool->getCount() == 2u;
427
- );
428
-
429
- TempDir d("rackapp.tmp/tmp/always_restart.txt");
430
-
431
- // This get() results in a restart.
432
- session1 = spawnRackApp(pool, "rackapp.tmp");
433
- old_pid = session1->getPid();
434
- session1.reset();
435
- EVENTUALLY(5,
436
- // First restart: no apps are active
437
- result = pool->getActive() == 0u;
438
- );
439
- ensure_equals("First restart: the first 2 apps were killed, and a new one was spawned",
440
- pool->getCount(), 1u);
441
- ensure("always_restart directory has not been deleted",
442
- stat("rackapp.tmp/tmp/always_restart.txt", &buf) == 0);
443
-
444
- // This get() results in a restart as well.
445
- session1 = spawnRackApp(pool, "rackapp.tmp");
446
- ensure(old_pid != session1->getPid());
447
- session1.reset();
448
- EVENTUALLY(5,
449
- // Second restart: no apps are active
450
- result = pool->getActive() == 0u;
451
- );
452
- ensure_equals("Second restart: the last app was killed, and a new one was spawned",
453
- pool->getCount(), 1u);
454
- ensure("always_restart directory has not been deleted",
455
- stat("rackapp.tmp/tmp/always_restart.txt", &buf) == 0);
456
- }
457
-
458
- TEST_METHOD(18) {
459
- // Test whether restarting with tmp/always_restart.txt really results in code reload.
460
- TempDirCopy c("stub/rack", "rackapp.tmp");
461
- SessionPtr session = spawnRackApp(pool, "rackapp.tmp");
462
- sendTestRequest(session);
463
- string result = readAll(session->getStream());
464
- ensure(result.find("hello <b>world</b>") != string::npos);
465
- session.reset();
466
-
467
- touchFile("rackapp.tmp/tmp/always_restart.txt");
468
- replaceStringInFile("rackapp.tmp/config.ru", "world", "world 2");
469
-
470
- session = spawnRackApp(pool, "rackapp.tmp");
471
- sendTestRequest(session);
472
- result = readAll(session->getStream());
473
- ensure("App code has been reloaded (1)", result.find("hello <b>world 2</b>") != string::npos);
474
- session.reset();
475
- EVENTUALLY(5,
476
- result = pool->getActive() == 0u;
477
- );
478
-
479
- replaceStringInFile("rackapp.tmp/config.ru", "world 2", "world 3");
480
- session = spawnRackApp(pool, "rackapp.tmp");
481
- sendTestRequest(session);
482
- result = readAll(session->getStream());
483
- ensure("App code has been reloaded (2)", result.find("hello <b>world 3</b>") != string::npos);
484
- session.reset();
485
- }
486
-
487
- TEST_METHOD(19) {
488
- // If tmp/restart.txt and tmp/always_restart.txt are present,
489
- // the application under app_root should still be restarted and
490
- // both files must be kept.
491
- pid_t old_pid, pid;
492
- struct stat buf;
493
- TempDirCopy c("stub/rack", "rackapp.tmp");
494
- SessionPtr session1 = spawnRackApp(pool, "rackapp.tmp");
495
- SessionPtr session2 = spawnRackApp(pool2, "rackapp.tmp");
496
- session1.reset();
497
- session2.reset();
498
- EVENTUALLY(5,
499
- result = pool->getActive() == 0u && pool->getCount() == 2u;
500
- );
501
-
502
- touchFile("rackapp.tmp/tmp/restart.txt");
503
- touchFile("rackapp.tmp/tmp/always_restart.txt");
504
-
505
- old_pid = spawnRackApp(pool, "rackapp.tmp")->getPid();
506
- ensure("always_restart.txt file has not been deleted",
507
- stat("rackapp.tmp/tmp/always_restart.txt", &buf) == 0);
508
- ensure("restart.txt file has not been deleted",
509
- stat("rackapp.tmp/tmp/restart.txt", &buf) == 0);
510
- EVENTUALLY(5,
511
- result = pool->getActive() == 0u;
512
- );
513
-
514
- pid = spawnRackApp(pool, "rackapp.tmp")->getPid();
515
- ensure("The app was restarted", pid != old_pid);
516
- }
517
-
518
- TEST_METHOD(20) {
519
- // It should look for restart.txt in the directory given by
520
- // the restartDir option, if available.
521
- struct stat buf;
522
- char path[1024];
523
- PoolOptions options("stub/rack");
524
- options.appType = "rack";
525
- options.restartDir = string(getcwd(path, sizeof(path))) + "/stub/rack";
526
-
527
- SessionPtr session1 = pool->get(options);
528
- SessionPtr session2 = pool2->get(options);
529
- session1.reset();
530
- session2.reset();
531
- EVENTUALLY(5,
532
- result = pool->getActive() == 0u && pool->getCount() == 2u;
533
- );
534
-
535
- DeleteFileEventually f("stub/rack/restart.txt");
536
- touchFile("stub/rack/restart.txt");
537
-
538
- pool->get(options);
539
-
540
- ensure_equals("No apps are active", pool->getActive(), 0u);
541
- ensure_equals("Both apps are killed, and a new one was spawned",
542
- pool->getCount(), 1u);
543
- ensure("Restart file still exists",
544
- stat("stub/rack/restart.txt", &buf) == 0);
545
- }
546
-
547
- TEST_METHOD(21) {
548
- // restartDir may also be a directory relative to the
549
- // application root.
550
- struct stat buf;
551
- PoolOptions options("stub/rack");
552
- options.appType = "rack";
553
- options.restartDir = "public";
554
-
555
- SessionPtr session1 = pool->get(options);
556
- SessionPtr session2 = pool2->get(options);
557
- session1.reset();
558
- session2.reset();
559
- EVENTUALLY(5,
560
- result = pool->getActive() == 0u && pool->getCount() == 2u;
561
- );
562
-
563
- DeleteFileEventually f("stub/rack/public/restart.txt");
564
- touchFile("stub/rack/public/restart.txt");
565
-
566
- pool->get(options);
567
-
568
- ensure_equals("No apps are active", pool->getActive(), 0u);
569
- ensure_equals("Both apps are killed, and a new one was spawned",
570
- pool->getCount(), 1u);
571
- ensure("Restart file still exists",
572
- stat("stub/rack/public/restart.txt", &buf) == 0);
573
- }
574
-
575
- TEST_METHOD(22) {
576
- // The cleaner thread should clean idle applications.
577
- pool->setMaxIdleTime(1);
578
- spawnRackApp(pool, "stub/rack");
579
- EVENTUALLY(10,
580
- result = pool->getCount() == 0u;
581
- );
582
-
583
- time_t begin = time(NULL);
584
- while (pool->getCount() == 1u && time(NULL) - begin < 10) {
585
- usleep(100000);
586
- }
587
- ensure_equals("App should have been cleaned up", pool->getCount(), 0u);
588
- }
589
-
590
- TEST_METHOD(23) {
591
- // MaxPerApp is respected.
592
- pool->setMax(3);
593
- pool->setMaxPerApp(1);
594
-
595
- // We connect to stub/rack while it already has an instance with
596
- // 1 request in its queue. Assert that the pool doesn't spawn
597
- // another instance.
598
- SessionPtr session1 = spawnRackApp(pool, "stub/rack");
599
- SessionPtr session2 = spawnRackApp(pool2, "stub/rack");
600
-
601
- // We connect to stub/wsgi. Assert that the pool spawns a new
602
- // instance for this app.
603
- TempDirCopy c("stub/wsgi", "wsgiapp.tmp");
604
- ApplicationPool::Ptr pool3 = newPoolConnection();
605
- SessionPtr session3 = spawnWsgiApp(pool3, "wsgiapp.tmp");
606
- ensure_equals(pool->getCount(), 2u);
607
- }
608
-
609
- TEST_METHOD(24) {
610
- // Application instance is shutdown after 'maxRequests' requests.
611
- PoolOptions options("stub/rack");
612
- int reader;
613
- pid_t originalPid;
614
- SessionPtr session;
615
-
616
- options.appType = "rack";
617
- options.maxRequests = 4;
618
- pool->setMax(1);
619
- session = pool->get(options);
620
- originalPid = session->getPid();
621
- session.reset();
622
- EVENTUALLY(5,
623
- result = pool->getActive() == 0u;
624
- );
625
-
626
- for (unsigned int i = 0; i < 4; i++) {
627
- session = pool->get(options);
628
- sendTestRequest(session);
629
- session->shutdownWriter();
630
- reader = session->getStream();
631
- readAll(reader);
632
- // Must explicitly call reset() here because we
633
- // want to close the session right now.
634
- session.reset();
635
- EVENTUALLY(5,
636
- result = pool->getActive() == 0u;
637
- );
638
- }
639
-
640
- session = pool->get(options);
641
- ensure(session->getPid() != originalPid);
642
- }
643
-
644
- TEST_METHOD(25) {
645
- // If global queueing mode is enabled, then get() waits until
646
- // there's at least one idle backend process for this application
647
- // domain.
648
- pool->setMax(1);
649
-
650
- PoolOptions options;
651
- options.appRoot = "stub/rack";
652
- options.appType = "rack";
653
- options.useGlobalQueue = true;
654
- SessionPtr session = pool->get(options);
655
-
656
- bool done = false;
657
- SpawnRackAppFunction func;
658
- func.pool = pool2;
659
- func.done = &done;
660
- TempThread thr(func);
661
-
662
- // Previous session hasn't been closed yet, so pool should still
663
- // be waiting.
664
- usleep(100000);
665
- ensure("(1)", !done);
666
- ensure_equals("(2)", pool->getGlobalQueueSize(), 1u);
667
- ensure_equals("(3)", pool->getActive(), 1u);
668
- ensure_equals("(4)", pool->getCount(), 1u);
669
-
670
- // Close the previous session. The thread should now finish.
671
- session.reset();
672
- EVENTUALLY(5,
673
- result = done;
674
- );
675
- }
676
-
677
- TEST_METHOD(26) {
678
- // When a previous application group spinned down, and we touched
679
- // restart.txt and try to spin up a new process for this domain,
680
- // then any ApplicationSpawner/FrameworkSpawner processes should be
681
- // killed first.
682
- SessionPtr session;
683
- TempDirCopy c1("stub/rack", "rackapp1.tmp");
684
- TempDirCopy c2("stub/rack", "rackapp2.tmp");
685
- shared_ptr<ReloadLoggingSpawnManager> spawnManager(
686
- new ReloadLoggingSpawnManager("../helper-scripts/passenger-spawn-server", generation)
687
- );
688
- reinitializeWithSpawnManager(spawnManager);
689
-
690
- pool->setMax(1);
691
- session = spawnRackApp(pool, "rackapp1.tmp");
692
- session.reset();
693
- session = spawnRackApp(pool, "rackapp2.tmp");
694
- ensure_equals("rackapp2.tmp is not reloaded because restart.txt is not touched",
695
- spawnManager->reloadLog.size(), 0u);
696
- session.reset();
697
- EVENTUALLY(5,
698
- result = pool->getActive() == 0u;
699
- );
700
-
701
- touchFile("rackapp1.tmp/tmp/restart.txt");
702
- session = spawnRackApp(pool, "rackapp1.tmp");
703
- ensure_equals("rackapp1.tmp is reloaded because restart.txt is touched (1)",
704
- spawnManager->reloadLog.size(), 1u);
705
- ensure_equals("rackapp1.tmp is reloaded because restart.txt is touched (2)",
706
- spawnManager->reloadLog[0], "rackapp1.tmp");
707
- }
708
-
709
- TEST_METHOD(27) {
710
- // Test inspect()
711
- SessionPtr session1 = spawnRackApp(pool, "stub/rack");
712
- string str = pool->inspect();
713
- ensure("Contains 'max = '", str.find("max ") != string::npos);
714
- ensure("Contains PID", str.find("PID: " + toString(session1->getPid())) != string::npos);
715
- }
716
-
717
- TEST_METHOD(28) {
718
- // Test toXml(true)
719
- SessionPtr session1 = spawnRackApp(pool, "stub/rack");
720
- string xml = pool->toXml();
721
- ensure("Contains <process>", xml.find("<process>") != string::npos);
722
- ensure("Contains PID", xml.find("<pid>" + toString(session1->getPid()) + "</pid>") != string::npos);
723
- ensure("Contains sensitive information", xml.find("<server_sockets>") != string::npos);
724
- }
725
-
726
- TEST_METHOD(29) {
727
- // Test toXml(false)
728
- SessionPtr session1 = spawnRackApp(pool, "stub/rack");
729
- string xml = pool->toXml(false);
730
- ensure("Contains <process>", xml.find("<process>") != string::npos);
731
- ensure("Contains PID", xml.find("<pid>" + toString(session1->getPid()) + "</pid>") != string::npos);
732
- ensure("Does not contain sensitive information", xml.find("<server_sockets>") == string::npos);
733
- }
734
-
735
- TEST_METHOD(30) {
736
- // Test detach().
737
-
738
- // Create 2 processes, where only the first one is active.
739
- SessionPtr session1 = spawnRackApp(pool, "stub/rack");
740
- SessionPtr session2 = spawnRackApp(pool2, "stub/rack");
741
- session2.reset();
742
- EVENTUALLY(5,
743
- result = pool->getActive() == 1u && pool->getCount() == 2u;
744
- );
745
-
746
- // Make sure session2 refers to a different process than session1.
747
- session2 = spawnRackApp(pool2, "stub/rack");
748
- string session2dk = session2->getDetachKey();
749
- session2.reset();
750
- EVENTUALLY(5,
751
- result = pool->getActive() == 1u;
752
- );
753
-
754
- // First detach works. It was active so the 'active' property
755
- // is decremented.
756
- ensure("(10)", pool->detach(session1->getDetachKey()));
757
- ensure_equals("(11)", pool->getActive(), 0u);
758
- ensure_equals("(12)", pool->getCount(), 1u);
759
-
760
- // Second detach with the same identifier doesn't do anything.
761
- ensure("(20)", !pool->detach(session1->getDetachKey()));
762
- ensure_equals("(21)", pool->getActive(), 0u);
763
- ensure_equals("(22)", pool->getCount(), 1u);
764
-
765
- // Detaching an inactive process works too.
766
- ensure("(30)", pool->detach(session2dk));
767
- ensure_equals("(31)", pool->getActive(), 0u);
768
- ensure_equals("(32)", pool->getCount(), 0u);
769
- }
770
-
771
- TEST_METHOD(31) {
772
- // If the app group does not yet exist, and options.minProcesses > 0,
773
- // then get() will spawn 1 process immediately, return its session,
774
- // and spawn more processes in the background until options.minProcesses
775
- // is satisfied.
776
- TempDirCopy c1("stub/rack", "rackapp.tmp");
777
- PoolOptions options;
778
- options.appRoot = "rackapp.tmp";
779
- options.appType = "rack";
780
- options.minProcesses = 3;
781
- options.spawnMethod = "conservative";
782
-
783
- writeFile("rackapp.tmp/config.ru",
784
- "sleep 0.1\n"
785
- "run lambda {}\n");
786
-
787
- SessionPtr session1 = pool->get(options);
788
- ensure_equals(pool->getActive(), 1u);
789
- ensure_equals(pool->getCount(), 1u);
790
-
791
- EVENTUALLY(5,
792
- result = pool->getCount() == 3u;
793
- );
794
- }
795
-
796
- TEST_METHOD(32) {
797
- // If the app group already exists, all processes are active,
798
- // count < max, options.minProcesses > 0 and global queuing turned off,
799
- // then get() will check out an existing process immediately
800
- // and spawn new ones in the background until options.minProcesses
801
- // is satisfied.
802
- TempDirCopy c1("stub/rack", "rackapp.tmp");
803
- PoolOptions options;
804
- options.appRoot = "rackapp.tmp";
805
- options.appType = "rack";
806
- options.spawnMethod = "conservative";
807
- options.minProcesses = 3;
808
- pool->setMax(3);
809
-
810
- // Spawn a single process.
811
- SessionPtr session1 = pool->get(options);
812
- ensure_equals(pool->getActive(), 1u);
813
- ensure_equals(pool->getCount(), 1u);
814
-
815
- writeFile("rackapp.tmp/config.ru",
816
- "sleep 0.1\n"
817
- "run lambda {}\n");
818
-
819
- // Now call get(); this one will use the previous process
820
- // and spawn a new one in the background.
821
- SessionPtr session2 = pool2->get(options);
822
- ensure_equals(pool->getActive(), 1u);
823
- ensure_equals(pool->getCount(), 1u);
824
- ensure_equals(session1->getPid(), session2->getPid());
825
-
826
- EVENTUALLY(5,
827
- result = pool->getCount() == 3u;
828
- );
829
- }
830
-
831
- /* If the app group already exists, all processes are active,
832
- * count < max, options.minProcesses > 0 and global queuing turned on,
833
- * then get() will wait until either
834
- * (1) an existing process becomes inactive.
835
- * or until
836
- * (2) a new process has been spawned.
837
- */
838
-
839
- TEST_METHOD(33) {
840
- // Here we test scenario (1).
841
- PoolOptions options;
842
- options.appRoot = "stub/rack";
843
- options.appType = "rack";
844
- options.minProcesses = 3;
845
- options.useGlobalQueue = true;
846
- pool->setMax(3);
847
-
848
- ApplicationPool::Ptr pool3 = newPoolConnection();
849
- ApplicationPool::Ptr pool4 = newPoolConnection();
850
-
851
- // Spawn 3 processes.
852
- SessionPtr session1 = pool->get(options);
853
- SessionPtr session2 = pool2->get(options);
854
- session2.reset();
855
- EVENTUALLY(5,
856
- result = pool->getCount() == 3u;
857
- );
858
-
859
- // Make sure all of them are active.
860
- session2 = pool2->get(options);
861
- SessionPtr session3 = pool3->get(options);
862
- ensure_equals(pool->getActive(), 3u);
863
- ensure_equals(pool->getCount(), 3u);
864
-
865
- // Now call get() in a thread.
866
- SpawnRackAppFunction func;
867
- bool done = false;
868
- func.pool = pool4;
869
- func.done = &done;
870
- TempThread thr(func);
871
-
872
- usleep(20000);
873
- ensure("Still waiting on global queue", !done);
874
- ensure_equals(pool->getGlobalQueueSize(), 1u);
875
-
876
- // Make 1 process available.
877
- session1.reset();
878
- EVENTUALLY(5,
879
- result = done;
880
- );
881
- }
882
-
883
- TEST_METHOD(34) {
884
- // Here we test scenario (2).
885
- PoolOptions options;
886
- options.appRoot = "stub/rack";
887
- options.appType = "rack";
888
- options.minProcesses = 3;
889
- options.useGlobalQueue = true;
890
- pool->setMax(3);
891
-
892
- ApplicationPool::Ptr pool3 = newPoolConnection();
893
- ApplicationPool::Ptr pool4 = newPoolConnection();
894
- ApplicationPool::Ptr pool5 = newPoolConnection();
895
-
896
- // Spawn 3 processes.
897
- SessionPtr session1 = pool->get(options);
898
- SessionPtr session2 = pool2->get(options);
899
- session2.reset();
900
- EVENTUALLY(5,
901
- result = pool->getCount() == 3u;
902
- );
903
-
904
- // Make sure all of them are active.
905
- session2 = pool2->get(options);
906
- SessionPtr session3 = pool3->get(options);
907
- ensure_equals(pool->getActive(), 3u);
908
- ensure_equals(pool->getCount(), 3u);
909
-
910
- // Now call get() in a thread.
911
- SpawnRackAppFunction func1;
912
- SessionPtr session4;
913
- bool done1 = false;
914
- func1.pool = pool4;
915
- func1.done = &done1;
916
- func1.session = &session4;
917
- TempThread thr1(func1);
918
-
919
- // And again.
920
- SpawnRackAppFunction func2;
921
- SessionPtr session5;
922
- bool done2 = false;
923
- func2.pool = pool5;
924
- func2.done = &done2;
925
- func2.session = &session5;
926
- TempThread thr2(func2);
927
-
928
- // We should now arrive at a state where there are 3 processes, all
929
- // busy, and 2 threads waiting on the global queue.
930
- usleep(20000);
931
- ensure("Still waiting on global queue", !done1 && !done2);
932
- ensure_equals(pool->getGlobalQueueSize(), 2u);
933
-
934
- // Increasing the max will cause one of the threads to wake
935
- // up, start a spawn action in the background, and go to sleep
936
- // again. Eventually the new process will be done spawning,
937
- // causing one of the threads to wake up. The other one will
938
- // continue to wait.
939
- pool->setMax(4);
940
- EVENTUALLY(5,
941
- result = (done1 && !done2) || (!done1 && done2);
942
- );
943
- }
944
-
945
- TEST_METHOD(35) {
946
- // When spawning an app in the background, if it encountered an error
947
- // it will remove the whole app group.
948
- TempDirCopy c1("stub/rack", "rackapp.tmp");
949
- PoolOptions options;
950
- options.appRoot = "rackapp.tmp";
951
- options.appType = "rack";
952
- options.spawnMethod = "conservative";
953
- options.printExceptions = false;
954
-
955
- SessionPtr session1 = pool->get(options);
956
-
957
- writeFile("rackapp.tmp/config.ru",
958
- "raise 'foo'\n");
959
- pool2->get(options);
960
-
961
- EVENTUALLY(5,
962
- result = pool->getCount() == 0u;
963
- );
964
- }
965
-
966
- TEST_METHOD(36) {
967
- // When cleaning, at least options.minProcesses processes should be kept around.
968
- pool->setMaxIdleTime(0);
969
- ApplicationPool::Ptr pool3 = newPoolConnection();
970
- PoolOptions options;
971
- options.appRoot = "stub/rack";
972
- options.appType = "rack";
973
- options.minProcesses = 2;
974
-
975
- // Spawn 2 processes.
976
- SessionPtr session1 = pool->get(options);
977
- SessionPtr session2 = pool2->get(options);
978
- session1.reset();
979
- session2.reset();
980
- EVENTUALLY(5,
981
- result = pool->getActive() == 0u && pool->getCount() == 2u;
982
- );
983
-
984
- // Spawn another process, so we get 3.
985
- session1 = pool->get(options);
986
- session2 = pool2->get(options);
987
- SessionPtr session3 = pool3->get(options);
988
- session3.reset();
989
- EVENTUALLY(5,
990
- result = pool->getActive() == 2u && pool->getCount() == 3u;
991
- );
992
-
993
- // Now wait until one process is idle cleaned.
994
- pool->setMaxIdleTime(1);
995
- EVENTUALLY(10,
996
- result = pool->getCount() == 2u;
997
- );
998
- }
999
-
1000
- TEST_METHOD(37) {
1001
- // Test whether processes are grouped together by appGroupName.
1002
- TempDirCopy c1("stub/rack", "rackapp.tmp");
1003
- PoolOptions options1;
1004
- options1.appRoot = "rackapp.tmp";
1005
- options1.appType = "rack";
1006
- options1.appGroupName = "group A";
1007
- SessionPtr session1 = pool->get(options1);
1008
-
1009
- TempDirCopy c2("stub/rack", "rackapp2.tmp");
1010
- PoolOptions options2;
1011
- options2.appRoot = "rackapp2.tmp";
1012
- options2.appType = "rack";
1013
- options2.appGroupName = "group A";
1014
- SessionPtr session2 = pool2->get(options2);
1015
-
1016
- session1.reset();
1017
- session2.reset();
1018
- EVENTUALLY(5,
1019
- result = pool->getCount() == 2u;
1020
- );
1021
-
1022
- touchFile("rackapp.tmp/tmp/restart.txt");
1023
- session1 = pool->get(options1);
1024
- ensure_equals(pool->getCount(), 1u);
1025
- }
1026
-
1027
- /*************************************/
1028
-
1029
- #endif /* USE_TEMPLATE */