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
@@ -2,7 +2,7 @@
2
2
  * OXT - OS eXtensions for boosT
3
3
  * Provides important functionality necessary for writing robust server software.
4
4
  *
5
- * Copyright (c) 2010 Phusion
5
+ * Copyright (c) 2010-2012 Phusion
6
6
  *
7
7
  * Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  * of this software and associated documentation files (the "Software"), to deal
@@ -40,20 +40,26 @@
40
40
  #include <cstdio>
41
41
  #include <ctime>
42
42
  #include <cassert>
43
+ #include "macros.hpp"
43
44
 
44
45
  /**
45
- * Support for interruption of blocking system calls and C library calls
46
+ * System call and C library call wrappers with extra features
46
47
  *
47
- * This file provides a framework for writing multithreading code that can
48
- * be interrupted, even when blocked on system calls or C library calls.
48
+ * This file provides wrappers for many system calls and C library calls
49
+ * and adds the following features:
49
50
  *
50
- * One must first call oxt::setup_syscall_interruption_support().
51
+ * - Interruption of blocking system calls and blocking C library calls.
52
+ * - Simulation of random failures.
53
+ *
54
+ * ## About system call interruption
55
+ *
56
+ * One must first call `oxt::setup_syscall_interruption_support()`.
51
57
  * Then one may use the functions in oxt::syscalls as drop-in replacements
52
58
  * for system calls or C library functions. These functions throw
53
59
  * boost::thread_interrupted upon interruption, instead of returning an EINTR
54
60
  * error.
55
61
  *
56
- * Once setup_syscall_interruption_support() has been called, system call
62
+ * Once `setup_syscall_interruption_support()` has been called, system call
57
63
  * interruption is enabled by default. You can enable or disable system call
58
64
  * interruption in the current scope by creating instances of
59
65
  * boost::this_thread::enable_syscall_interruption or
@@ -63,7 +69,8 @@
63
69
  * boost::thread_interrupted, nor will they return EINTR errors. This is similar
64
70
  * to Boost thread interruption.
65
71
  *
66
- * <h2>How to interrupt</h2>
72
+ * ### How to interrupt
73
+ *
67
74
  * Generally, oxt::thread::interrupt() and oxt::thread::interrupt_and_join()
68
75
  * should be used for interrupting threads. These methods will interrupt
69
76
  * the thread at all Boost interruption points, as well as system calls that
@@ -89,12 +96,18 @@
89
96
  * received. So one must keep sending signals periodically until the
90
97
  * thread has quit.
91
98
  *
92
- * @warning
93
- * After oxt::setup_syscall_interruption_support() is called, sending a signal
99
+ * **Warning**:
100
+ *
101
+ * After `oxt::setup_syscall_interruption_support()` is called, sending a signal
94
102
  * will cause system calls to return with an EINTR error. The oxt::syscall
95
103
  * functions will automatically take care of this, but if you're calling any
96
104
  * system calls without using that namespace, then you should check for and
97
105
  * take care of EINTR errors.
106
+ *
107
+ * ## About random simulation of failures
108
+ *
109
+ * Call `oxt::setup_random_failure_simulation()` to initialize random
110
+ * failure simulation.
98
111
  */
99
112
 
100
113
  // This is one of the things that Java is good at and C++ sucks at. Sigh...
@@ -102,21 +115,14 @@
102
115
  namespace oxt {
103
116
  static const int INTERRUPTION_SIGNAL = SIGUSR1; // SIGUSR2 is reserved by Valgrind...
104
117
 
105
- /**
106
- * Setup system call interruption support.
107
- * This function may only be called once. It installs a signal handler
108
- * for INTERRUPTION_SIGNAL, so one should not install a different signal
109
- * handler for that signal after calling this function. It also resets
110
- * the process signal mask.
111
- *
112
- * @warning
113
- * After oxt::setup_syscall_interruption_support() is called, sending a signal
114
- * will cause system calls to return with an EINTR error. The oxt::syscall
115
- * functions will automatically take care of this, but if you're calling any
116
- * system calls without using that namespace, then you should check for and
117
- * take care of EINTR errors.
118
- */
118
+ struct ErrorChance {
119
+ double chance;
120
+ int errorCode;
121
+ };
122
+
119
123
  void setup_syscall_interruption_support();
124
+
125
+ void setup_random_failure_simulation(const ErrorChance *errorChances, unsigned int n);
120
126
 
121
127
  /**
122
128
  * System call and C library call wrappers with interruption support.
@@ -133,6 +139,8 @@ namespace oxt {
133
139
  int close(int fd);
134
140
  int pipe(int filedes[2]);
135
141
  int dup2(int filedes, int filedes2);
142
+ int mkdir(const char *pathname, mode_t mode);
143
+ int chown(const char *path, uid_t owner, gid_t group);
136
144
 
137
145
  int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
138
146
  int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
@@ -155,6 +163,7 @@ namespace oxt {
155
163
  int fclose(FILE *fp);
156
164
  int unlink(const char *pathname);
157
165
  int stat(const char *path, struct stat *buf);
166
+ int lstat(const char *path, struct stat *buf);
158
167
 
159
168
  time_t time(time_t *t);
160
169
  unsigned int sleep(unsigned int seconds);
@@ -175,8 +184,12 @@ namespace this_thread {
175
184
  /**
176
185
  * @intern
177
186
  */
178
- extern thread_specific_ptr<bool> _syscalls_interruptable;
179
-
187
+ #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
188
+ extern __thread bool _syscalls_interruptable;
189
+ #else
190
+ extern thread_specific_ptr<bool> _syscalls_interruptable;
191
+ #endif
192
+
180
193
  /**
181
194
  * Check whether system calls should be interruptable in
182
195
  * the calling thread.
@@ -194,17 +207,26 @@ namespace this_thread {
194
207
  bool last_value;
195
208
  public:
196
209
  enable_syscall_interruption() {
197
- if (_syscalls_interruptable.get() == NULL) {
198
- last_value = true;
199
- _syscalls_interruptable.reset(new bool(true));
200
- } else {
201
- last_value = *_syscalls_interruptable;
202
- *_syscalls_interruptable = true;
203
- }
210
+ #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
211
+ last_value = _syscalls_interruptable;
212
+ _syscalls_interruptable = true;
213
+ #else
214
+ if (_syscalls_interruptable.get() == NULL) {
215
+ last_value = true;
216
+ _syscalls_interruptable.reset(new bool(true));
217
+ } else {
218
+ last_value = *_syscalls_interruptable;
219
+ *_syscalls_interruptable = true;
220
+ }
221
+ #endif
204
222
  }
205
223
 
206
224
  ~enable_syscall_interruption() {
207
- *_syscalls_interruptable = last_value;
225
+ #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
226
+ _syscalls_interruptable = last_value;
227
+ #else
228
+ *_syscalls_interruptable = last_value;
229
+ #endif
208
230
  }
209
231
  };
210
232
 
@@ -220,17 +242,26 @@ namespace this_thread {
220
242
  bool last_value;
221
243
  public:
222
244
  disable_syscall_interruption() {
223
- if (_syscalls_interruptable.get() == NULL) {
224
- last_value = true;
225
- _syscalls_interruptable.reset(new bool(false));
226
- } else {
227
- last_value = *_syscalls_interruptable;
228
- *_syscalls_interruptable = false;
229
- }
245
+ #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
246
+ last_value = _syscalls_interruptable;
247
+ _syscalls_interruptable = false;
248
+ #else
249
+ if (_syscalls_interruptable.get() == NULL) {
250
+ last_value = true;
251
+ _syscalls_interruptable.reset(new bool(false));
252
+ } else {
253
+ last_value = *_syscalls_interruptable;
254
+ *_syscalls_interruptable = false;
255
+ }
256
+ #endif
230
257
  }
231
258
 
232
259
  ~disable_syscall_interruption() {
233
- *_syscalls_interruptable = last_value;
260
+ #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
261
+ _syscalls_interruptable = last_value;
262
+ #else
263
+ *_syscalls_interruptable = last_value;
264
+ #endif
234
265
  }
235
266
  };
236
267
 
@@ -243,13 +274,22 @@ namespace this_thread {
243
274
  int last_value;
244
275
  public:
245
276
  restore_syscall_interruption(const disable_syscall_interruption &intr) {
246
- assert(_syscalls_interruptable.get() != NULL);
247
- last_value = *_syscalls_interruptable;
248
- *_syscalls_interruptable = intr.last_value;
277
+ #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
278
+ last_value = _syscalls_interruptable;
279
+ _syscalls_interruptable = intr.last_value;
280
+ #else
281
+ assert(_syscalls_interruptable.get() != NULL);
282
+ last_value = *_syscalls_interruptable;
283
+ *_syscalls_interruptable = intr.last_value;
284
+ #endif
249
285
  }
250
286
 
251
287
  ~restore_syscall_interruption() {
252
- *_syscalls_interruptable = last_value;
288
+ #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
289
+ _syscalls_interruptable = last_value;
290
+ #else
291
+ *_syscalls_interruptable = last_value;
292
+ #endif
253
293
  }
254
294
  };
255
295
 
@@ -26,14 +26,11 @@
26
26
  #define _OXT_THREAD_HPP_
27
27
 
28
28
  #include <boost/thread.hpp>
29
- #include <boost/shared_ptr.hpp>
30
29
  #include <boost/bind.hpp>
30
+ #include <boost/make_shared.hpp>
31
31
  #include <boost/date_time/posix_time/posix_time_types.hpp>
32
32
  #include "system_calls.hpp"
33
- #include "backtrace.hpp"
34
- #ifdef OXT_BACKTRACE_IS_ENABLED
35
- #include <sstream>
36
- #endif
33
+ #include "detail/context.hpp"
37
34
  #include <string>
38
35
  #include <list>
39
36
  #include <unistd.h>
@@ -41,9 +38,6 @@
41
38
 
42
39
  namespace oxt {
43
40
 
44
- extern boost::mutex _next_thread_number_mutex;
45
- extern unsigned int _next_thread_number;
46
-
47
41
  /**
48
42
  * Enhanced thread class with support for:
49
43
  * - user-defined stack size.
@@ -52,63 +46,10 @@ extern unsigned int _next_thread_number;
52
46
  */
53
47
  class thread: public boost::thread {
54
48
  private:
55
- struct thread_data {
56
- std::string name;
57
- #ifdef OXT_BACKTRACE_IS_ENABLED
58
- thread_registration *registration;
59
- boost::mutex registration_lock;
60
- bool done;
61
- #endif
62
- };
63
-
64
- typedef boost::shared_ptr<thread_data> thread_data_ptr;
65
-
66
- thread_data_ptr data;
49
+ thread_local_context_ptr context;
67
50
 
68
- void initialize_data(const std::string &thread_name) {
69
- data = thread_data_ptr(new thread_data());
70
- if (thread_name.empty()) {
71
- boost::mutex::scoped_lock l(_next_thread_number_mutex);
72
- std::stringstream str;
73
-
74
- str << "Thread #" << _next_thread_number;
75
- _next_thread_number++;
76
- data->name = str.str();
77
- } else {
78
- data->name = thread_name;
79
- }
80
- #ifdef OXT_BACKTRACE_IS_ENABLED
81
- data->registration = NULL;
82
- data->done = false;
83
- #endif
84
- }
85
-
86
- static void thread_main(const boost::function<void ()> func, thread_data_ptr data) {
87
- #ifdef OXT_BACKTRACE_IS_ENABLED
88
- initialize_backtrace_support_for_this_thread i(data->name);
89
- data->registration = i.registration;
90
- #endif
91
-
92
- #ifdef OXT_BACKTRACE_IS_ENABLED
93
- // Put finalization code in a struct destructor,
94
- // for exception safety.
95
- struct finalization_routines {
96
- thread_data_ptr &data;
97
-
98
- finalization_routines(thread_data_ptr &data_)
99
- : data(data_) {}
100
-
101
- ~finalization_routines() {
102
- boost::mutex::scoped_lock l(data->registration_lock);
103
- data->registration = NULL;
104
- data->done = true;
105
- }
106
- };
107
- finalization_routines f(data);
108
- #endif
109
-
110
- func();
111
- }
51
+ static std::string make_thread_name(const std::string &given_name);
52
+ static void thread_main(const boost::function<void ()> func, thread_local_context_ptr ctx);
112
53
 
113
54
  public:
114
55
  /**
@@ -129,10 +70,10 @@ public:
129
70
  * @throws boost::thread_resource_error Something went wrong during
130
71
  * creation of the thread.
131
72
  */
132
- explicit thread(const boost::function<void ()> func, const std::string &name = "", unsigned int stack_size = 0) {
133
- initialize_data(name);
134
-
135
- set_thread_main_function(boost::bind(thread_main, func, data));
73
+ explicit thread(const boost::function<void ()> func, const std::string &name = std::string(), unsigned int stack_size = 0) {
74
+ context = thread_local_context::make_shared_ptr();
75
+ context->thread_name = make_thread_name(name);
76
+ set_thread_main_function(boost::bind(thread_main, func, context));
136
77
 
137
78
  unsigned long min_stack_size;
138
79
  bool stack_min_size_defined;
@@ -180,53 +121,18 @@ public:
180
121
  /**
181
122
  * Return this thread's name. The name was set during construction.
182
123
  */
183
- std::string name() const throw() {
184
- return data->name;
185
- }
124
+ std::string name() const throw();
186
125
 
187
126
  /**
188
127
  * Return the current backtrace of the thread of execution, as a string.
189
128
  */
190
- std::string backtrace() const throw() {
191
- #ifdef OXT_BACKTRACE_IS_ENABLED
192
- boost::mutex::scoped_lock l(data->registration_lock);
193
- if (data->registration == NULL) {
194
- if (data->done) {
195
- return " (no backtrace: thread has quit)";
196
- } else {
197
- return " (no backtrace: thread hasn't been started yet)";
198
- }
199
- } else {
200
- spin_lock::scoped_lock l2(*data->registration->backtrace_lock);
201
- return _format_backtrace(data->registration->backtrace);
202
- }
203
- #else
204
- return " (backtrace support disabled during compile time)";
205
- #endif
206
- }
129
+ std::string backtrace() const throw();
207
130
 
208
131
  /**
209
132
  * Return the backtraces of all oxt::thread threads, as well as that of the
210
133
  * main thread, in a nicely formatted string.
211
134
  */
212
- static std::string all_backtraces() throw() {
213
- #ifdef OXT_BACKTRACE_IS_ENABLED
214
- boost::mutex::scoped_lock l(_thread_registration_mutex);
215
- list<thread_registration *>::const_iterator it;
216
- std::stringstream result;
217
-
218
- for (it = _registered_threads.begin(); it != _registered_threads.end(); it++) {
219
- thread_registration *r = *it;
220
- result << "Thread '" << r->name << "':" << endl;
221
-
222
- spin_lock::scoped_lock l(*r->backtrace_lock);
223
- result << _format_backtrace(r->backtrace) << endl;
224
- }
225
- return result.str();
226
- #else
227
- return "(backtrace support disabled during compile time)";
228
- #endif
229
- }
135
+ static std::string all_backtraces() throw();
230
136
 
231
137
  /**
232
138
  * Interrupt the thread. This method behaves just like
@@ -240,17 +146,7 @@ public:
240
146
  * interrupt_and_join() is a convenience method that implements this
241
147
  * pattern.
242
148
  */
243
- void interrupt(bool interruptSyscalls = true) {
244
- int ret;
245
-
246
- boost::thread::interrupt();
247
- if (interruptSyscalls) {
248
- do {
249
- ret = pthread_kill(native_handle(),
250
- INTERRUPTION_SIGNAL);
251
- } while (ret == EINTR);
252
- }
253
- }
149
+ void interrupt(bool interruptSyscalls = true);
254
150
 
255
151
  /**
256
152
  * Keep interrupting the thread until it's done, then join it.
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - http://www.modrails.com/
3
- * Copyright (c) 2010 Phusion
3
+ * Copyright (c) 2010, 2011, 2012 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -33,6 +33,7 @@
33
33
  #include <sys/types.h>
34
34
  #include <sys/stat.h>
35
35
  #include <sys/ioctl.h>
36
+ #include <sys/wait.h>
36
37
  #include <sys/un.h>
37
38
  #include <sys/socket.h>
38
39
  #include <sys/uio.h>
@@ -47,12 +48,12 @@
47
48
  #include <limits.h>
48
49
  #include <grp.h>
49
50
  #include <signal.h>
51
+ #include <pthread.h>
50
52
  #ifdef HAVE_ALLOCA_H
51
53
  #include <alloca.h>
52
54
  #endif
53
55
  #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
54
56
  #define HAVE_KQUEUE
55
- #include <pthread.h>
56
57
  #include <sys/event.h>
57
58
  #include <sys/time.h>
58
59
  #endif
@@ -83,213 +84,6 @@ static VALUE S_ProcessTimes;
83
84
  static VALUE cFileSystemWatcher;
84
85
  #endif
85
86
 
86
- /*
87
- * call-seq: send_fd(socket_fd, fd_to_send)
88
- *
89
- * Send a file descriptor over the given Unix socket. You do not have to call
90
- * this function directly. A convenience wrapper is provided by IO#send_io.
91
- *
92
- * - +socket_fd+ (integer): The file descriptor of the socket.
93
- * - +fd_to_send+ (integer): The file descriptor to send.
94
- * - Raises +SystemCallError+ if something went wrong.
95
- */
96
- static VALUE
97
- send_fd(VALUE self, VALUE socket_fd, VALUE fd_to_send) {
98
- struct msghdr msg;
99
- struct iovec vec;
100
- char dummy[1];
101
- #if defined(__APPLE__) || defined(__SOLARIS__) || defined(__arm__)
102
- struct {
103
- struct cmsghdr header;
104
- int fd;
105
- } control_data;
106
- #else
107
- char control_data[CMSG_SPACE(sizeof(int))];
108
- #endif
109
- struct cmsghdr *control_header;
110
- int control_payload;
111
-
112
- msg.msg_name = NULL;
113
- msg.msg_namelen = 0;
114
-
115
- /* Linux and Solaris require msg_iov to be non-NULL. */
116
- dummy[0] = '\0';
117
- vec.iov_base = dummy;
118
- vec.iov_len = sizeof(dummy);
119
- msg.msg_iov = &vec;
120
- msg.msg_iovlen = 1;
121
-
122
- msg.msg_control = (caddr_t) &control_data;
123
- msg.msg_controllen = sizeof(control_data);
124
- msg.msg_flags = 0;
125
-
126
- control_header = CMSG_FIRSTHDR(&msg);
127
- control_header->cmsg_level = SOL_SOCKET;
128
- control_header->cmsg_type = SCM_RIGHTS;
129
- control_payload = NUM2INT(fd_to_send);
130
- #if defined(__APPLE__) || defined(__SOLARIS__) || defined(__arm__)
131
- control_header->cmsg_len = sizeof(control_data);
132
- control_data.fd = control_payload;
133
- #else
134
- control_header->cmsg_len = CMSG_LEN(sizeof(int));
135
- memcpy(CMSG_DATA(control_header), &control_payload, sizeof(int));
136
- #endif
137
-
138
- if (sendmsg(NUM2INT(socket_fd), &msg, 0) == -1) {
139
- rb_sys_fail("sendmsg(2)");
140
- return Qnil;
141
- }
142
-
143
- return Qnil;
144
- }
145
-
146
- /*
147
- * call-seq: recv_fd(socket_fd)
148
- *
149
- * Receive a file descriptor from the given Unix socket. Returns the received
150
- * file descriptor as an integer. Raises +SystemCallError+ if something went
151
- * wrong.
152
- *
153
- * You do not have call this method directly. A convenience wrapper is
154
- * provided by IO#recv_io.
155
- */
156
- static VALUE
157
- recv_fd(VALUE self, VALUE socket_fd) {
158
- struct msghdr msg;
159
- struct iovec vec;
160
- char dummy[1];
161
- #if defined(__APPLE__) || defined(__SOLARIS__) || defined(__arm__)
162
- // File descriptor passing macros (CMSG_*) seem to be broken
163
- // on 64-bit MacOS X. This structure works around the problem.
164
- struct {
165
- struct cmsghdr header;
166
- int fd;
167
- } control_data;
168
- #define EXPECTED_CMSG_LEN sizeof(control_data)
169
- #else
170
- char control_data[CMSG_SPACE(sizeof(int))];
171
- #define EXPECTED_CMSG_LEN CMSG_LEN(sizeof(int))
172
- #endif
173
- struct cmsghdr *control_header;
174
-
175
- msg.msg_name = NULL;
176
- msg.msg_namelen = 0;
177
-
178
- dummy[0] = '\0';
179
- vec.iov_base = dummy;
180
- vec.iov_len = sizeof(dummy);
181
- msg.msg_iov = &vec;
182
- msg.msg_iovlen = 1;
183
-
184
- msg.msg_control = (caddr_t) &control_data;
185
- msg.msg_controllen = sizeof(control_data);
186
- msg.msg_flags = 0;
187
-
188
- if (recvmsg(NUM2INT(socket_fd), &msg, 0) == -1) {
189
- rb_sys_fail("Cannot read file descriptor with recvmsg()");
190
- return Qnil;
191
- }
192
-
193
- control_header = CMSG_FIRSTHDR(&msg);
194
- if (control_header == NULL) {
195
- rb_raise(rb_eIOError, "No valid file descriptor received.");
196
- return Qnil;
197
- }
198
- if (control_header->cmsg_len != EXPECTED_CMSG_LEN
199
- || control_header->cmsg_level != SOL_SOCKET
200
- || control_header->cmsg_type != SCM_RIGHTS) {
201
- rb_raise(rb_eIOError, "No valid file descriptor received.");
202
- return Qnil;
203
- }
204
- #if defined(__APPLE__) || defined(__SOLARIS__) || defined(__arm__)
205
- return INT2NUM(control_data.fd);
206
- #else
207
- return INT2NUM(*((int *) CMSG_DATA(control_header)));
208
- #endif
209
- }
210
-
211
- /*
212
- * call-seq: create_unix_socket(filename, backlog)
213
- *
214
- * Create a SOCK_STREAM server Unix socket. Unlike Ruby's UNIXServer class,
215
- * this function is also able to create Unix sockets on the abstract namespace
216
- * by prepending the filename with a null byte.
217
- *
218
- * - +filename+ (string): The filename of the Unix socket to create.
219
- * - +backlog+ (integer): The backlog to use for listening on the socket.
220
- * - Returns: The file descriptor of the created Unix socket, as an integer.
221
- * - Raises +SystemCallError+ if something went wrong.
222
- */
223
- static VALUE
224
- create_unix_socket(VALUE self, VALUE filename, VALUE backlog) {
225
- int fd, ret;
226
- struct sockaddr_un addr;
227
- const char *filename_str;
228
- long filename_length;
229
-
230
- filename_str = RSTRING_PTR(filename);
231
- filename_length = RSTRING_LEN(filename);
232
-
233
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
234
- if (fd == -1) {
235
- rb_sys_fail("Cannot create a Unix socket");
236
- return Qnil;
237
- }
238
-
239
- addr.sun_family = AF_UNIX;
240
- memcpy(addr.sun_path, filename_str,
241
- MIN((long) filename_length, (long) sizeof(addr.sun_path)));
242
- addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
243
-
244
- ret = bind(fd, (const struct sockaddr *) &addr, sizeof(addr));
245
- if (ret == -1) {
246
- int e = errno;
247
- close(fd);
248
- errno = e;
249
- rb_sys_fail("Cannot bind Unix socket");
250
- return Qnil;
251
- }
252
-
253
- ret = listen(fd, NUM2INT(backlog));
254
- if (ret == -1) {
255
- int e = errno;
256
- close(fd);
257
- errno = e;
258
- rb_sys_fail("Cannot listen on Unix socket");
259
- return Qnil;
260
- }
261
- return INT2NUM(fd);
262
- }
263
-
264
- /*
265
- * call-seq: close_all_file_descriptors(exceptions)
266
- *
267
- * Close all file descriptors, except those given in the +exceptions+ array.
268
- * For example, the following would close all file descriptors except standard
269
- * input (0) and standard output (1).
270
- *
271
- * close_all_file_descriptors([0, 1])
272
- */
273
- static VALUE
274
- close_all_file_descriptors(VALUE self, VALUE exceptions) {
275
- long i, j;
276
-
277
- for (i = sysconf(_SC_OPEN_MAX) - 1; i >= 0; i--) {
278
- int is_exception = 0;
279
- #ifdef RB_RESERVED_FD_P
280
- is_exception = rb_reserved_fd_p((int) i);
281
- #endif
282
- for (j = 0; j < RARRAY_LEN(exceptions) && !is_exception; j++) {
283
- long fd = NUM2INT(rb_ary_entry(exceptions, j));
284
- is_exception = i == fd;
285
- }
286
- if (!is_exception) {
287
- close((int) i);
288
- }
289
- }
290
- return Qnil;
291
- }
292
-
293
87
  /*
294
88
  * call-seq: disable_stdio_buffering
295
89
  *
@@ -586,29 +380,6 @@ f_writev3(VALUE self, VALUE fd, VALUE components1, VALUE components2, VALUE comp
586
380
  return f_generic_writev(fd, array_of_components, 3);
587
381
  }
588
382
 
589
- /**
590
- * Ruby's implementations of initgroups, setgid and setuid are broken various ways,
591
- * sigh...
592
- * Ruby's setgid and setuid can't handle negative UIDs and initgroups is just broken.
593
- * Work around it by using our own implementation.
594
- */
595
- static VALUE
596
- switch_user(VALUE self, VALUE username, VALUE uid, VALUE gid) {
597
- uid_t the_uid = (uid_t) NUM2LL(uid);
598
- gid_t the_gid = (gid_t) NUM2LL(gid);
599
-
600
- if (initgroups(RSTRING_PTR(username), the_gid) == -1) {
601
- rb_sys_fail("initgroups");
602
- }
603
- if (setgid(the_gid) == -1) {
604
- rb_sys_fail("setgid");
605
- }
606
- if (setuid(the_uid) == -1) {
607
- rb_sys_fail("setuid");
608
- }
609
- return Qnil;
610
- }
611
-
612
383
  static VALUE
613
384
  process_times(VALUE self) {
614
385
  struct rusage usage;
@@ -623,6 +394,82 @@ process_times(VALUE self) {
623
394
  return rb_struct_new(S_ProcessTimes, rb_ull2inum(utime), rb_ull2inum(stime));
624
395
  }
625
396
 
397
+ static void *
398
+ detach_process_main(void *arg) {
399
+ pid_t pid = (pid_t) (long) arg;
400
+ int ret;
401
+ do {
402
+ ret = waitpid(pid, NULL, 0);
403
+ } while (ret == -1 && errno == EINTR);
404
+ return NULL;
405
+ }
406
+
407
+ static VALUE
408
+ detach_process(VALUE self, VALUE pid) {
409
+ pthread_t thr;
410
+ pthread_attr_t attr;
411
+ size_t stack_size = 96 * 1024;
412
+
413
+ unsigned long min_stack_size;
414
+ int stack_min_size_defined;
415
+ int round_stack_size;
416
+
417
+ #ifdef PTHREAD_STACK_MIN
418
+ // PTHREAD_STACK_MIN may not be a constant macro so we need
419
+ // to evaluate it dynamically.
420
+ min_stack_size = PTHREAD_STACK_MIN;
421
+ stack_min_size_defined = 1;
422
+ #else
423
+ // Assume minimum stack size is 128 KB.
424
+ min_stack_size = 128 * 1024;
425
+ stack_min_size_defined = 0;
426
+ #endif
427
+ if (stack_size != 0 && stack_size < min_stack_size) {
428
+ stack_size = min_stack_size;
429
+ round_stack_size = !stack_min_size_defined;
430
+ } else {
431
+ round_stack_size = 1;
432
+ }
433
+
434
+ if (round_stack_size) {
435
+ // Round stack size up to page boundary.
436
+ long page_size;
437
+ #if defined(_SC_PAGESIZE)
438
+ page_size = sysconf(_SC_PAGESIZE);
439
+ #elif defined(_SC_PAGE_SIZE)
440
+ page_size = sysconf(_SC_PAGE_SIZE);
441
+ #elif defined(PAGESIZE)
442
+ page_size = sysconf(PAGESIZE);
443
+ #elif defined(PAGE_SIZE)
444
+ page_size = sysconf(PAGE_SIZE);
445
+ #else
446
+ page_size = getpagesize();
447
+ #endif
448
+ if (stack_size % page_size != 0) {
449
+ stack_size = stack_size - (stack_size % page_size) + page_size;
450
+ }
451
+ }
452
+
453
+ pthread_attr_init(&attr);
454
+ pthread_attr_setdetachstate(&attr, 1);
455
+ pthread_attr_setstacksize(&attr, stack_size);
456
+ pthread_create(&thr, &attr, detach_process_main, (void *) NUM2LONG(pid));
457
+ pthread_attr_destroy(&attr);
458
+ return Qnil;
459
+ }
460
+
461
+ /**
462
+ * Freeze the current process forever. On Ruby 1.9 this never unlocks the GIL.
463
+ * Useful for testing purposes.
464
+ */
465
+ static VALUE
466
+ freeze_process(VALUE self) {
467
+ while (1) {
468
+ usleep(60 * 1000000);
469
+ }
470
+ return Qnil;
471
+ }
472
+
626
473
  #if defined(HAVE_KQUEUE) || defined(IN_DOXYGEN)
627
474
  typedef struct {
628
475
  VALUE klass;
@@ -824,6 +671,7 @@ fs_watcher_new(VALUE klass, VALUE filenames, VALUE termination_pipe) {
824
671
  if (status) {
825
672
  fs_watcher_free(watcher);
826
673
  rb_jump_tag(status);
674
+ return Qnil;
827
675
  } else {
828
676
  return result;
829
677
  }
@@ -1010,17 +858,14 @@ Init_passenger_native_support() {
1010
858
 
1011
859
  S_ProcessTimes = rb_struct_define("ProcessTimes", "utime", "stime", NULL);
1012
860
 
1013
- rb_define_singleton_method(mNativeSupport, "send_fd", send_fd, 2);
1014
- rb_define_singleton_method(mNativeSupport, "recv_fd", recv_fd, 1);
1015
- rb_define_singleton_method(mNativeSupport, "create_unix_socket", create_unix_socket, 2);
1016
- rb_define_singleton_method(mNativeSupport, "close_all_file_descriptors", close_all_file_descriptors, 1);
1017
861
  rb_define_singleton_method(mNativeSupport, "disable_stdio_buffering", disable_stdio_buffering, 0);
1018
862
  rb_define_singleton_method(mNativeSupport, "split_by_null_into_hash", split_by_null_into_hash, 1);
1019
863
  rb_define_singleton_method(mNativeSupport, "writev", f_writev, 2);
1020
864
  rb_define_singleton_method(mNativeSupport, "writev2", f_writev2, 3);
1021
865
  rb_define_singleton_method(mNativeSupport, "writev3", f_writev3, 4);
1022
- rb_define_singleton_method(mNativeSupport, "switch_user", switch_user, 3);
1023
866
  rb_define_singleton_method(mNativeSupport, "process_times", process_times, 0);
867
+ rb_define_singleton_method(mNativeSupport, "detach_process", detach_process, 1);
868
+ rb_define_singleton_method(mNativeSupport, "freeze_process", freeze_process, 0);
1024
869
 
1025
870
  #ifdef HAVE_KQUEUE
1026
871
  cFileSystemWatcher = rb_define_class_under(mNativeSupport,