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
@@ -0,0 +1,103 @@
1
+ // Boost result_of library
2
+
3
+ // Copyright Douglas Gregor 2004. Use, modification and
4
+ // distribution is subject to the Boost Software License, Version
5
+ // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
+ // http://www.boost.org/LICENSE_1_0.txt)
7
+
8
+ // For more information, see http://www.boost.org/libs/utility
9
+ #ifndef BOOST_RESULT_OF_HPP
10
+ #define BOOST_RESULT_OF_HPP
11
+
12
+ #include <boost/config.hpp>
13
+ #include <boost/preprocessor/iteration/iterate.hpp>
14
+ #include <boost/preprocessor/punctuation/comma_if.hpp>
15
+ #include <boost/preprocessor/repetition/enum_params.hpp>
16
+ #include <boost/preprocessor/repetition/enum_binary_params.hpp>
17
+ #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
18
+ #include <boost/preprocessor/facilities/intercept.hpp>
19
+ #include <boost/detail/workaround.hpp>
20
+ #include <boost/mpl/has_xxx.hpp>
21
+ #include <boost/mpl/if.hpp>
22
+ #include <boost/mpl/bool.hpp>
23
+ #include <boost/mpl/or.hpp>
24
+ #include <boost/type_traits/is_pointer.hpp>
25
+ #include <boost/type_traits/is_member_function_pointer.hpp>
26
+ #include <boost/type_traits/remove_cv.hpp>
27
+ #include <boost/utility/declval.hpp>
28
+
29
+ #ifndef BOOST_RESULT_OF_NUM_ARGS
30
+ # define BOOST_RESULT_OF_NUM_ARGS 10
31
+ #endif
32
+
33
+ namespace boost {
34
+
35
+ template<typename F> struct result_of;
36
+ template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of
37
+
38
+ #if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
39
+ namespace detail {
40
+
41
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
42
+
43
+ template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
44
+ template<typename F> struct cpp0x_result_of_impl;
45
+
46
+ template<typename F>
47
+ struct result_of_void_impl
48
+ {
49
+ typedef void type;
50
+ };
51
+
52
+ template<typename R>
53
+ struct result_of_void_impl<R (*)(void)>
54
+ {
55
+ typedef R type;
56
+ };
57
+
58
+ template<typename R>
59
+ struct result_of_void_impl<R (&)(void)>
60
+ {
61
+ typedef R type;
62
+ };
63
+
64
+ // Determine the return type of a function pointer or pointer to member.
65
+ template<typename F, typename FArgs>
66
+ struct result_of_pointer
67
+ : tr1_result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
68
+
69
+ template<typename F, typename FArgs>
70
+ struct tr1_result_of_impl<F, FArgs, true>
71
+ {
72
+ typedef typename F::result_type type;
73
+ };
74
+
75
+ template<typename FArgs>
76
+ struct is_function_with_no_args : mpl::false_ {};
77
+
78
+ template<typename F>
79
+ struct is_function_with_no_args<F(void)> : mpl::true_ {};
80
+
81
+ template<typename F, typename FArgs>
82
+ struct result_of_nested_result : F::template result<FArgs>
83
+ {};
84
+
85
+ template<typename F, typename FArgs>
86
+ struct tr1_result_of_impl<F, FArgs, false>
87
+ : mpl::if_<is_function_with_no_args<FArgs>,
88
+ result_of_void_impl<F>,
89
+ result_of_nested_result<F, FArgs> >::type
90
+ {};
91
+
92
+ } // end namespace detail
93
+
94
+ #define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))
95
+ #include BOOST_PP_ITERATE()
96
+
97
+ #else
98
+ # define BOOST_NO_RESULT_OF 1
99
+ #endif
100
+
101
+ }
102
+
103
+ #endif // BOOST_RESULT_OF_HPP
@@ -0,0 +1,55 @@
1
+ // Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker
2
+ //
3
+ // Distributed under the Boost Software License, Version 1.0. (See
4
+ // accompanying file LICENSE_1_0.txt or copy at
5
+ // http://www.boost.org/LICENSE_1_0.txt)
6
+ // For more information, see http://www.boost.org
7
+
8
+
9
+ #ifndef BOOST_UTILITY_SWAP_HPP
10
+ #define BOOST_UTILITY_SWAP_HPP
11
+
12
+ // Note: the implementation of this utility contains various workarounds:
13
+ // - swap_impl is put outside the boost namespace, to avoid infinite
14
+ // recursion (causing stack overflow) when swapping objects of a primitive
15
+ // type.
16
+ // - swap_impl has a using-directive, rather than a using-declaration,
17
+ // because some compilers (including MSVC 7.1, Borland 5.9.3, and
18
+ // Intel 8.1) don't do argument-dependent lookup when it has a
19
+ // using-declaration instead.
20
+ // - boost::swap has two template arguments, instead of one, to
21
+ // avoid ambiguity when swapping objects of a Boost type that does
22
+ // not have its own boost::swap overload.
23
+
24
+ #include <algorithm> //for std::swap
25
+ #include <cstddef> //for std::size_t
26
+
27
+ namespace boost_swap_impl
28
+ {
29
+ template<class T>
30
+ void swap_impl(T& left, T& right)
31
+ {
32
+ using namespace std;//use std::swap if argument dependent lookup fails
33
+ swap(left,right);
34
+ }
35
+
36
+ template<class T, std::size_t N>
37
+ void swap_impl(T (& left)[N], T (& right)[N])
38
+ {
39
+ for (std::size_t i = 0; i < N; ++i)
40
+ {
41
+ ::boost_swap_impl::swap_impl(left[i], right[i]);
42
+ }
43
+ }
44
+ }
45
+
46
+ namespace boost
47
+ {
48
+ template<class T1, class T2>
49
+ void swap(T1& left, T2& right)
50
+ {
51
+ ::boost_swap_impl::swap_impl(left, right);
52
+ }
53
+ }
54
+
55
+ #endif
@@ -0,0 +1,36 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2012 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _PASSENGER_ANSI_COLOR_CONSTANTS_H_
26
+
27
+ #define ANSI_COLOR_RESET "\e[0m"
28
+ #define ANSI_COLOR_BOLD "\e[1m"
29
+ #define ANSI_COLOR_RED "\e[31m"
30
+ #define ANSI_COLOR_GREEN "\e[32m"
31
+ #define ANSI_COLOR_YELLOW "\e[33m"
32
+ #define ANSI_COLOR_WHITE "\e[37m"
33
+ #define ANSI_COLOR_BLACK_BG "\e[40m"
34
+ #define ANSI_COLOR_BLUE_BG "\e[44m"
35
+
36
+ #endif /* _PASSENGER_ANSI_COLOR_CONSTANTS_H_ */
@@ -0,0 +1,87 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2011, 2012 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _PASSENGER_APPLICATION_POOL2_COMMON_H_
26
+ #define _PASSENGER_APPLICATION_POOL2_COMMON_H_
27
+
28
+ #include <boost/thread.hpp>
29
+ #include <boost/shared_ptr.hpp>
30
+ #include <boost/function.hpp>
31
+ #include <oxt/tracable_exception.hpp>
32
+ #include <ApplicationPool2/Options.h>
33
+ #include <Utils/StringMap.h>
34
+
35
+ namespace tut {
36
+ struct ApplicationPool2_PoolTest;
37
+ }
38
+
39
+ namespace Passenger {
40
+ namespace ApplicationPool2 {
41
+
42
+ using namespace std;
43
+ using namespace boost;
44
+ using namespace oxt;
45
+
46
+ class Pool;
47
+ class SuperGroup;
48
+ class Group;
49
+ class Process;
50
+ class Session;
51
+
52
+ typedef shared_ptr<Pool> PoolPtr;
53
+ typedef shared_ptr<SuperGroup> SuperGroupPtr;
54
+ typedef shared_ptr<Group> GroupPtr;
55
+ typedef shared_ptr<Process> ProcessPtr;
56
+ typedef shared_ptr<Session> SessionPtr;
57
+ typedef shared_ptr<tracable_exception> ExceptionPtr;
58
+ typedef StringMap<SuperGroupPtr> SuperGroupMap;
59
+ typedef function<void (const SessionPtr &session, const ExceptionPtr &e)> GetCallback;
60
+ typedef function<void ()> Callback;
61
+
62
+ struct GetWaiter {
63
+ Options options;
64
+ GetCallback callback;
65
+
66
+ GetWaiter(const Options &o, const GetCallback &cb)
67
+ : options(o),
68
+ callback(cb)
69
+ {
70
+ options.persist(o);
71
+ }
72
+ };
73
+
74
+ struct Ticket {
75
+ boost::mutex syncher;
76
+ condition_variable cond;
77
+ SessionPtr session;
78
+ ExceptionPtr exception;
79
+ };
80
+
81
+ ExceptionPtr copyException(const tracable_exception &e);
82
+ void rethrowException(const ExceptionPtr &e);
83
+
84
+ } // namespace ApplicationPool2
85
+ } // namespace Passenger
86
+
87
+ #endif /* _PASSENGER_APPLICATION_POOL2_COMMON_H_ */
@@ -0,0 +1,53 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2011, 2012 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _PASSENGER_APPLICATION_POOL2_COMPONENT_INFO_H_
26
+ #define _PASSENGER_APPLICATION_POOL2_COMPONENT_INFO_H_
27
+
28
+ #include <string>
29
+
30
+ namespace Passenger {
31
+ namespace ApplicationPool2 {
32
+
33
+ using namespace std;
34
+
35
+
36
+ struct ComponentInfo {
37
+ string name;
38
+ bool isDefault;
39
+
40
+ /****************/
41
+ /****************/
42
+
43
+ ComponentInfo() {
44
+ isDefault = false;
45
+ /******************/
46
+ }
47
+ };
48
+
49
+
50
+ } // namespace ApplicationPool2
51
+ } // namespace Passenger
52
+
53
+ #endif /* _PASSENGER_APPLICATION_POOL2_COMPONENT_INFO_H_ */
@@ -0,0 +1,648 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2011, 2012 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _PASSENGER_APPLICATION_POOL2_GROUP_H_
26
+ #define _PASSENGER_APPLICATION_POOL2_GROUP_H_
27
+
28
+ #include <string>
29
+ #include <map>
30
+ #include <queue>
31
+ #include <deque>
32
+ #include <boost/thread.hpp>
33
+ #include <boost/bind.hpp>
34
+ #include <boost/shared_ptr.hpp>
35
+ #include <boost/make_shared.hpp>
36
+ #include <oxt/macros.hpp>
37
+ #include <oxt/thread.hpp>
38
+ #include <cassert>
39
+ #include <ApplicationPool2/Common.h>
40
+ #include <ApplicationPool2/ComponentInfo.h>
41
+ #include <ApplicationPool2/Spawner.h>
42
+ #include <ApplicationPool2/Process.h>
43
+ #include <ApplicationPool2/Options.h>
44
+ #include <Utils/CachedFileStat.hpp>
45
+ #include <Utils/FileChangeChecker.h>
46
+ #include <Utils/SmallVector.h>
47
+
48
+ namespace Passenger {
49
+ namespace ApplicationPool2 {
50
+
51
+ using namespace std;
52
+ using namespace boost;
53
+ using namespace oxt;
54
+
55
+
56
+ /**
57
+ * Except for otherwise documented parts, this class is not thread-safe,
58
+ * so only access within ApplicationPool lock.
59
+ */
60
+ class Group: public enable_shared_from_this<Group> {
61
+ private:
62
+ friend class Pool;
63
+ friend class SuperGroup;
64
+
65
+ struct GetAction {
66
+ GetCallback callback;
67
+ SessionPtr session;
68
+ };
69
+
70
+ struct DisableWaiter {
71
+ ProcessPtr process;
72
+ Callback callback;
73
+
74
+ DisableWaiter(const ProcessPtr &_process, const Callback &_callback)
75
+ : process(_process),
76
+ callback(_callback)
77
+ { }
78
+ };
79
+
80
+ mutable boost::mutex backrefSyncher;
81
+ weak_ptr<SuperGroup> superGroup;
82
+ CachedFileStat cstat;
83
+ FileChangeChecker fileChangeChecker;
84
+ string restartFile;
85
+ string alwaysRestartFile;
86
+
87
+
88
+ static void _onSessionInitiateFailure(Session *session) {
89
+ const ProcessPtr &process = session->getProcess();
90
+ GroupPtr group = process->getGroup();
91
+ if (OXT_LIKELY(group != NULL)) {
92
+ group->onSessionInitiateFailure(process, session);
93
+ }
94
+ }
95
+
96
+ static void _onSessionClose(Session *session) {
97
+ const ProcessPtr &process = session->getProcess();
98
+ GroupPtr group = process->getGroup();
99
+ if (OXT_LIKELY(group != NULL)) {
100
+ group->onSessionClose(process, session);
101
+ }
102
+ }
103
+
104
+ void createInterruptableThread(const function<void ()> &func, const string &name,
105
+ unsigned int stackSize);
106
+ static string generateSecret(const SuperGroupPtr &superGroup);
107
+ void onSessionInitiateFailure(const ProcessPtr &process, Session *session);
108
+ void onSessionClose(const ProcessPtr &process, Session *session);
109
+ void spawnThreadMain(GroupPtr self, SpawnerPtr spawner, Options options);
110
+ void spawnThreadRealMain(const SpawnerPtr &spawner, const Options &options);
111
+ void finalizeRestart(GroupPtr self, Options options, SpawnerFactoryPtr spawnerFactory,
112
+ vector<Callback> postLockActions);
113
+
114
+ void verifyInvariants() const {
115
+ // !a || b: logical equivalent of a IMPLIES b.
116
+
117
+ assert(count >= 0);
118
+ assert(0 <= disablingCount && disablingCount <= count);
119
+ assert(processes.empty() == (count == 0));
120
+ assert(processes.empty() == (pqueue.top() == NULL));
121
+ assert(disabledCount >= 0);
122
+ assert(disabledProcesses.empty() == (disabledCount == 0));
123
+ assert(!( count > 0 && disablingCount == count ) || ( spawning() ));
124
+
125
+ // Verify getWaitlist invariants.
126
+ assert(!( !getWaitlist.empty() ) || ( processes.empty() || pqueue.top()->atFullCapacity() ));
127
+ assert(!( !processes.empty() && !pqueue.top()->atFullCapacity() ) || ( getWaitlist.empty() ));
128
+ assert(!( processes.empty() && !spawning() && !restarting() ) || ( getWaitlist.empty() ));
129
+ assert(!( !getWaitlist.empty() ) || ( !processes.empty() || spawning() || restarting() ));
130
+
131
+ // Verify disableWaitlist invariants.
132
+ assert((int) disableWaitlist.size() >= disablingCount);
133
+
134
+ // Verify m_spawning and m_restarting.
135
+ assert(!( m_restarting ) || !m_spawning);
136
+ }
137
+
138
+ void resetOptions(const Options &newOptions) {
139
+ options = newOptions;
140
+ options.persist(newOptions);
141
+ options.clearPerRequestFields();
142
+ options.groupSecret = secret;
143
+ }
144
+
145
+ void mergeOptions(const Options &other) {
146
+ options.maxRequests = other.maxRequests;
147
+ options.minProcesses = other.minProcesses;
148
+ options.statThrottleRate = other.statThrottleRate;
149
+ options.maxPreloaderIdleTime = other.maxPreloaderIdleTime;
150
+ }
151
+
152
+ void runAllActions(const vector<Callback> &actions) {
153
+ vector<Callback>::const_iterator it, end = actions.end();
154
+ for (it = actions.begin(); it != end; it++) {
155
+ (*it)();
156
+ }
157
+ }
158
+
159
+ static void cleanupSpawner(SpawnerPtr spawner) {
160
+ try {
161
+ spawner->cleanup();
162
+ } catch (const thread_interrupted &) {
163
+ // Return.
164
+ }
165
+ }
166
+
167
+ SessionPtr newSession() {
168
+ assert(count > 0);
169
+ Process *process = pqueue.top();
170
+ SessionPtr session = process->newSession();
171
+ session->onInitiateFailure = _onSessionInitiateFailure;
172
+ session->onClose = _onSessionClose;
173
+ pqueue.pop();
174
+ process->pqHandle = pqueue.push(process, process->utilization());
175
+ return session;
176
+ }
177
+
178
+ template<typename Lock>
179
+ void assignSessionsToGetWaitersQuickly(Lock &lock) {
180
+ SmallVector<GetAction, 50> actions;
181
+ actions.reserve(getWaitlist.size());
182
+ while (!getWaitlist.empty() && pqueue.top() != NULL && !pqueue.top()->atFullCapacity()) {
183
+ GetAction action;
184
+ action.callback = getWaitlist.front().callback;
185
+ action.session = newSession();
186
+ getWaitlist.pop();
187
+ actions.push_back(action);
188
+ }
189
+
190
+ verifyInvariants();
191
+ lock.unlock();
192
+ SmallVector<GetAction, 50>::const_iterator it, end = actions.end();
193
+ for (it = actions.begin(); it != end; it++) {
194
+ it->callback(it->session, ExceptionPtr());
195
+ }
196
+ }
197
+
198
+ void assignSessionsToGetWaiters(vector<Callback> &postLockActions) {
199
+ while (!getWaitlist.empty() && pqueue.top() != NULL && !pqueue.top()->atFullCapacity()) {
200
+ postLockActions.push_back(boost::bind(
201
+ getWaitlist.front().callback, newSession(),
202
+ ExceptionPtr()));
203
+ getWaitlist.pop();
204
+ }
205
+ }
206
+
207
+ void assignExceptionToGetWaiters(const ExceptionPtr &exception,
208
+ vector<Callback> &postLockActions)
209
+ {
210
+ while (!getWaitlist.empty()) {
211
+ postLockActions.push_back(boost::bind(
212
+ getWaitlist.front().callback, SessionPtr(),
213
+ exception));
214
+ getWaitlist.pop();
215
+ }
216
+ }
217
+
218
+ void removeFromDisableWaitlist(const ProcessPtr &p, vector<Callback> &postLockActions) {
219
+ deque<DisableWaiter>::const_iterator it, end = disableWaitlist.end();
220
+ deque<DisableWaiter> newList;
221
+ for (it = disableWaitlist.begin(); it != end; it++) {
222
+ const DisableWaiter &waiter = *it;
223
+ const ProcessPtr process = waiter.process;
224
+ if (process == p) {
225
+ postLockActions.push_back(waiter.callback);
226
+ } else {
227
+ newList.push_back(waiter);
228
+ }
229
+ }
230
+ disableWaitlist = newList;
231
+ }
232
+
233
+ public:
234
+ Options options;
235
+ /** This name uniquely identifies this Group within its Pool. It can also be used as the display name. */
236
+ const string name;
237
+ /** A secret token that may be known among all processes in this Group. Used for securing
238
+ * intra-group process communication.
239
+ */
240
+ const string secret;
241
+ ComponentInfo componentInfo;
242
+
243
+ /**
244
+ * 'processes' contains all enabled processes in this group.
245
+ * 'disabledProcesses' contains all disabled processes in this group.
246
+ * They do not intersect.
247
+ *
248
+ * 'pqueue' orders all enabled processes according to utilization() values, from small to large.
249
+ * 'count' indicates the total number of enabled processes in this group.
250
+ * 'disablingCount' indicates the number of processes in 'processes' with enabled == DISABLING.
251
+ * 'disabledCount' indicates the number of disabled processes.
252
+ *
253
+ * Invariants:
254
+ * count >= 0
255
+ * 0 <= disablingCount <= count
256
+ * processes.size() == count
257
+ * processes.empty() == (pqueue.top() == NULL)
258
+ * disabledProcesses.size() == disabledCount
259
+ * if pqueue.top().atFullCapacity():
260
+ * All enabled processes are at full capacity.
261
+ * if (count > 0) and (disablingCount == count):
262
+ * spawning()
263
+ * for all process in processes:
264
+ * process.enabled == Process::ENABLED || process.enabled == Process::DISABLING
265
+ * for all process in disabledProcesses:
266
+ * process.enabled == Process::DISABLED
267
+ */
268
+ int count;
269
+ int disablingCount;
270
+ int disabledCount;
271
+ PriorityQueue<Process> pqueue;
272
+ ProcessList processes;
273
+ ProcessList disabledProcesses;
274
+
275
+ /**
276
+ * get() requests for this group that cannot be immediately satisfied are
277
+ * put on this wait list, which must be processed as soon as the necessary
278
+ * resources have become free.
279
+ *
280
+ * Invariant 1:
281
+ * if getWaitlist is non-empty:
282
+ * processes.empty() or (all enabled processes are at full capacity)
283
+ * Equivalently:
284
+ * if !processes.empty() and (an enabled process is not at full capacity):
285
+ * getWaitlist is empty.
286
+ *
287
+ * Invariant 2:
288
+ * if processes.empty() && !spawning() && !restarting():
289
+ * getWaitlist is empty
290
+ * Equivalently:
291
+ * if getWaitlist is non-empty:
292
+ * !processes.empty() || spawning() || restarting()
293
+ */
294
+ queue<GetWaiter> getWaitlist;
295
+ /**
296
+ * Invariant:
297
+ * disableWaitlist.size() >= disablingCount
298
+ */
299
+ deque<DisableWaiter> disableWaitlist;
300
+
301
+ SpawnerPtr spawner;
302
+ /**
303
+ * Whether process(es) are being spawned right now.
304
+ */
305
+ bool m_spawning;
306
+ /** Whether a restart is in progress. While restarting is in progress,
307
+ * it is not possible to signal the desire to spawn new process. If spawning
308
+ * was already in progress when the restart was initiated, then the spawning
309
+ * will abort as soon as possible.
310
+ *
311
+ * Invariant:
312
+ * if m_restarting: !m_spawning
313
+ */
314
+ bool m_restarting;
315
+
316
+ Group(const SuperGroupPtr &superGroup, const Options &options, const ComponentInfo &info);
317
+
318
+ SessionPtr get(const Options &newOptions, const GetCallback &callback) {
319
+ if (OXT_LIKELY(!restarting())) {
320
+ if (OXT_UNLIKELY(needsRestart(newOptions))) {
321
+ restart(newOptions);
322
+ } else {
323
+ mergeOptions(newOptions);
324
+ }
325
+ if (OXT_UNLIKELY(!newOptions.noop && shouldSpawn())) {
326
+ spawn();
327
+ }
328
+ }
329
+
330
+ if (OXT_UNLIKELY(newOptions.noop)) {
331
+ ProcessPtr process = make_shared<Process>(SafeLibevPtr(),
332
+ 0, string(), string(),
333
+ FileDescriptor(), FileDescriptor(),
334
+ SocketListPtr(), 0, 0);
335
+ process->setGroup(shared_from_this());
336
+ return make_shared<Session>(process, (Socket *) NULL);
337
+ }
338
+
339
+ if (OXT_UNLIKELY(count == 0)) {
340
+ /* We don't have any processes yet, but it's on the way.
341
+ * Call the callback after a process has been spawned
342
+ * or has failed to spawn.
343
+ */
344
+ assert(spawning() || restarting());
345
+ getWaitlist.push(GetWaiter(newOptions, callback));
346
+ P_DEBUG("No session checked out yet: group is spawning or restarting");
347
+ return SessionPtr();
348
+ } else {
349
+ Process *process = pqueue.top();
350
+ assert(process != NULL);
351
+ if (process->atFullCapacity()) {
352
+ /* Looks like all processes are at full capacity.
353
+ * Wait until a new one has been spawned or until
354
+ * resources have become free.
355
+ */
356
+ getWaitlist.push(GetWaiter(newOptions, callback));
357
+ P_DEBUG("No session checked out yet: all processes are at full capacity");
358
+ return SessionPtr();
359
+ } else {
360
+ P_DEBUG("Session checked out from process " << process->inspect());
361
+ return newSession();
362
+ }
363
+ }
364
+ }
365
+
366
+ // Thread-safe.
367
+ SuperGroupPtr getSuperGroup() const {
368
+ lock_guard<boost::mutex> lock(backrefSyncher);
369
+ return superGroup.lock();
370
+ }
371
+
372
+ // Thread-safe.
373
+ void setSuperGroup(const SuperGroupPtr &superGroup) {
374
+ lock_guard<boost::mutex> lock(backrefSyncher);
375
+ this->superGroup = superGroup;
376
+ }
377
+
378
+ // Thread-safe.
379
+ PoolPtr getPool() const;
380
+
381
+ // Thread-safe.
382
+ bool detached() const {
383
+ return getSuperGroup() == NULL;
384
+ }
385
+
386
+ /**
387
+ * Attaches the given process to this Group and mark it as enabled. This
388
+ * function doesn't touch getWaitlist so be sure to fix its invariants
389
+ * afterwards if necessary.
390
+ */
391
+ void attach(const ProcessPtr &process, vector<Callback> &postLockActions) {
392
+ assert(process->getGroup() == NULL);
393
+ process->setGroup(shared_from_this());
394
+ processes.push_back(process);
395
+ process->it = processes.last_iterator();
396
+ process->pqHandle = pqueue.push(process.get(), process->utilization());
397
+ process->enabled = Process::ENABLED;
398
+ count++;
399
+
400
+ // Disable all processes in 'disableWaitlist' and call their callbacks
401
+ // outside the lock.
402
+ deque<DisableWaiter>::const_iterator it, end = disableWaitlist.end();
403
+ postLockActions.reserve(postLockActions.size() + disableWaitlist.size());
404
+ for (it = disableWaitlist.begin(); it != end; it++) {
405
+ const DisableWaiter &waiter = *it;
406
+ const ProcessPtr process = waiter.process;
407
+ // The same process can appear multiple times in disableWaitlist.
408
+ assert(process->enabled == Process::DISABLING
409
+ || process->enabled == Process::DISABLED);
410
+ if (process->enabled == Process::DISABLING) {
411
+ process->enabled = Process::DISABLED;
412
+ processes.erase(process->it);
413
+ pqueue.erase(process->pqHandle);
414
+ disabledProcesses.push_back(process);
415
+ process->it = disabledProcesses.last_iterator();
416
+ count--;
417
+ disablingCount--;
418
+ disabledCount++;
419
+ }
420
+ postLockActions.push_back(waiter.callback);
421
+ }
422
+ disableWaitlist.clear();
423
+ }
424
+
425
+ /**
426
+ * Detaches the given process from this Group. This function doesn't touch
427
+ * getWaitlist so be sure to fix its invariants afterwards if necessary.
428
+ */
429
+ void detach(const ProcessPtr &process, vector<Callback> &postLockActions) {
430
+ assert(process->getGroup().get() == this);
431
+ if (process->enabled == Process::ENABLED || process->enabled == Process::DISABLING) {
432
+ assert(count > 0);
433
+ process->setGroup(GroupPtr());
434
+ processes.erase(process->it);
435
+ pqueue.erase(process->pqHandle);
436
+ count--;
437
+ if (process->enabled == Process::DISABLING) {
438
+ disablingCount--;
439
+ removeFromDisableWaitlist(process, postLockActions);
440
+ }
441
+ } else {
442
+ assert(!disabledProcesses.empty());
443
+ process->setGroup(GroupPtr());
444
+ disabledProcesses.erase(process->it);
445
+ disabledCount--;
446
+ }
447
+ }
448
+
449
+ /**
450
+ * Detaches all processes from this Group. This function doesn't touch
451
+ * getWaitlist so be sure to fix its invariants afterwards if necessary.
452
+ */
453
+ void detachAll(vector<Callback> &postLockActions) {
454
+ ProcessList::iterator it, end = processes.end();
455
+ for (it = processes.begin(); it != end; it++) {
456
+ (*it)->setGroup(GroupPtr());
457
+ }
458
+
459
+ processes.clear();
460
+ disabledProcesses.clear();
461
+ pqueue.clear();
462
+ count = 0;
463
+ disablingCount = 0;
464
+ disabledCount = 0;
465
+
466
+ postLockActions.reserve(disableWaitlist.size());
467
+ while (!disableWaitlist.empty()) {
468
+ const DisableWaiter &waiter = disableWaitlist.front();
469
+ assert(waiter.process->enabled == Process::DISABLING);
470
+ postLockActions.push_back(waiter.callback);
471
+ disableWaitlist.pop_front();
472
+ }
473
+ }
474
+
475
+ /**
476
+ * Marks the given process as enabled. This function doesn't touch getWaitlist
477
+ * so be sure to fix its invariants afterwards if necessary.
478
+ */
479
+ void enable(const ProcessPtr &process, vector<Callback> &postLockActions) {
480
+ assert(process->getGroup().get() == this);
481
+ if (process->enabled == Process::DISABLING) {
482
+ process->enabled = Process::ENABLED;
483
+ disablingCount--;
484
+ removeFromDisableWaitlist(process, postLockActions);
485
+ } else if (process->enabled == Process::DISABLED) {
486
+ disabledProcesses.erase(process->it);
487
+ processes.push_back(process);
488
+ process->it = processes.last_iterator();
489
+ process->pqHandle = pqueue.push(process.get(), process->utilization());
490
+ process->enabled = Process::ENABLED;
491
+ count++;
492
+ disabledCount--;
493
+ }
494
+ }
495
+
496
+ /**
497
+ * Marks the given process as disabled.
498
+ */
499
+ bool disable(const ProcessPtr &process, const Callback &callback) {
500
+ assert(process->getGroup().get() == this);
501
+ if (process->enabled == Process::ENABLED) {
502
+ assert(count > 0);
503
+ if (count - disablingCount == 1) {
504
+ /* All processes are going to be disabled, so in order
505
+ * to avoid blocking requests we first spawn a new process
506
+ * and disable this process after the other one is done
507
+ * spawning. We do this irregardless of resource limits
508
+ * because we assume the administrator knows what he's
509
+ * doing.
510
+ */
511
+ process->enabled = Process::DISABLING;
512
+ disablingCount++;
513
+ disableWaitlist.push_back(DisableWaiter(process, callback));
514
+ spawn();
515
+ return false;
516
+ } else {
517
+ assert(count - disablingCount > 1);
518
+ processes.erase(process->it);
519
+ disabledProcesses.push_back(process);
520
+ pqueue.erase(process->pqHandle);
521
+ process->it = disabledProcesses.last_iterator();
522
+ process->enabled = Process::DISABLED;
523
+ return true;
524
+ }
525
+ } else if (process->enabled == Process::DISABLING) {
526
+ disableWaitlist.push_back(DisableWaiter(process, callback));
527
+ return false;
528
+ } else {
529
+ return true;
530
+ }
531
+ }
532
+
533
+ void asyncCleanupSpawner() {
534
+ createInterruptableThread(
535
+ boost::bind(cleanupSpawner, spawner),
536
+ "Group spawner cleanup: " + name,
537
+ POOL_HELPER_THREAD_STACK_SIZE);
538
+ }
539
+
540
+ unsigned int utilization() const {
541
+ int result = count;
542
+ if (spawning()) {
543
+ result++;
544
+ }
545
+ return result;
546
+ }
547
+
548
+ bool garbageCollectable(unsigned long long now = 0) const {
549
+ /* if (now == 0) {
550
+ now = SystemTime::getUsec();
551
+ }
552
+ return utilization() == 0
553
+ && getWaitlist.empty()
554
+ && disabledProcesses.empty()
555
+ && options.getMaxPreloaderIdleTime() != 0
556
+ && now - spawner->lastUsed() >
557
+ (unsigned long long) options.getMaxPreloaderIdleTime() * 1000000; */
558
+ return false;
559
+ }
560
+
561
+ /** Whether a new process should be spawned for this group in case
562
+ * another get action is to be performed.
563
+ */
564
+ bool shouldSpawn() const;
565
+
566
+ /** Start spawning a new process in the background, in case this
567
+ * isn't already happening and the group isn't being restarted.
568
+ * Will ensure that at least options.minProcesses processes are spawned.
569
+ */
570
+ void spawn() {
571
+ if (!spawning() && !restarting()) {
572
+ P_DEBUG("Requested spawning of new process for group " << name);
573
+ createInterruptableThread(
574
+ boost::bind(&Group::spawnThreadMain,
575
+ this, shared_from_this(), spawner,
576
+ options.copyAndPersist().clearPerRequestFields()),
577
+ "Group process spawner: " + name,
578
+ POOL_HELPER_THREAD_STACK_SIZE);
579
+ m_spawning = true;
580
+ }
581
+ }
582
+
583
+ bool needsRestart(const Options &options) {
584
+ if (m_restarting) {
585
+ return false;
586
+ } else {
587
+ struct stat buf;
588
+ return cstat.stat(alwaysRestartFile, &buf, options.statThrottleRate) == 0 ||
589
+ fileChangeChecker.changed(restartFile, options.statThrottleRate);
590
+ }
591
+ }
592
+
593
+ void restart(const Options &options);
594
+
595
+ bool spawning() const {
596
+ return m_spawning;
597
+ }
598
+
599
+ bool restarting() const {
600
+ return m_restarting;
601
+ }
602
+
603
+ template<typename Stream>
604
+ void inspectXml(Stream &stream, bool includeSecrets = true) const {
605
+ ProcessList::const_iterator it;
606
+
607
+ stream << "<name>" << escapeForXml(name) << "</name>";
608
+ stream << "<component_name>" << escapeForXml(componentInfo.name) << "</component_name>";
609
+ stream << "<app_root>" << escapeForXml(options.appRoot) << "</app_root>";
610
+ stream << "<app_type>" << escapeForXml(options.appType) << "</app_type>";
611
+ stream << "<environment>" << escapeForXml(options.environment) << "</environment>";
612
+ stream << "<process_count>" << (count + disabledCount) << "</process_count>";
613
+ stream << "<utilization>" << utilization() << "</utilization>";
614
+ stream << "<get_wait_list_size>" << getWaitlist.size() << "</get_wait_list_size>";
615
+ stream << "<disable_wait_list_size>" << disableWaitlist.size() << "</disable_wait_list_size>";
616
+ if (spawning()) {
617
+ stream << "<spawning/>";
618
+ }
619
+ if (restarting()) {
620
+ stream << "<restarting/>";
621
+ }
622
+ if (includeSecrets) {
623
+ stream << "<secret>" << escapeForXml(secret) << "</secret>";
624
+ }
625
+
626
+ stream << "<processes>";
627
+
628
+ for (it = processes.begin(); it != processes.end(); it++) {
629
+ stream << "<process>";
630
+ (*it)->inspectXml(stream, includeSecrets);
631
+ stream << "</process>";
632
+ }
633
+
634
+ for (it = disabledProcesses.begin(); it != disabledProcesses.end(); it++) {
635
+ stream << "<process>";
636
+ (*it)->inspectXml(stream, includeSecrets);
637
+ stream << "</process>";
638
+ }
639
+
640
+ stream << "</processes>";
641
+ }
642
+ };
643
+
644
+
645
+ } // namespace ApplicationPool2
646
+ } // namespace Passenger
647
+
648
+ #endif /* _PASSENGER_APPLICATION_POOL2_GROUP_H_ */