passenger 3.0.0 → 3.0.1

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 (538) hide show
  1. data/DEVELOPERS.TXT +9 -6
  2. data/NEWS +50 -0
  3. data/Rakefile +2 -1
  4. data/bin/passenger-install-apache2-module +4 -4
  5. data/bin/passenger-install-nginx-module +1 -1
  6. data/bin/passenger-make-enterprisey +1 -1
  7. data/build/agents.rb +26 -19
  8. data/build/apache2.rb +49 -46
  9. data/build/basics.rb +37 -13
  10. data/build/common_library.rb +134 -64
  11. data/build/config.rb +18 -11
  12. data/build/cplusplus_support.rb +4 -0
  13. data/build/cxx_tests.rb +26 -12
  14. data/build/documentation.rb +18 -11
  15. data/build/integration_tests.rb +18 -11
  16. data/build/misc.rb +18 -11
  17. data/build/nginx.rb +27 -19
  18. data/build/oxt_tests.rb +18 -11
  19. data/build/packaging.rb +45 -37
  20. data/build/rpm.rb +98 -0
  21. data/build/ruby_extension.rb +19 -13
  22. data/build/ruby_tests.rb +19 -12
  23. data/build/test_basics.rb +23 -11
  24. data/debian/README.Debian +15 -0
  25. data/debian/changelog +185 -0
  26. data/debian/control +47 -19
  27. data/debian/copyright +20 -0
  28. data/debian/libapache2-mod-passenger.install +1 -0
  29. data/debian/libapache2-mod-passenger.postinst +36 -0
  30. data/debian/libapache2-mod-passenger.prerm +15 -0
  31. data/debian/passenger-common.install +4 -0
  32. data/debian/passenger.conf +4 -0
  33. data/debian/passenger.load +1 -0
  34. data/debian/rules +37 -0
  35. data/debian/watch +3 -0
  36. data/{misc → dev}/copy_boost_headers.rb +3 -0
  37. data/{misc → dev}/find_owner_pipe_leaks.rb +0 -0
  38. data/{misc → dev}/render_error_pages.rb +0 -0
  39. data/doc/Users guide Apache.html +39 -1
  40. data/doc/Users guide Apache.txt +40 -0
  41. data/doc/Users guide Nginx.html +1 -1
  42. data/doc/Users guide Standalone.html +1 -1
  43. data/doc/cxxapi/Constants_8h_source.html +1 -1
  44. data/doc/cxxapi/DirectoryMapper_8h_source.html +6 -22
  45. data/doc/cxxapi/EventedClient_8h_source.html +572 -468
  46. data/doc/cxxapi/Exceptions_8h_source.html +142 -129
  47. data/doc/cxxapi/FileDescriptor_8h_source.html +263 -199
  48. data/doc/cxxapi/MessageChannel_8h_source.html +686 -770
  49. data/doc/cxxapi/MessageServer_8h_source.html +1 -1
  50. data/doc/cxxapi/PoolOptions_8h_source.html +79 -78
  51. data/doc/cxxapi/ResourceLocator_8h_source.html +105 -55
  52. data/doc/cxxapi/SafeLibev_8h_source.html +180 -0
  53. data/doc/cxxapi/ServerInstanceDir_8h_source.html +114 -110
  54. data/doc/cxxapi/Session_8h_source.html +1 -1
  55. data/doc/cxxapi/SpawnManager_8h_source.html +208 -208
  56. data/doc/cxxapi/StaticString_8h_source.html +258 -183
  57. data/doc/cxxapi/Utils_8h_source.html +71 -54
  58. data/doc/cxxapi/annotated.html +3 -0
  59. data/doc/cxxapi/classAgentWatcher.html +2 -2
  60. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +0 -1
  61. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +0 -27
  62. data/doc/cxxapi/classPassenger_1_1EventedClient-members.html +5 -0
  63. data/doc/cxxapi/classPassenger_1_1EventedClient.html +102 -7
  64. data/doc/cxxapi/classPassenger_1_1FileDescriptor-members.html +2 -1
  65. data/doc/cxxapi/classPassenger_1_1FileDescriptor.html +34 -8
  66. data/doc/cxxapi/classPassenger_1_1FileDescriptorPair-members.html +36 -0
  67. data/doc/cxxapi/classPassenger_1_1FileDescriptorPair.html +52 -0
  68. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +0 -3
  69. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +0 -120
  70. data/doc/cxxapi/classPassenger_1_1SafeLibev-members.html +36 -0
  71. data/doc/cxxapi/classPassenger_1_1SafeLibev.html +51 -0
  72. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -0
  73. data/doc/cxxapi/classPassenger_1_1SpawnException.html +22 -0
  74. data/doc/cxxapi/classes.html +14 -14
  75. data/doc/cxxapi/files.html +2 -0
  76. data/doc/cxxapi/functions_0x63.html +6 -3
  77. data/doc/cxxapi/functions_0x64.html +9 -2
  78. data/doc/cxxapi/functions_0x67.html +6 -9
  79. data/doc/cxxapi/functions_0x69.html +3 -0
  80. data/doc/cxxapi/functions_0x77.html +8 -8
  81. data/doc/cxxapi/functions_eval.html +6 -0
  82. data/doc/cxxapi/functions_func.html +18 -17
  83. data/doc/cxxapi/functions_vars.html +8 -0
  84. data/doc/cxxapi/graph_legend.png +0 -0
  85. data/doc/cxxapi/group__Core.png +0 -0
  86. data/doc/cxxapi/group__Hooks.png +0 -0
  87. data/doc/cxxapi/hierarchy.html +3 -0
  88. data/doc/cxxapi/inherit__graph__14.map +1 -1
  89. data/doc/cxxapi/inherit__graph__14.md5 +1 -1
  90. data/doc/cxxapi/inherit__graph__14.png +0 -0
  91. data/doc/cxxapi/inherit__graph__15.map +1 -3
  92. data/doc/cxxapi/inherit__graph__15.md5 +1 -1
  93. data/doc/cxxapi/inherit__graph__15.png +0 -0
  94. data/doc/cxxapi/inherit__graph__16.map +3 -1
  95. data/doc/cxxapi/inherit__graph__16.md5 +1 -1
  96. data/doc/cxxapi/inherit__graph__16.png +0 -0
  97. data/doc/cxxapi/inherit__graph__17.map +1 -1
  98. data/doc/cxxapi/inherit__graph__17.md5 +1 -1
  99. data/doc/cxxapi/inherit__graph__17.png +0 -0
  100. data/doc/cxxapi/inherit__graph__18.map +1 -2
  101. data/doc/cxxapi/inherit__graph__18.md5 +1 -1
  102. data/doc/cxxapi/inherit__graph__18.png +0 -0
  103. data/doc/cxxapi/inherit__graph__19.map +2 -1
  104. data/doc/cxxapi/inherit__graph__19.md5 +1 -1
  105. data/doc/cxxapi/inherit__graph__19.png +0 -0
  106. data/doc/cxxapi/inherit__graph__20.map +1 -1
  107. data/doc/cxxapi/inherit__graph__20.md5 +1 -1
  108. data/doc/cxxapi/inherit__graph__20.png +0 -0
  109. data/doc/cxxapi/inherit__graph__21.map +1 -1
  110. data/doc/cxxapi/inherit__graph__21.md5 +1 -1
  111. data/doc/cxxapi/inherit__graph__21.png +0 -0
  112. data/doc/cxxapi/inherit__graph__22.map +1 -1
  113. data/doc/cxxapi/inherit__graph__22.md5 +1 -1
  114. data/doc/cxxapi/inherit__graph__22.png +0 -0
  115. data/doc/cxxapi/inherit__graph__23.map +1 -1
  116. data/doc/cxxapi/inherit__graph__23.md5 +1 -1
  117. data/doc/cxxapi/inherit__graph__23.png +0 -0
  118. data/doc/cxxapi/inherit__graph__24.map +1 -1
  119. data/doc/cxxapi/inherit__graph__24.md5 +1 -1
  120. data/doc/cxxapi/inherit__graph__24.png +0 -0
  121. data/doc/cxxapi/inherit__graph__25.map +1 -1
  122. data/doc/cxxapi/inherit__graph__25.md5 +1 -1
  123. data/doc/cxxapi/inherit__graph__25.png +0 -0
  124. data/doc/cxxapi/inherit__graph__26.map +1 -1
  125. data/doc/cxxapi/inherit__graph__26.md5 +1 -1
  126. data/doc/cxxapi/inherit__graph__26.png +0 -0
  127. data/doc/cxxapi/inherit__graph__27.map +1 -1
  128. data/doc/cxxapi/inherit__graph__27.md5 +1 -1
  129. data/doc/cxxapi/inherit__graph__27.png +0 -0
  130. data/doc/cxxapi/inherit__graph__28.map +1 -2
  131. data/doc/cxxapi/inherit__graph__28.md5 +1 -1
  132. data/doc/cxxapi/inherit__graph__28.png +0 -0
  133. data/doc/cxxapi/inherit__graph__29.map +1 -1
  134. data/doc/cxxapi/inherit__graph__29.md5 +1 -1
  135. data/doc/cxxapi/inherit__graph__29.png +0 -0
  136. data/doc/cxxapi/inherit__graph__30.map +1 -1
  137. data/doc/cxxapi/inherit__graph__30.md5 +1 -1
  138. data/doc/cxxapi/inherit__graph__30.png +0 -0
  139. data/doc/cxxapi/inherit__graph__31.map +2 -1
  140. data/doc/cxxapi/inherit__graph__31.md5 +1 -1
  141. data/doc/cxxapi/inherit__graph__31.png +0 -0
  142. data/doc/cxxapi/inherit__graph__32.map +1 -3
  143. data/doc/cxxapi/inherit__graph__32.md5 +1 -1
  144. data/doc/cxxapi/inherit__graph__32.png +0 -0
  145. data/doc/cxxapi/inherit__graph__33.map +1 -1
  146. data/doc/cxxapi/inherit__graph__33.md5 +1 -1
  147. data/doc/cxxapi/inherit__graph__33.png +0 -0
  148. data/doc/cxxapi/inherit__graph__34.map +1 -1
  149. data/doc/cxxapi/inherit__graph__34.md5 +1 -1
  150. data/doc/cxxapi/inherit__graph__34.png +0 -0
  151. data/doc/cxxapi/inherit__graph__35.map +3 -1
  152. data/doc/cxxapi/inherit__graph__35.md5 +1 -1
  153. data/doc/cxxapi/inherit__graph__35.png +0 -0
  154. data/doc/cxxapi/inherit__graph__36.map +1 -1
  155. data/doc/cxxapi/inherit__graph__36.md5 +1 -1
  156. data/doc/cxxapi/inherit__graph__36.png +0 -0
  157. data/doc/cxxapi/inherit__graph__37.map +1 -1
  158. data/doc/cxxapi/inherit__graph__37.md5 +1 -1
  159. data/doc/cxxapi/inherit__graph__37.png +0 -0
  160. data/doc/cxxapi/inherit__graph__38.map +3 -1
  161. data/doc/cxxapi/inherit__graph__38.md5 +1 -1
  162. data/doc/cxxapi/inherit__graph__38.png +0 -0
  163. data/doc/cxxapi/inherit__graph__39.map +3 -1
  164. data/doc/cxxapi/inherit__graph__39.md5 +1 -1
  165. data/doc/cxxapi/inherit__graph__39.png +0 -0
  166. data/doc/cxxapi/inherits.html +33 -24
  167. data/doc/cxxapi/namespacePassenger.html +52 -0
  168. data/doc/cxxapi/namespacemembers.html +6 -0
  169. data/doc/cxxapi/namespacemembers_func.html +6 -0
  170. data/doc/cxxapi/tree.html +8 -0
  171. data/ext/apache2/Configuration.cpp +30 -8
  172. data/ext/apache2/Configuration.hpp +15 -14
  173. data/ext/apache2/DirectoryMapper.h +0 -16
  174. data/ext/apache2/Hooks.cpp +30 -29
  175. data/ext/boost/algorithm/string/detail/case_conv.hpp +6 -6
  176. data/ext/boost/algorithm/string/detail/find_format.hpp +14 -4
  177. data/ext/boost/algorithm/string/detail/find_format_all.hpp +13 -3
  178. data/ext/boost/algorithm/string/detail/find_format_store.hpp +11 -0
  179. data/ext/boost/algorithm/string/erase.hpp +2 -2
  180. data/ext/boost/bind/placeholders.hpp +2 -2
  181. data/ext/boost/concept/detail/backward_compatibility.hpp +16 -0
  182. data/ext/boost/concept/detail/general.hpp +15 -6
  183. data/ext/boost/concept/detail/has_constraints.hpp +5 -3
  184. data/ext/boost/concept/usage.hpp +5 -4
  185. data/ext/boost/concept_check.hpp +10 -1
  186. data/ext/boost/config/abi/borland_prefix.hpp +1 -1
  187. data/ext/boost/config/auto_link.hpp +68 -21
  188. data/ext/boost/config/compiler/borland.hpp +11 -3
  189. data/ext/boost/config/compiler/clang.hpp +62 -0
  190. data/ext/boost/config/compiler/codegear.hpp +21 -7
  191. data/ext/boost/config/compiler/common_edg.hpp +4 -2
  192. data/ext/boost/config/compiler/digitalmars.hpp +1 -1
  193. data/ext/boost/config/compiler/gcc.hpp +46 -7
  194. data/ext/boost/config/compiler/gcc_xml.hpp +25 -0
  195. data/ext/boost/config/compiler/intel.hpp +23 -0
  196. data/ext/boost/config/compiler/kai.hpp +1 -1
  197. data/ext/boost/config/compiler/metrowerks.hpp +1 -1
  198. data/ext/boost/config/compiler/nvcc.hpp +86 -0
  199. data/ext/boost/config/compiler/pgi.hpp +18 -3
  200. data/ext/boost/config/compiler/sunpro_cc.hpp +19 -5
  201. data/ext/boost/config/compiler/vacpp.hpp +8 -0
  202. data/ext/boost/config/compiler/visualc.hpp +27 -11
  203. data/ext/boost/config/platform/cygwin.hpp +0 -3
  204. data/ext/boost/config/platform/symbian.hpp +94 -0
  205. data/ext/boost/config/platform/win32.hpp +8 -1
  206. data/ext/boost/config/select_compiler_config.hpp +10 -0
  207. data/ext/boost/config/select_platform_config.hpp +4 -0
  208. data/ext/boost/config/stdlib/dinkumware.hpp +11 -1
  209. data/ext/boost/config/stdlib/libcomo.hpp +1 -0
  210. data/ext/boost/config/stdlib/libstdcpp3.hpp +1 -0
  211. data/ext/boost/config/stdlib/modena.hpp +1 -0
  212. data/ext/boost/config/stdlib/msl.hpp +1 -0
  213. data/ext/boost/config/stdlib/roguewave.hpp +1 -0
  214. data/ext/boost/config/stdlib/sgi.hpp +1 -0
  215. data/ext/boost/config/stdlib/stlport.hpp +1 -0
  216. data/ext/boost/config/stdlib/vacpp.hpp +1 -0
  217. data/ext/boost/config/suffix.hpp +40 -2
  218. data/ext/boost/cstdint.hpp +36 -7
  219. data/ext/boost/date_time/gregorian/conversion.hpp +4 -2
  220. data/ext/boost/date_time/microsec_time_clock.hpp +7 -7
  221. data/ext/boost/date_time/posix_time/conversion.hpp +4 -2
  222. data/ext/boost/date_time/time_facet.hpp +43 -4
  223. data/ext/boost/detail/endian.hpp +5 -2
  224. data/ext/boost/detail/lcast_precision.hpp +2 -2
  225. data/ext/boost/detail/sp_typeinfo.hpp +1 -1
  226. data/ext/boost/detail/workaround.hpp +5 -0
  227. data/ext/boost/exception/detail/error_info_impl.hpp +3 -3
  228. data/ext/boost/exception/detail/exception_ptr.hpp +76 -135
  229. data/ext/boost/exception/detail/is_output_streamable.hpp +15 -2
  230. data/ext/boost/exception/detail/type_info.hpp +9 -5
  231. data/ext/boost/exception/diagnostic_information.hpp +5 -3
  232. data/ext/boost/exception/exception.hpp +60 -46
  233. data/ext/boost/exception/info.hpp +47 -14
  234. data/ext/boost/function/function_base.hpp +4 -4
  235. data/ext/boost/integer.hpp +4 -0
  236. data/ext/boost/integer_fwd.hpp +9 -3
  237. data/ext/boost/iterator/iterator_concepts.hpp +284 -0
  238. data/ext/boost/iterator/transform_iterator.hpp +0 -1
  239. data/ext/boost/make_shared.hpp +17 -0
  240. data/ext/boost/mpl/aux_/config/has_xxx.hpp +4 -3
  241. data/ext/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp +2 -6
  242. data/ext/boost/mpl/aux_/template_arity.hpp +4 -4
  243. data/ext/boost/mpl/eval_if.hpp +3 -3
  244. data/ext/boost/mpl/has_xxx.hpp +369 -3
  245. data/ext/boost/optional/optional.hpp +3 -1
  246. data/ext/boost/optional/optional_fwd.hpp +1 -1
  247. data/ext/boost/preprocessor/repetition/enum_trailing_params.hpp +38 -0
  248. data/ext/boost/range/algorithm/equal.hpp +188 -0
  249. data/ext/boost/range/as_literal.hpp +15 -15
  250. data/ext/boost/range/concepts.hpp +331 -0
  251. data/ext/boost/range/const_iterator.hpp +7 -4
  252. data/ext/boost/range/detail/extract_optional_type.hpp +52 -0
  253. data/ext/boost/range/detail/implementation_help.hpp +7 -7
  254. data/ext/boost/range/detail/misc_concept.hpp +33 -0
  255. data/ext/boost/range/iterator.hpp +32 -32
  256. data/ext/boost/range/iterator_range.hpp +8 -651
  257. data/ext/boost/range/iterator_range_core.hpp +542 -0
  258. data/ext/boost/range/iterator_range_io.hpp +93 -0
  259. data/ext/boost/range/mutable_iterator.hpp +7 -4
  260. data/ext/boost/range/size.hpp +1 -1
  261. data/ext/boost/range/size_type.hpp +2 -1
  262. data/ext/boost/shared_array.hpp +19 -0
  263. data/ext/boost/smart_ptr/detail/sp_convertible.hpp +2 -2
  264. data/ext/boost/smart_ptr/detail/yield_k.hpp +1 -1
  265. data/ext/boost/smart_ptr/make_shared.hpp +508 -0
  266. data/ext/boost/smart_ptr/shared_array.hpp +147 -0
  267. data/ext/boost/src/pthread/thread.cpp +16 -21
  268. data/ext/boost/src/pthread/timeconv.inl +7 -4
  269. data/ext/boost/thread/barrier.hpp +2 -1
  270. data/ext/boost/thread/detail/config.hpp +7 -1
  271. data/ext/boost/thread/detail/platform.hpp +1 -1
  272. data/ext/boost/thread/detail/thread.hpp +62 -18
  273. data/ext/boost/thread/detail/thread_group.hpp +5 -2
  274. data/ext/boost/thread/detail/tss_hooks.hpp +8 -25
  275. data/ext/boost/thread/future.hpp +45 -34
  276. data/ext/boost/thread/locks.hpp +184 -55
  277. data/ext/boost/thread/pthread/condition_variable.hpp +7 -7
  278. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +4 -2
  279. data/ext/boost/thread/pthread/mutex.hpp +29 -17
  280. data/ext/boost/thread/pthread/once.hpp +5 -0
  281. data/ext/boost/thread/pthread/recursive_mutex.hpp +97 -18
  282. data/ext/boost/thread/pthread/shared_mutex.hpp +1 -1
  283. data/ext/boost/thread/pthread/thread_heap_alloc.hpp +1 -1
  284. data/ext/boost/thread/tss.hpp +2 -0
  285. data/ext/boost/throw_exception.hpp +21 -5
  286. data/ext/boost/token_functions.hpp +111 -91
  287. data/ext/boost/type_traits/add_reference.hpp +19 -1
  288. data/ext/boost/type_traits/function_traits.hpp +2 -2
  289. data/ext/boost/type_traits/is_const.hpp +24 -5
  290. data/ext/boost/type_traits/is_convertible.hpp +1 -1
  291. data/ext/boost/type_traits/is_function.hpp +3 -0
  292. data/ext/boost/type_traits/is_lvalue_reference.hpp +118 -0
  293. data/ext/boost/type_traits/is_reference.hpp +8 -81
  294. data/ext/boost/type_traits/is_rvalue_reference.hpp +29 -0
  295. data/ext/boost/type_traits/is_same.hpp +2 -2
  296. data/ext/boost/type_traits/is_volatile.hpp +26 -7
  297. data/ext/boost/type_traits/remove_const.hpp +12 -0
  298. data/ext/boost/type_traits/remove_cv.hpp +23 -1
  299. data/ext/boost/type_traits/remove_reference.hpp +21 -1
  300. data/ext/boost/type_traits/type_with_alignment.hpp +10 -10
  301. data/ext/boost/units/detail/utility.hpp +104 -0
  302. data/ext/boost/utility/compare_pointees.hpp +1 -1
  303. data/ext/common/AgentsStarter.hpp +151 -161
  304. data/ext/common/ApplicationPool/Pool.h +16 -4
  305. data/ext/common/Constants.h +1 -1
  306. data/ext/common/EventedClient.h +130 -26
  307. data/ext/common/Exceptions.h +15 -2
  308. data/ext/common/FileDescriptor.h +76 -12
  309. data/ext/common/IniFile.h +488 -0
  310. data/ext/common/LoggingAgent/LoggingServer.h +2 -2
  311. data/ext/common/LoggingAgent/RemoteSender.h +15 -6
  312. data/ext/common/MessageChannel.h +17 -101
  313. data/ext/common/PoolOptions.h +1 -0
  314. data/ext/common/ResourceLocator.h +78 -28
  315. data/ext/common/SafeLibev.h +149 -0
  316. data/ext/common/ServerInstanceDir.h +11 -7
  317. data/ext/common/Session.h +1 -1
  318. data/ext/common/SpawnManager.h +14 -14
  319. data/ext/common/StaticString.h +75 -0
  320. data/ext/common/Utils.cpp +304 -12
  321. data/ext/common/Utils.h +17 -0
  322. data/ext/common/Utils/BufferedIO.h +196 -0
  323. data/ext/common/Utils/IOUtils.cpp +159 -0
  324. data/ext/common/Utils/IOUtils.h +118 -1
  325. data/ext/common/Utils/ProcessMetricsCollector.h +184 -56
  326. data/ext/common/Utils/StrIntUtils.cpp +45 -11
  327. data/ext/common/Utils/StrIntUtils.h +8 -5
  328. data/ext/common/Utils/Timer.h +22 -0
  329. data/ext/common/Utils/utf8.h +35 -0
  330. data/ext/common/Utils/utf8/checked.h +324 -0
  331. data/ext/common/Utils/utf8/core.h +359 -0
  332. data/ext/common/Utils/utf8/unchecked.h +229 -0
  333. data/ext/common/Watchdog.cpp +52 -85
  334. data/ext/libev/config.h +122 -0
  335. data/ext/nginx/Configuration.c +7 -1
  336. data/ext/nginx/HelperAgent.cpp +16 -18
  337. data/ext/nginx/config +6 -4
  338. data/ext/oxt/system_calls.cpp +10 -0
  339. data/ext/oxt/system_calls.hpp +2 -0
  340. data/lib/phusion_passenger.rb +6 -11
  341. data/lib/phusion_passenger/dependencies.rb +2 -0
  342. data/lib/phusion_passenger/packaging.rb +5 -5
  343. data/lib/phusion_passenger/platform_info.rb +88 -0
  344. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +3 -17
  345. data/lib/phusion_passenger/platform_info/compiler.rb +14 -32
  346. data/lib/phusion_passenger/platform_info/curl.rb +6 -1
  347. data/lib/phusion_passenger/platform_info/operating_system.rb +107 -0
  348. data/lib/phusion_passenger/public_api.rb +2 -2
  349. data/lib/phusion_passenger/rails3_extensions/init.rb +5 -2
  350. data/lib/phusion_passenger/standalone/command.rb +6 -2
  351. data/lib/phusion_passenger/standalone/package_runtime_command.rb +2 -2
  352. data/lib/phusion_passenger/standalone/runtime_installer.rb +17 -5
  353. data/lib/phusion_passenger/standalone/start_command.rb +12 -12
  354. data/lib/phusion_passenger/standalone/stop_command.rb +3 -3
  355. data/lib/phusion_passenger/standalone/utils.rb +6 -2
  356. data/lib/phusion_passenger/templates/standalone/config.erb +37 -5
  357. data/lib/phusion_passenger/utils.rb +4 -7
  358. data/resources/mime.types +73 -0
  359. data/{misc → resources}/union_station_gateway.crt +0 -0
  360. data/test/cxx/BufferedIOTest.cpp +364 -0
  361. data/test/cxx/EventedClientTest.cpp +150 -13
  362. data/test/cxx/IOUtilsTest.cpp +399 -1
  363. data/test/cxx/MessageChannelTest.cpp +5 -120
  364. data/test/cxx/ProcessMetricsCollectorTest.cpp +121 -0
  365. data/test/cxx/StaticStringTest.cpp +134 -0
  366. data/test/cxx/UtilsTest.cpp +16 -46
  367. data/test/stub/rails_apps/2.3/mycook/public/dispatch.cgi +2 -2
  368. data/test/stub/rails_apps/2.3/mycook/public/dispatch.fcgi +1 -1
  369. data/test/stub/rails_apps/2.3/mycook/public/dispatch.rb +1 -1
  370. data/test/stub/rails_apps/3.0/empty/Gemfile.lock +73 -0
  371. data/test/support/allocate_memory.c +14 -0
  372. data/test/support/test_helper.rb +3 -0
  373. metadata +57 -174
  374. data/bin/passenger-stress-test +0 -345
  375. data/debian/postinst +0 -24
  376. data/doc/rdoc/classes/ConditionVariable.html +0 -215
  377. data/doc/rdoc/classes/Exception.html +0 -120
  378. data/doc/rdoc/classes/GC.html +0 -113
  379. data/doc/rdoc/classes/IO.html +0 -221
  380. data/doc/rdoc/classes/PhusionPassenger.html +0 -397
  381. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +0 -180
  382. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +0 -647
  383. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +0 -654
  384. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/InvalidPassword.html +0 -92
  385. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +0 -97
  386. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +0 -96
  387. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +0 -97
  388. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +0 -96
  389. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +0 -619
  390. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +0 -142
  391. data/doc/rdoc/classes/PhusionPassenger/AdminTools/MemoryStats.html +0 -368
  392. data/doc/rdoc/classes/PhusionPassenger/AdminTools/MemoryStats/Process.html +0 -231
  393. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance.html +0 -588
  394. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/CorruptedDirectoryError.html +0 -92
  395. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/GenerationsAbsentError.html +0 -92
  396. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/Group.html +0 -147
  397. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/Process.html +0 -279
  398. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/RoleDeniedError.html +0 -92
  399. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/StaleDirectoryError.html +0 -92
  400. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/Stats.html +0 -123
  401. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/UnsupportedGenerationStructureVersionError.html +0 -92
  402. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger.html +0 -341
  403. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger/Log.html +0 -294
  404. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger/SharedData.html +0 -199
  405. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +0 -155
  406. data/doc/rdoc/classes/PhusionPassenger/AppProcess.html +0 -367
  407. data/doc/rdoc/classes/PhusionPassenger/ClassicRails.html +0 -95
  408. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/ApplicationSpawner.html +0 -351
  409. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/ApplicationSpawner/Error.html +0 -98
  410. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/CGIFixed.html +0 -200
  411. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/FrameworkSpawner.html +0 -410
  412. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/FrameworkSpawner/Error.html +0 -98
  413. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/RequestHandler.html +0 -156
  414. data/doc/rdoc/classes/PhusionPassenger/ClassicRailsExtensions.html +0 -115
  415. data/doc/rdoc/classes/PhusionPassenger/ClassicRailsExtensions/AnalyticsLogging.html +0 -202
  416. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +0 -172
  417. data/doc/rdoc/classes/PhusionPassenger/DebugLogging.html +0 -273
  418. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +0 -145
  419. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +0 -162
  420. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +0 -141
  421. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +0 -92
  422. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +0 -673
  423. data/doc/rdoc/classes/PhusionPassenger/MessageChannel/InvalidHashError.html +0 -92
  424. data/doc/rdoc/classes/PhusionPassenger/MessageClient.html +0 -415
  425. data/doc/rdoc/classes/PhusionPassenger/NativeSupportLoader.html +0 -134
  426. data/doc/rdoc/classes/PhusionPassenger/Packaging.html +0 -129
  427. data/doc/rdoc/classes/PhusionPassenger/PlatformInfo.html +0 -1809
  428. data/doc/rdoc/classes/PhusionPassenger/Plugin.html +0 -237
  429. data/doc/rdoc/classes/PhusionPassenger/Rack.html +0 -91
  430. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +0 -312
  431. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner/Error.html +0 -98
  432. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +0 -218
  433. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions.html +0 -114
  434. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging.html +0 -256
  435. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging/ACExtension.html +0 -139
  436. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging/ASBenchmarkableExtension.html +0 -118
  437. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging/ExceptionLogger.html +0 -135
  438. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +0 -378
  439. data/doc/rdoc/classes/PhusionPassenger/Standalone.html +0 -111
  440. data/doc/rdoc/classes/PhusionPassenger/Standalone/AppFinder.html +0 -252
  441. data/doc/rdoc/classes/PhusionPassenger/Standalone/Command.html +0 -161
  442. data/doc/rdoc/classes/PhusionPassenger/Standalone/ConfigFile.html +0 -368
  443. data/doc/rdoc/classes/PhusionPassenger/Standalone/ConfigFile/DisallowedContextError.html +0 -132
  444. data/doc/rdoc/classes/PhusionPassenger/Standalone/HelpCommand.html +0 -151
  445. data/doc/rdoc/classes/PhusionPassenger/Standalone/Main.html +0 -189
  446. data/doc/rdoc/classes/PhusionPassenger/Standalone/PackageRuntimeCommand.html +0 -177
  447. data/doc/rdoc/classes/PhusionPassenger/Standalone/RuntimeInstaller.html +0 -341
  448. data/doc/rdoc/classes/PhusionPassenger/Standalone/StartCommand.html +0 -203
  449. data/doc/rdoc/classes/PhusionPassenger/Standalone/StatusCommand.html +0 -156
  450. data/doc/rdoc/classes/PhusionPassenger/Standalone/StopCommand.html +0 -168
  451. data/doc/rdoc/classes/PhusionPassenger/Standalone/Utils.html +0 -86
  452. data/doc/rdoc/classes/PhusionPassenger/Standalone/VersionCommand.html +0 -135
  453. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +0 -125
  454. data/doc/rdoc/classes/PhusionPassenger/Utils.html +0 -1550
  455. data/doc/rdoc/classes/PhusionPassenger/Utils/FileSystemWatcher.html +0 -204
  456. data/doc/rdoc/classes/PhusionPassenger/Utils/FileSystemWatcher/DirInfo.html +0 -171
  457. data/doc/rdoc/classes/PhusionPassenger/Utils/FileSystemWatcher/FileInfo.html +0 -140
  458. data/doc/rdoc/classes/PhusionPassenger/Utils/HostsFileParser.html +0 -260
  459. data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +0 -169
  460. data/doc/rdoc/classes/PhusionPassenger/Utils/RewindableInput.html +0 -265
  461. data/doc/rdoc/classes/PhusionPassenger/Utils/RewindableInput/Tempfile.html +0 -120
  462. data/doc/rdoc/classes/PhusionPassenger/Utils/UnseekableSocket.html +0 -561
  463. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +0 -140
  464. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +0 -89
  465. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +0 -182
  466. data/doc/rdoc/classes/Process.html +0 -115
  467. data/doc/rdoc/classes/Signal.html +0 -139
  468. data/doc/rdoc/created.rid +0 -1
  469. data/doc/rdoc/files/DEVELOPERS_TXT.html +0 -276
  470. data/doc/rdoc/files/README.html +0 -157
  471. data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +0 -130
  472. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +0 -135
  473. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +0 -126
  474. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +0 -128
  475. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/memory_stats_rb.html +0 -126
  476. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/server_instance_rb.html +0 -132
  477. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +0 -122
  478. data/doc/rdoc/files/lib/phusion_passenger/analytics_logger_rb.html +0 -129
  479. data/doc/rdoc/files/lib/phusion_passenger/app_process_rb.html +0 -127
  480. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/application_spawner_rb.html +0 -141
  481. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/cgi_fixed_rb.html +0 -126
  482. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/framework_spawner_rb.html +0 -146
  483. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/request_handler_rb.html +0 -125
  484. data/doc/rdoc/files/lib/phusion_passenger/classic_rails_extensions/init_rb.html +0 -132
  485. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +0 -126
  486. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +0 -122
  487. data/doc/rdoc/files/lib/phusion_passenger/debug_logging_rb.html +0 -122
  488. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +0 -147
  489. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +0 -122
  490. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +0 -127
  491. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +0 -120
  492. data/doc/rdoc/files/lib/phusion_passenger/message_client_rb.html +0 -127
  493. data/doc/rdoc/files/lib/phusion_passenger/native_support_rb.html +0 -132
  494. data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +0 -122
  495. data/doc/rdoc/files/lib/phusion_passenger/platform_info/apache_rb.html +0 -127
  496. data/doc/rdoc/files/lib/phusion_passenger/platform_info/binary_compatibility_rb.html +0 -129
  497. data/doc/rdoc/files/lib/phusion_passenger/platform_info/compiler_rb.html +0 -126
  498. data/doc/rdoc/files/lib/phusion_passenger/platform_info/curl_rb.html +0 -126
  499. data/doc/rdoc/files/lib/phusion_passenger/platform_info/documentation_tools_rb.html +0 -126
  500. data/doc/rdoc/files/lib/phusion_passenger/platform_info/linux_rb.html +0 -126
  501. data/doc/rdoc/files/lib/phusion_passenger/platform_info/operating_system_rb.html +0 -127
  502. data/doc/rdoc/files/lib/phusion_passenger/platform_info/ruby_rb.html +0 -128
  503. data/doc/rdoc/files/lib/phusion_passenger/platform_info/zlib_rb.html +0 -126
  504. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +0 -122
  505. data/doc/rdoc/files/lib/phusion_passenger/plugin_rb.html +0 -127
  506. data/doc/rdoc/files/lib/phusion_passenger/public_api_rb.html +0 -127
  507. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +0 -137
  508. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +0 -125
  509. data/doc/rdoc/files/lib/phusion_passenger/rails3_extensions/init_rb.html +0 -127
  510. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +0 -122
  511. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +0 -160
  512. data/doc/rdoc/files/lib/phusion_passenger/standalone/app_finder_rb.html +0 -127
  513. data/doc/rdoc/files/lib/phusion_passenger/standalone/command_rb.html +0 -135
  514. data/doc/rdoc/files/lib/phusion_passenger/standalone/config_file_rb.html +0 -126
  515. data/doc/rdoc/files/lib/phusion_passenger/standalone/help_command_rb.html +0 -126
  516. data/doc/rdoc/files/lib/phusion_passenger/standalone/main_rb.html +0 -126
  517. data/doc/rdoc/files/lib/phusion_passenger/standalone/package_runtime_command_rb.html +0 -127
  518. data/doc/rdoc/files/lib/phusion_passenger/standalone/runtime_installer_rb.html +0 -133
  519. data/doc/rdoc/files/lib/phusion_passenger/standalone/start_command_rb.html +0 -136
  520. data/doc/rdoc/files/lib/phusion_passenger/standalone/status_command_rb.html +0 -126
  521. data/doc/rdoc/files/lib/phusion_passenger/standalone/stop_command_rb.html +0 -126
  522. data/doc/rdoc/files/lib/phusion_passenger/standalone/utils_rb.html +0 -126
  523. data/doc/rdoc/files/lib/phusion_passenger/standalone/version_command_rb.html +0 -127
  524. data/doc/rdoc/files/lib/phusion_passenger/utils/file_system_watcher_rb.html +0 -126
  525. data/doc/rdoc/files/lib/phusion_passenger/utils/hosts_file_parser_rb.html +0 -120
  526. data/doc/rdoc/files/lib/phusion_passenger/utils/rewindable_input_rb.html +0 -100
  527. data/doc/rdoc/files/lib/phusion_passenger/utils/tmpdir_rb.html +0 -122
  528. data/doc/rdoc/files/lib/phusion_passenger/utils/unseekable_socket_rb.html +0 -126
  529. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +0 -179
  530. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +0 -132
  531. data/doc/rdoc/fr_class_index.html +0 -138
  532. data/doc/rdoc/fr_file_index.html +0 -108
  533. data/doc/rdoc/fr_method_index.html +0 -430
  534. data/doc/rdoc/index.html +0 -26
  535. data/doc/rdoc/rdoc-style.css +0 -187
  536. data/ext/apache2/LICENSE-CNRI.TXT +0 -79
  537. data/ext/common/Utils/BlockingScalar.h +0 -50
  538. data/ext/common/Utils/FileHandleGuard.h +0 -81
@@ -246,126 +246,130 @@
246
246
  <a name="l00221"></a>00221 }
247
247
  <a name="l00222"></a>00222
248
248
  <a name="l00223"></a>00223 <span class="keywordtype">bool</span> isDirectory(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;dir, <span class="keyword">struct</span> dirent *entry)<span class="keyword"> const </span>{
249
- <a name="l00224"></a>00224 <span class="preprocessor"> #ifdef __sun__</span>
250
- <a name="l00225"></a>00225 <span class="preprocessor"></span> <span class="keywordtype">string</span> path = dir;
251
- <a name="l00226"></a>00226 path.append(<span class="stringliteral">&quot;/&quot;</span>);
252
- <a name="l00227"></a>00227 path.append(entry-&gt;d_name);
253
- <a name="l00228"></a>00228 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga15298b031377d3ecb80295bd5b1a8180" title="Check whether &amp;#39;filename&amp;#39; exists and what kind of file it is.">getFileType</a>(path) == <a class="code" href="namespacePassenger.html#a14174b712df6046cb823cde43d7ef07dabb09dbba1071b4770913363db2462eee" title="A directory.">FT_DIRECTORY</a>;
254
- <a name="l00229"></a>00229 <span class="preprocessor"> #else</span>
255
- <a name="l00230"></a>00230 <span class="preprocessor"></span> <span class="keywordflow">return</span> entry-&gt;d_type == DT_DIR;
249
+ <a name="l00224"></a>00224 <span class="preprocessor"> #ifdef DT_DIR</span>
250
+ <a name="l00225"></a>00225 <span class="preprocessor"></span> <span class="keywordflow">if</span> (entry-&gt;d_type == DT_DIR) {
251
+ <a name="l00226"></a>00226 <span class="keywordflow">return</span> <span class="keyword">true</span>;
252
+ <a name="l00227"></a>00227 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (entry-&gt;d_type != DT_UNKNOWN) {
253
+ <a name="l00228"></a>00228 <span class="keywordflow">return</span> <span class="keyword">false</span>;
254
+ <a name="l00229"></a>00229 }
255
+ <a name="l00230"></a>00230 <span class="comment">// If DT_UNKNOWN, use normal check.</span>
256
256
  <a name="l00231"></a>00231 <span class="preprocessor"> #endif</span>
257
- <a name="l00232"></a>00232 <span class="preprocessor"></span> }
258
- <a name="l00233"></a>00233
259
- <a name="l00234"></a>00234 <span class="keyword">public</span>:
260
- <a name="l00235"></a>00235 ServerInstanceDir(pid_t webServerPid, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;parentDir = <span class="stringliteral">&quot;&quot;</span>, <span class="keywordtype">bool</span> owner = <span class="keyword">true</span>) {
261
- <a name="l00236"></a>00236 <span class="keywordtype">string</span> theParentDir;
262
- <a name="l00237"></a>00237
263
- <a name="l00238"></a>00238 <span class="keywordflow">if</span> (parentDir.empty()) {
264
- <a name="l00239"></a>00239 theParentDir = <a class="code" href="group__Support.html#ga68f4105c5a8e510520b5ea3eecb66213" title="Return the path name for the directory in which the system stores general temporary...">getSystemTempDir</a>();
265
- <a name="l00240"></a>00240 } <span class="keywordflow">else</span> {
266
- <a name="l00241"></a>00241 theParentDir = parentDir;
267
- <a name="l00242"></a>00242 }
268
- <a name="l00243"></a>00243
269
- <a name="l00244"></a>00244 <span class="comment">/* We embed the super structure version in the server instance directory name</span>
270
- <a name="l00245"></a>00245 <span class="comment"> * because it&#39;s possible to upgrade Phusion Passenger without changing the</span>
271
- <a name="l00246"></a>00246 <span class="comment"> * web server&#39;s PID. This way each incompatible upgrade will use its own</span>
272
- <a name="l00247"></a>00247 <span class="comment"> * server instance directory.</span>
273
- <a name="l00248"></a>00248 <span class="comment"> */</span>
274
- <a name="l00249"></a>00249 initialize(theParentDir + <span class="stringliteral">&quot;/passenger.&quot;</span> +
275
- <a name="l00250"></a>00250 toString(DIR_STRUCTURE_MAJOR_VERSION) + <span class="stringliteral">&quot;.&quot;</span> +
276
- <a name="l00251"></a>00251 toString(DIR_STRUCTURE_MINOR_VERSION) + <span class="stringliteral">&quot;.&quot;</span> +
277
- <a name="l00252"></a>00252 toString&lt;unsigned long long&gt;(webServerPid),
278
- <a name="l00253"></a>00253 owner);
279
- <a name="l00254"></a>00254
280
- <a name="l00255"></a>00255 }
281
- <a name="l00256"></a>00256
282
- <a name="l00257"></a>00257 ServerInstanceDir(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;path, <span class="keywordtype">bool</span> owner = <span class="keyword">true</span>) {
283
- <a name="l00258"></a>00258 initialize(path, owner);
257
+ <a name="l00232"></a>00232 <span class="preprocessor"></span> <span class="keywordtype">string</span> path = dir;
258
+ <a name="l00233"></a>00233 path.append(<span class="stringliteral">&quot;/&quot;</span>);
259
+ <a name="l00234"></a>00234 path.append(entry-&gt;d_name);
260
+ <a name="l00235"></a>00235 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga15298b031377d3ecb80295bd5b1a8180" title="Check whether &amp;#39;filename&amp;#39; exists and what kind of file it is.">getFileType</a>(path) == <a class="code" href="namespacePassenger.html#a14174b712df6046cb823cde43d7ef07dabb09dbba1071b4770913363db2462eee" title="A directory.">FT_DIRECTORY</a>;
261
+ <a name="l00236"></a>00236 }
262
+ <a name="l00237"></a>00237
263
+ <a name="l00238"></a>00238 <span class="keyword">public</span>:
264
+ <a name="l00239"></a>00239 ServerInstanceDir(pid_t webServerPid, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;parentDir = <span class="stringliteral">&quot;&quot;</span>, <span class="keywordtype">bool</span> owner = <span class="keyword">true</span>) {
265
+ <a name="l00240"></a>00240 <span class="keywordtype">string</span> theParentDir;
266
+ <a name="l00241"></a>00241
267
+ <a name="l00242"></a>00242 <span class="keywordflow">if</span> (parentDir.empty()) {
268
+ <a name="l00243"></a>00243 theParentDir = <a class="code" href="group__Support.html#ga68f4105c5a8e510520b5ea3eecb66213" title="Return the path name for the directory in which the system stores general temporary...">getSystemTempDir</a>();
269
+ <a name="l00244"></a>00244 } <span class="keywordflow">else</span> {
270
+ <a name="l00245"></a>00245 theParentDir = parentDir;
271
+ <a name="l00246"></a>00246 }
272
+ <a name="l00247"></a>00247
273
+ <a name="l00248"></a>00248 <span class="comment">/* We embed the super structure version in the server instance directory name</span>
274
+ <a name="l00249"></a>00249 <span class="comment"> * because it&#39;s possible to upgrade Phusion Passenger without changing the</span>
275
+ <a name="l00250"></a>00250 <span class="comment"> * web server&#39;s PID. This way each incompatible upgrade will use its own</span>
276
+ <a name="l00251"></a>00251 <span class="comment"> * server instance directory.</span>
277
+ <a name="l00252"></a>00252 <span class="comment"> */</span>
278
+ <a name="l00253"></a>00253 initialize(theParentDir + <span class="stringliteral">&quot;/passenger.&quot;</span> +
279
+ <a name="l00254"></a>00254 toString(DIR_STRUCTURE_MAJOR_VERSION) + <span class="stringliteral">&quot;.&quot;</span> +
280
+ <a name="l00255"></a>00255 toString(DIR_STRUCTURE_MINOR_VERSION) + <span class="stringliteral">&quot;.&quot;</span> +
281
+ <a name="l00256"></a>00256 toString&lt;unsigned long long&gt;(webServerPid),
282
+ <a name="l00257"></a>00257 owner);
283
+ <a name="l00258"></a>00258
284
284
  <a name="l00259"></a>00259 }
285
285
  <a name="l00260"></a>00260
286
- <a name="l00261"></a>00261 ~ServerInstanceDir() {
287
- <a name="l00262"></a>00262 <span class="keywordflow">if</span> (owner) {
288
- <a name="l00263"></a>00263 GenerationPtr newestGeneration;
289
- <a name="l00264"></a>00264 <span class="keywordflow">try</span> {
290
- <a name="l00265"></a>00265 newestGeneration = getNewestGeneration();
291
- <a name="l00266"></a>00266 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> FileSystemException &amp;e) {
292
- <a name="l00267"></a>00267 <span class="keywordflow">if</span> (e.code() == ENOENT) {
293
- <a name="l00268"></a>00268 <span class="keywordflow">return</span>;
294
- <a name="l00269"></a>00269 } <span class="keywordflow">else</span> {
295
- <a name="l00270"></a>00270 <span class="keywordflow">throw</span>;
296
- <a name="l00271"></a>00271 }
297
- <a name="l00272"></a>00272 }
298
- <a name="l00273"></a>00273 <span class="keywordflow">if</span> (newestGeneration == NULL) {
299
- <a name="l00274"></a>00274 <a class="code" href="namespacePassenger.html#a8422d210cbd2f62d21254415b5a7f747" title="Remove an entire directory tree recursively.">removeDirTree</a>(path);
300
- <a name="l00275"></a>00275 }
301
- <a name="l00276"></a>00276 }
302
- <a name="l00277"></a>00277 }
303
- <a name="l00278"></a>00278
304
- <a name="l00279"></a>00279 <span class="keywordtype">string</span> getPath()<span class="keyword"> const </span>{
305
- <a name="l00280"></a>00280 <span class="keywordflow">return</span> path;
286
+ <a name="l00261"></a>00261 ServerInstanceDir(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;path, <span class="keywordtype">bool</span> owner = <span class="keyword">true</span>) {
287
+ <a name="l00262"></a>00262 initialize(path, owner);
288
+ <a name="l00263"></a>00263 }
289
+ <a name="l00264"></a>00264
290
+ <a name="l00265"></a>00265 ~ServerInstanceDir() {
291
+ <a name="l00266"></a>00266 <span class="keywordflow">if</span> (owner) {
292
+ <a name="l00267"></a>00267 GenerationPtr newestGeneration;
293
+ <a name="l00268"></a>00268 <span class="keywordflow">try</span> {
294
+ <a name="l00269"></a>00269 newestGeneration = getNewestGeneration();
295
+ <a name="l00270"></a>00270 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> FileSystemException &amp;e) {
296
+ <a name="l00271"></a>00271 <span class="keywordflow">if</span> (e.code() == ENOENT) {
297
+ <a name="l00272"></a>00272 <span class="keywordflow">return</span>;
298
+ <a name="l00273"></a>00273 } <span class="keywordflow">else</span> {
299
+ <a name="l00274"></a>00274 <span class="keywordflow">throw</span>;
300
+ <a name="l00275"></a>00275 }
301
+ <a name="l00276"></a>00276 }
302
+ <a name="l00277"></a>00277 <span class="keywordflow">if</span> (newestGeneration == NULL) {
303
+ <a name="l00278"></a>00278 <a class="code" href="namespacePassenger.html#a8422d210cbd2f62d21254415b5a7f747" title="Remove an entire directory tree recursively.">removeDirTree</a>(path);
304
+ <a name="l00279"></a>00279 }
305
+ <a name="l00280"></a>00280 }
306
306
  <a name="l00281"></a>00281 }
307
307
  <a name="l00282"></a>00282
308
- <a name="l00283"></a>00283 <span class="keywordtype">void</span> detach() {
309
- <a name="l00284"></a>00284 owner = <span class="keyword">false</span>;
308
+ <a name="l00283"></a>00283 <span class="keywordtype">string</span> getPath()<span class="keyword"> const </span>{
309
+ <a name="l00284"></a>00284 <span class="keywordflow">return</span> path;
310
310
  <a name="l00285"></a>00285 }
311
311
  <a name="l00286"></a>00286
312
- <a name="l00287"></a>00287 GenerationPtr newGeneration(<span class="keywordtype">bool</span> userSwitching, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;defaultUser,
313
- <a name="l00288"></a>00288 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;defaultGroup, uid_t webServerWorkerUid,
314
- <a name="l00289"></a>00289 gid_t webServerWorkerGid)
315
- <a name="l00290"></a>00290 {
316
- <a name="l00291"></a>00291 GenerationPtr newestGeneration = getNewestGeneration();
317
- <a name="l00292"></a>00292 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> newNumber;
318
- <a name="l00293"></a>00293 <span class="keywordflow">if</span> (newestGeneration != NULL) {
319
- <a name="l00294"></a>00294 newNumber = newestGeneration-&gt;getNumber() + 1;
320
- <a name="l00295"></a>00295 } <span class="keywordflow">else</span> {
321
- <a name="l00296"></a>00296 newNumber = 0;
322
- <a name="l00297"></a>00297 }
323
- <a name="l00298"></a>00298
324
- <a name="l00299"></a>00299 GenerationPtr generation(<span class="keyword">new</span> Generation(path, newNumber));
325
- <a name="l00300"></a>00300 generation-&gt;create(userSwitching, defaultUser, defaultGroup,
326
- <a name="l00301"></a>00301 webServerWorkerUid, webServerWorkerGid);
327
- <a name="l00302"></a>00302 <span class="keywordflow">return</span> generation;
328
- <a name="l00303"></a>00303 }
329
- <a name="l00304"></a>00304
330
- <a name="l00305"></a>00305 GenerationPtr getGeneration(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> number)<span class="keyword"> const </span>{
331
- <a name="l00306"></a>00306 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> Generation(path, number));
312
+ <a name="l00287"></a>00287 <span class="keywordtype">void</span> detach() {
313
+ <a name="l00288"></a>00288 owner = <span class="keyword">false</span>;
314
+ <a name="l00289"></a>00289 }
315
+ <a name="l00290"></a>00290
316
+ <a name="l00291"></a>00291 GenerationPtr newGeneration(<span class="keywordtype">bool</span> userSwitching, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;defaultUser,
317
+ <a name="l00292"></a>00292 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;defaultGroup, uid_t webServerWorkerUid,
318
+ <a name="l00293"></a>00293 gid_t webServerWorkerGid)
319
+ <a name="l00294"></a>00294 {
320
+ <a name="l00295"></a>00295 GenerationPtr newestGeneration = getNewestGeneration();
321
+ <a name="l00296"></a>00296 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> newNumber;
322
+ <a name="l00297"></a>00297 <span class="keywordflow">if</span> (newestGeneration != NULL) {
323
+ <a name="l00298"></a>00298 newNumber = newestGeneration-&gt;getNumber() + 1;
324
+ <a name="l00299"></a>00299 } <span class="keywordflow">else</span> {
325
+ <a name="l00300"></a>00300 newNumber = 0;
326
+ <a name="l00301"></a>00301 }
327
+ <a name="l00302"></a>00302
328
+ <a name="l00303"></a>00303 GenerationPtr generation(<span class="keyword">new</span> Generation(path, newNumber));
329
+ <a name="l00304"></a>00304 generation-&gt;create(userSwitching, defaultUser, defaultGroup,
330
+ <a name="l00305"></a>00305 webServerWorkerUid, webServerWorkerGid);
331
+ <a name="l00306"></a>00306 <span class="keywordflow">return</span> generation;
332
332
  <a name="l00307"></a>00307 }
333
333
  <a name="l00308"></a>00308
334
- <a name="l00309"></a>00309 GenerationPtr getNewestGeneration()<span class="keyword"> const </span>{
335
- <a name="l00310"></a>00310 DIR *dir = opendir(path.c_str());
336
- <a name="l00311"></a>00311 <span class="keyword">struct </span>dirent *entry;
337
- <a name="l00312"></a>00312 <span class="keywordtype">int</span> result = -1;
338
- <a name="l00313"></a>00313
339
- <a name="l00314"></a>00314 <span class="keywordflow">if</span> (dir == NULL) {
340
- <a name="l00315"></a>00315 <span class="keywordtype">int</span> e = errno;
341
- <a name="l00316"></a>00316 <span class="keywordflow">throw</span> FileSystemException(<span class="stringliteral">&quot;Cannot open directory &quot;</span> + path,
342
- <a name="l00317"></a>00317 e, path);
343
- <a name="l00318"></a>00318 }
344
- <a name="l00319"></a>00319 <span class="keywordflow">while</span> ((entry = readdir(dir)) != NULL) {
345
- <a name="l00320"></a>00320 <span class="keywordflow">if</span> (isDirectory(path, entry)
346
- <a name="l00321"></a>00321 &amp;&amp; strncmp(entry-&gt;d_name, <span class="stringliteral">&quot;generation-&quot;</span>, <span class="keyword">sizeof</span>(<span class="stringliteral">&quot;generation-&quot;</span>) - 1) == 0) {
347
- <a name="l00322"></a>00322 <span class="keyword">const</span> <span class="keywordtype">char</span> *numberString = entry-&gt;d_name + <span class="keyword">sizeof</span>(<span class="stringliteral">&quot;generation-&quot;</span>) - 1;
348
- <a name="l00323"></a>00323 <span class="keywordtype">int</span> number = atoi(numberString);
349
- <a name="l00324"></a>00324 <span class="keywordflow">if</span> (number &gt;= 0 &amp;&amp; number &gt; result) {
350
- <a name="l00325"></a>00325 result = number;
351
- <a name="l00326"></a>00326 }
352
- <a name="l00327"></a>00327 }
353
- <a name="l00328"></a>00328 }
354
- <a name="l00329"></a>00329 closedir(dir);
355
- <a name="l00330"></a>00330
356
- <a name="l00331"></a>00331 <span class="keywordflow">if</span> (result == -1) {
357
- <a name="l00332"></a>00332 <span class="keywordflow">return</span> GenerationPtr();
358
- <a name="l00333"></a>00333 } <span class="keywordflow">else</span> {
359
- <a name="l00334"></a>00334 <span class="keywordflow">return</span> getGeneration(result);
360
- <a name="l00335"></a>00335 }
361
- <a name="l00336"></a>00336 }
362
- <a name="l00337"></a>00337 };
363
- <a name="l00338"></a>00338
364
- <a name="l00339"></a>00339 <span class="keyword">typedef</span> shared_ptr&lt;ServerInstanceDir&gt; ServerInstanceDirPtr;
365
- <a name="l00340"></a>00340
366
- <a name="l00341"></a>00341 } <span class="comment">// namespace Passenger</span>
334
+ <a name="l00309"></a>00309 GenerationPtr getGeneration(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> number)<span class="keyword"> const </span>{
335
+ <a name="l00310"></a>00310 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> Generation(path, number));
336
+ <a name="l00311"></a>00311 }
337
+ <a name="l00312"></a>00312
338
+ <a name="l00313"></a>00313 GenerationPtr getNewestGeneration()<span class="keyword"> const </span>{
339
+ <a name="l00314"></a>00314 DIR *dir = opendir(path.c_str());
340
+ <a name="l00315"></a>00315 <span class="keyword">struct </span>dirent *entry;
341
+ <a name="l00316"></a>00316 <span class="keywordtype">int</span> result = -1;
342
+ <a name="l00317"></a>00317
343
+ <a name="l00318"></a>00318 <span class="keywordflow">if</span> (dir == NULL) {
344
+ <a name="l00319"></a>00319 <span class="keywordtype">int</span> e = errno;
345
+ <a name="l00320"></a>00320 <span class="keywordflow">throw</span> FileSystemException(<span class="stringliteral">&quot;Cannot open directory &quot;</span> + path,
346
+ <a name="l00321"></a>00321 e, path);
347
+ <a name="l00322"></a>00322 }
348
+ <a name="l00323"></a>00323 <span class="keywordflow">while</span> ((entry = readdir(dir)) != NULL) {
349
+ <a name="l00324"></a>00324 <span class="keywordflow">if</span> (isDirectory(path, entry)
350
+ <a name="l00325"></a>00325 &amp;&amp; strncmp(entry-&gt;d_name, <span class="stringliteral">&quot;generation-&quot;</span>, <span class="keyword">sizeof</span>(<span class="stringliteral">&quot;generation-&quot;</span>) - 1) == 0) {
351
+ <a name="l00326"></a>00326 <span class="keyword">const</span> <span class="keywordtype">char</span> *numberString = entry-&gt;d_name + <span class="keyword">sizeof</span>(<span class="stringliteral">&quot;generation-&quot;</span>) - 1;
352
+ <a name="l00327"></a>00327 <span class="keywordtype">int</span> number = atoi(numberString);
353
+ <a name="l00328"></a>00328 <span class="keywordflow">if</span> (number &gt;= 0 &amp;&amp; number &gt; result) {
354
+ <a name="l00329"></a>00329 result = number;
355
+ <a name="l00330"></a>00330 }
356
+ <a name="l00331"></a>00331 }
357
+ <a name="l00332"></a>00332 }
358
+ <a name="l00333"></a>00333 closedir(dir);
359
+ <a name="l00334"></a>00334
360
+ <a name="l00335"></a>00335 <span class="keywordflow">if</span> (result == -1) {
361
+ <a name="l00336"></a>00336 <span class="keywordflow">return</span> GenerationPtr();
362
+ <a name="l00337"></a>00337 } <span class="keywordflow">else</span> {
363
+ <a name="l00338"></a>00338 <span class="keywordflow">return</span> getGeneration(result);
364
+ <a name="l00339"></a>00339 }
365
+ <a name="l00340"></a>00340 }
366
+ <a name="l00341"></a>00341 };
367
367
  <a name="l00342"></a>00342
368
- <a name="l00343"></a>00343 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_SERVER_INSTANCE_DIR_H_ */</span>
368
+ <a name="l00343"></a>00343 <span class="keyword">typedef</span> shared_ptr&lt;ServerInstanceDir&gt; ServerInstanceDirPtr;
369
+ <a name="l00344"></a>00344
370
+ <a name="l00345"></a>00345 } <span class="comment">// namespace Passenger</span>
371
+ <a name="l00346"></a>00346
372
+ <a name="l00347"></a>00347 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_SERVER_INSTANCE_DIR_H_ */</span>
369
373
  </pre></div></div>
370
374
  <hr size="1"/><address style="text-align: right;"><small>Generated by&nbsp;
371
375
  <a href="http://www.doxygen.org/index.html">
@@ -228,7 +228,7 @@
228
228
  <a name="l00203"></a>00203 <span class="stringliteral">&quot;already been closed or discarded.&quot;</span>);
229
229
  <a name="l00204"></a>00204 }
230
230
  <a name="l00205"></a>00205 <span class="keywordflow">try</span> {
231
- <a name="l00206"></a>00206 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a>(stream).writeRaw(block, size);
231
+ <a name="l00206"></a>00206 writeExact(stream, block, size);
232
232
  <a name="l00207"></a>00207 } <span class="keywordflow">catch</span> (<a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> &amp;e) {
233
233
  <a name="l00208"></a>00208 e.setBriefMessage(<span class="stringliteral">&quot;An error occured while sending the &quot;</span>
234
234
  <a name="l00209"></a>00209 <span class="stringliteral">&quot;request body to the request handler&quot;</span>);
@@ -81,200 +81,200 @@
81
81
  <a name="l00056"></a>00056 <span class="preprocessor">#include &quot;Logging.h&quot;</span>
82
82
  <a name="l00057"></a>00057 <span class="preprocessor">#include &quot;Utils/Base64.h&quot;</span>
83
83
  <a name="l00058"></a>00058 <span class="preprocessor">#include &quot;Utils/SystemTime.h&quot;</span>
84
- <a name="l00059"></a>00059
85
- <a name="l00060"></a>00060 <span class="keyword">namespace </span>Passenger {
86
- <a name="l00061"></a>00061
87
- <a name="l00062"></a>00062 <span class="keyword">using namespace </span>std;
88
- <a name="l00063"></a>00063 <span class="keyword">using namespace </span>boost;
89
- <a name="l00064"></a>00064 <span class="keyword">using namespace </span>oxt;
90
- <a name="l00065"></a>00065 <span class="comment"></span>
91
- <a name="l00066"></a>00066 <span class="comment">/**</span>
92
- <a name="l00067"></a>00067 <span class="comment"> * An AbstractSpawnManager implementation.</span>
93
- <a name="l00068"></a>00068 <span class="comment"> *</span>
94
- <a name="l00069"></a>00069 <span class="comment"> * Internally, this class makes use of a spawn server, which is written in Ruby. This server</span>
95
- <a name="l00070"></a>00070 <span class="comment"> * is automatically started when a SpawnManager instance is created, and automatically</span>
96
- <a name="l00071"></a>00071 <span class="comment"> * shutdown when that instance is destroyed. The existance of the spawn server is almost</span>
97
- <a name="l00072"></a>00072 <span class="comment"> * totally transparent to users of this class. Spawn requests are sent to the server,</span>
98
- <a name="l00073"></a>00073 <span class="comment"> * and details about the spawned process is returned.</span>
99
- <a name="l00074"></a>00074 <span class="comment"> *</span>
100
- <a name="l00075"></a>00075 <span class="comment"> * If the spawn server dies during the middle of an operation, it will be restarted.</span>
101
- <a name="l00076"></a>00076 <span class="comment"> * See spawn() for full details.</span>
102
- <a name="l00077"></a>00077 <span class="comment"> *</span>
103
- <a name="l00078"></a>00078 <span class="comment"> * The communication channel with the server is anonymous, i.e. no other processes</span>
104
- <a name="l00079"></a>00079 <span class="comment"> * can access the communication channel, so communication is guaranteed to be safe</span>
105
- <a name="l00080"></a>00080 <span class="comment"> * (unless, of course, if the spawn server itself is a trojan).</span>
106
- <a name="l00081"></a>00081 <span class="comment"> *</span>
107
- <a name="l00082"></a><a class="code" href="classPassenger_1_1SpawnManager.html">00082</a> <span class="comment"> * The server will try to keep the spawning time as small as possible, by keeping</span>
108
- <a name="l00083"></a>00083 <span class="comment"> * corresponding Ruby on Rails frameworks and application code in memory. So the second</span>
109
- <a name="l00084"></a>00084 <span class="comment"> * time a process of the same application is spawned, the spawn time is significantly</span>
110
- <a name="l00085"></a>00085 <span class="comment"> * lower than the first time. Nevertheless, spawning is a relatively expensive operation</span>
111
- <a name="l00086"></a>00086 <span class="comment"> * (compared to the processing of a typical HTTP request/response), and so should be</span>
112
- <a name="l00087"></a>00087 <span class="comment"> * avoided whenever possible.</span>
113
- <a name="l00088"></a>00088 <span class="comment"> *</span>
114
- <a name="l00089"></a>00089 <span class="comment"> * See the documentation of the spawn server for full implementation details.</span>
115
- <a name="l00090"></a>00090 <span class="comment"> *</span>
116
- <a name="l00091"></a>00091 <span class="comment"> * @ingroup Support</span>
117
- <a name="l00092"></a>00092 <span class="comment"> */</span>
118
- <a name="l00093"></a>00093 <span class="keyword">class </span><a class="code" href="classPassenger_1_1SpawnManager.html" title="An AbstractSpawnManager implementation.">SpawnManager</a>: <span class="keyword">public</span> <a class="code" href="classPassenger_1_1AbstractSpawnManager.html" title="Spawning of application processes.">AbstractSpawnManager</a> {
119
- <a name="l00094"></a>00094 <span class="keyword">private</span>:
120
- <a name="l00095"></a>00095 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> SERVER_SOCKET_FD = 3;
121
- <a name="l00096"></a>00096 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> OWNER_SOCKET_FD = 4;
122
- <a name="l00097"></a>00097 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> HIGHEST_FD = OWNER_SOCKET_FD;
123
- <a name="l00098"></a>00098
124
- <a name="l00099"></a>00099 <span class="keywordtype">string</span> spawnServerCommand;
125
- <a name="l00100"></a>00100 ServerInstanceDir::GenerationPtr generation;
126
- <a name="l00101"></a>00101 AccountsDatabasePtr accountsDatabase;
127
- <a name="l00102"></a>00102 <span class="keywordtype">string</span> rubyCommand;
128
- <a name="l00103"></a>00103 AnalyticsLoggerPtr analyticsLogger;
129
- <a name="l00104"></a>00104 <span class="keywordtype">int</span> logLevel;
130
- <a name="l00105"></a>00105 <span class="keywordtype">string</span> debugLogFile;
131
- <a name="l00106"></a>00106
132
- <a name="l00107"></a>00107 boost::mutex lock;
133
- <a name="l00108"></a>00108 <a class="code" href="classPassenger_1_1RandomGenerator.html" title="A random data generator.">RandomGenerator</a> random;
134
- <a name="l00109"></a>00109
135
- <a name="l00110"></a>00110 pid_t pid;
136
- <a name="l00111"></a>00111 <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> ownerSocket;
137
- <a name="l00112"></a>00112 <span class="keywordtype">string</span> socketFilename;
138
- <a name="l00113"></a>00113 <span class="keywordtype">string</span> socketPassword;
139
- <a name="l00114"></a>00114 <span class="keywordtype">bool</span> serverNeedsRestart;
140
- <a name="l00115"></a>00115
141
- <a name="l00116"></a>00116 <span class="keyword">static</span> <span class="keywordtype">void</span> deleteAccount(AccountsDatabasePtr accountsDatabase, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;username) {
142
- <a name="l00117"></a>00117 accountsDatabase-&gt;remove(username);
143
- <a name="l00118"></a>00118 }
144
- <a name="l00119"></a>00119 <span class="comment"></span>
145
- <a name="l00120"></a>00120 <span class="comment"> /**</span>
146
- <a name="l00121"></a>00121 <span class="comment"> * Restarts the spawn server.</span>
147
- <a name="l00122"></a>00122 <span class="comment"> *</span>
148
- <a name="l00123"></a>00123 <span class="comment"> * @pre System call interruption is disabled.</span>
149
- <a name="l00124"></a>00124 <span class="comment"> * @throws RuntimeException An error occurred while creating a Unix server socket.</span>
150
- <a name="l00125"></a>00125 <span class="comment"> * @throws SystemException An error occured while trying to setup the spawn server.</span>
151
- <a name="l00126"></a>00126 <span class="comment"> * @throws IOException An error occurred while generating random data.</span>
152
- <a name="l00127"></a>00127 <span class="comment"> */</span>
153
- <a name="l00128"></a>00128 <span class="keywordtype">void</span> restartServer() {
154
- <a name="l00129"></a>00129 TRACE_POINT();
155
- <a name="l00130"></a>00130 <span class="keywordflow">if</span> (pid != 0) {
156
- <a name="l00131"></a>00131 UPDATE_TRACE_POINT();
157
- <a name="l00132"></a>00132 ownerSocket.<a class="code" href="classPassenger_1_1FileDescriptor.html#ad7c1a99531181878cbab74a7400c5432" title="Close the underlying file descriptor.">close</a>();
158
- <a name="l00133"></a>00133
159
- <a name="l00134"></a>00134 <span class="comment">/* Wait at most 5 seconds for the spawn server to exit.</span>
160
- <a name="l00135"></a>00135 <span class="comment"> * If that doesn&#39;t work, kill it, then wait at most 5 seconds</span>
161
- <a name="l00136"></a>00136 <span class="comment"> * for it to exit.</span>
162
- <a name="l00137"></a>00137 <span class="comment"> */</span>
163
- <a name="l00138"></a>00138 time_t begin = syscalls::time(NULL);
164
- <a name="l00139"></a>00139 <span class="keywordtype">bool</span> done = <span class="keyword">false</span>;
165
- <a name="l00140"></a>00140 <span class="keywordflow">while</span> (!done &amp;&amp; syscalls::time(NULL) - begin &lt; 5) {
166
- <a name="l00141"></a>00141 <span class="keywordflow">if</span> (syscalls::waitpid(pid, NULL, WNOHANG) &gt; 0) {
167
- <a name="l00142"></a>00142 done = <span class="keyword">true</span>;
168
- <a name="l00143"></a>00143 } <span class="keywordflow">else</span> {
169
- <a name="l00144"></a>00144 syscalls::usleep(100000);
170
- <a name="l00145"></a>00145 }
171
- <a name="l00146"></a>00146 }
172
- <a name="l00147"></a>00147 UPDATE_TRACE_POINT();
173
- <a name="l00148"></a>00148 <span class="keywordflow">if</span> (!done) {
174
- <a name="l00149"></a>00149 UPDATE_TRACE_POINT();
175
- <a name="l00150"></a>00150 P_TRACE(2, <span class="stringliteral">&quot;Spawn server did not exit in time, killing it...&quot;</span>);
176
- <a name="l00151"></a>00151 syscalls::kill(pid, SIGTERM);
177
- <a name="l00152"></a>00152 begin = syscalls::time(NULL);
178
- <a name="l00153"></a>00153 <span class="keywordflow">while</span> (syscalls::time(NULL) - begin &lt; 5) {
179
- <a name="l00154"></a>00154 <span class="keywordflow">if</span> (syscalls::waitpid(pid, NULL, WNOHANG) &gt; 0) {
180
- <a name="l00155"></a>00155 <span class="keywordflow">break</span>;
181
- <a name="l00156"></a>00156 } <span class="keywordflow">else</span> {
182
- <a name="l00157"></a>00157 syscalls::usleep(100000);
183
- <a name="l00158"></a>00158 }
184
- <a name="l00159"></a>00159 }
185
- <a name="l00160"></a>00160 }
186
- <a name="l00161"></a>00161 pid = 0;
187
- <a name="l00162"></a>00162 }
188
- <a name="l00163"></a>00163
189
- <a name="l00164"></a>00164 <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> serverSocket;
190
- <a name="l00165"></a>00165 <span class="keywordtype">string</span> socketFilename;
191
- <a name="l00166"></a>00166 <span class="keywordtype">string</span> socketPassword;
192
- <a name="l00167"></a>00167 <span class="keywordtype">int</span> ret, fds[2];
193
- <a name="l00168"></a>00168
194
- <a name="l00169"></a>00169 UPDATE_TRACE_POINT();
195
- <a name="l00170"></a>00170 socketFilename = generation-&gt;getPath() + <span class="stringliteral">&quot;/spawn-server/socket.&quot;</span> +
196
- <a name="l00171"></a>00171 toString(getpid()) + <span class="stringliteral">&quot;.&quot;</span> +
197
- <a name="l00172"></a>00172 pointerToIntString(<span class="keyword">this</span>);
198
- <a name="l00173"></a>00173 socketPassword = Base64::encode(random.generateByteString(32));
199
- <a name="l00174"></a>00174 serverSocket = createUnixServer(socketFilename.c_str());
200
- <a name="l00175"></a>00175 <span class="keywordflow">do</span> {
201
- <a name="l00176"></a>00176 ret = chmod(socketFilename.c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
202
- <a name="l00177"></a>00177 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
203
- <a name="l00178"></a>00178 <span class="keywordflow">if</span> (ret == -1) {
204
- <a name="l00179"></a>00179 <span class="keywordtype">int</span> e = errno;
205
- <a name="l00180"></a>00180 syscalls::unlink(socketFilename.c_str());
206
- <a name="l00181"></a>00181 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1FileSystemException.html" title="A filesystem error, as returned by the operating system.">FileSystemException</a>(<span class="stringliteral">&quot;Cannot set permissions on &#39;&quot;</span> + socketFilename + <span class="stringliteral">&quot;&#39;&quot;</span>,
207
- <a name="l00182"></a>00182 e, socketFilename);
208
- <a name="l00183"></a>00183 }
209
- <a name="l00184"></a>00184
210
- <a name="l00185"></a>00185 <span class="keywordflow">if</span> (syscalls::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
211
- <a name="l00186"></a>00186 <span class="keywordtype">int</span> e = errno;
212
- <a name="l00187"></a>00187 syscalls::unlink(socketFilename.c_str());
213
- <a name="l00188"></a>00188 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">&quot;Cannot create a Unix socket&quot;</span>, e);
214
- <a name="l00189"></a>00189 }
215
- <a name="l00190"></a>00190
216
- <a name="l00191"></a>00191 UPDATE_TRACE_POINT();
217
- <a name="l00192"></a>00192 pid = syscalls::fork();
218
- <a name="l00193"></a>00193 <span class="keywordflow">if</span> (pid == 0) {
219
- <a name="l00194"></a>00194 dup2(serverSocket, HIGHEST_FD + 1);
220
- <a name="l00195"></a>00195 dup2(fds[1], HIGHEST_FD + 2);
221
- <a name="l00196"></a>00196 dup2(HIGHEST_FD + 1, SERVER_SOCKET_FD);
222
- <a name="l00197"></a>00197 dup2(HIGHEST_FD + 2, OWNER_SOCKET_FD);
223
- <a name="l00198"></a>00198
224
- <a name="l00199"></a>00199 <span class="comment">// Close all unnecessary file descriptors</span>
225
- <a name="l00200"></a>00200 <span class="keywordflow">for</span> (<span class="keywordtype">long</span> i = sysconf(_SC_OPEN_MAX) - 1; i &gt; HIGHEST_FD; i--) {
226
- <a name="l00201"></a>00201 close(i);
227
- <a name="l00202"></a>00202 }
228
- <a name="l00203"></a>00203
229
- <a name="l00204"></a>00204 execlp(rubyCommand.c_str(),
230
- <a name="l00205"></a>00205 rubyCommand.c_str(),
231
- <a name="l00206"></a>00206 spawnServerCommand.c_str(),
232
- <a name="l00207"></a>00207 <span class="comment">/* The spawn server changes the process names of the subservers</span>
233
- <a name="l00208"></a>00208 <span class="comment"> * that it starts, for better usability. However, the process name length</span>
234
- <a name="l00209"></a>00209 <span class="comment"> * (as shown by ps) is limited. Here, we try to expand that limit by</span>
235
- <a name="l00210"></a>00210 <span class="comment"> * deliberately passing a useless whitespace string to the spawn server.</span>
236
- <a name="l00211"></a>00211 <span class="comment"> * This argument is ignored by the spawn server. This works on some</span>
237
- <a name="l00212"></a>00212 <span class="comment"> * systems, such as Ubuntu Linux.</span>
238
- <a name="l00213"></a>00213 <span class="comment"> */</span>
239
- <a name="l00214"></a>00214 <span class="stringliteral">&quot; &quot;</span>,
240
- <a name="l00215"></a>00215 (<span class="keywordtype">char</span> *) NULL);
241
- <a name="l00216"></a>00216 <span class="keywordtype">int</span> e = errno;
242
- <a name="l00217"></a>00217 fprintf(stderr, <span class="stringliteral">&quot;*** Passenger ERROR (%s:%d):\n&quot;</span>
243
- <a name="l00218"></a>00218 <span class="stringliteral">&quot;Could not start the spawn server: %s: %s (%d)\n&quot;</span>,
244
- <a name="l00219"></a>00219 __FILE__, __LINE__,
245
- <a name="l00220"></a>00220 rubyCommand.c_str(), strerror(e), e);
246
- <a name="l00221"></a>00221 fflush(stderr);
247
- <a name="l00222"></a>00222 _exit(1);
248
- <a name="l00223"></a>00223 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (pid == -1) {
249
- <a name="l00224"></a>00224 <span class="keywordtype">int</span> e = errno;
250
- <a name="l00225"></a>00225 syscalls::unlink(socketFilename.c_str());
251
- <a name="l00226"></a>00226 syscalls::close(fds[0]);
252
- <a name="l00227"></a>00227 syscalls::close(fds[1]);
253
- <a name="l00228"></a>00228 pid = 0;
254
- <a name="l00229"></a>00229 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">&quot;Unable to fork a process&quot;</span>, e);
255
- <a name="l00230"></a>00230 } <span class="keywordflow">else</span> {
256
- <a name="l00231"></a>00231 <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> ownerSocket = fds[0];
257
- <a name="l00232"></a>00232 syscalls::close(fds[1]);
258
- <a name="l00233"></a>00233 serverSocket.close();
259
- <a name="l00234"></a>00234
260
- <a name="l00235"></a>00235 <span class="comment">// Pass arguments to spawn server.</span>
261
- <a name="l00236"></a>00236 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> ownerSocketChannel(ownerSocket);
262
- <a name="l00237"></a>00237 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(socketFilename + <span class="stringliteral">&quot;\n&quot;</span>);
263
- <a name="l00238"></a>00238 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(socketPassword + <span class="stringliteral">&quot;\n&quot;</span>);
264
- <a name="l00239"></a>00239 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(generation-&gt;getPath() + <span class="stringliteral">&quot;\n&quot;</span>);
84
+ <a name="l00059"></a>00059 <span class="preprocessor">#include &quot;Utils/IOUtils.h&quot;</span>
85
+ <a name="l00060"></a>00060
86
+ <a name="l00061"></a>00061 <span class="keyword">namespace </span>Passenger {
87
+ <a name="l00062"></a>00062
88
+ <a name="l00063"></a>00063 <span class="keyword">using namespace </span>std;
89
+ <a name="l00064"></a>00064 <span class="keyword">using namespace </span>boost;
90
+ <a name="l00065"></a>00065 <span class="keyword">using namespace </span>oxt;
91
+ <a name="l00066"></a>00066 <span class="comment"></span>
92
+ <a name="l00067"></a>00067 <span class="comment">/**</span>
93
+ <a name="l00068"></a>00068 <span class="comment"> * An AbstractSpawnManager implementation.</span>
94
+ <a name="l00069"></a>00069 <span class="comment"> *</span>
95
+ <a name="l00070"></a>00070 <span class="comment"> * Internally, this class makes use of a spawn server, which is written in Ruby. This server</span>
96
+ <a name="l00071"></a>00071 <span class="comment"> * is automatically started when a SpawnManager instance is created, and automatically</span>
97
+ <a name="l00072"></a>00072 <span class="comment"> * shutdown when that instance is destroyed. The existance of the spawn server is almost</span>
98
+ <a name="l00073"></a>00073 <span class="comment"> * totally transparent to users of this class. Spawn requests are sent to the server,</span>
99
+ <a name="l00074"></a>00074 <span class="comment"> * and details about the spawned process is returned.</span>
100
+ <a name="l00075"></a>00075 <span class="comment"> *</span>
101
+ <a name="l00076"></a>00076 <span class="comment"> * If the spawn server dies during the middle of an operation, it will be restarted.</span>
102
+ <a name="l00077"></a>00077 <span class="comment"> * See spawn() for full details.</span>
103
+ <a name="l00078"></a>00078 <span class="comment"> *</span>
104
+ <a name="l00079"></a>00079 <span class="comment"> * The communication channel with the server is anonymous, i.e. no other processes</span>
105
+ <a name="l00080"></a>00080 <span class="comment"> * can access the communication channel, so communication is guaranteed to be safe</span>
106
+ <a name="l00081"></a>00081 <span class="comment"> * (unless, of course, if the spawn server itself is a trojan).</span>
107
+ <a name="l00082"></a><a class="code" href="classPassenger_1_1SpawnManager.html">00082</a> <span class="comment"> *</span>
108
+ <a name="l00083"></a>00083 <span class="comment"> * The server will try to keep the spawning time as small as possible, by keeping</span>
109
+ <a name="l00084"></a>00084 <span class="comment"> * corresponding Ruby on Rails frameworks and application code in memory. So the second</span>
110
+ <a name="l00085"></a>00085 <span class="comment"> * time a process of the same application is spawned, the spawn time is significantly</span>
111
+ <a name="l00086"></a>00086 <span class="comment"> * lower than the first time. Nevertheless, spawning is a relatively expensive operation</span>
112
+ <a name="l00087"></a>00087 <span class="comment"> * (compared to the processing of a typical HTTP request/response), and so should be</span>
113
+ <a name="l00088"></a>00088 <span class="comment"> * avoided whenever possible.</span>
114
+ <a name="l00089"></a>00089 <span class="comment"> *</span>
115
+ <a name="l00090"></a>00090 <span class="comment"> * See the documentation of the spawn server for full implementation details.</span>
116
+ <a name="l00091"></a>00091 <span class="comment"> *</span>
117
+ <a name="l00092"></a>00092 <span class="comment"> * @ingroup Support</span>
118
+ <a name="l00093"></a>00093 <span class="comment"> */</span>
119
+ <a name="l00094"></a>00094 <span class="keyword">class </span><a class="code" href="classPassenger_1_1SpawnManager.html" title="An AbstractSpawnManager implementation.">SpawnManager</a>: <span class="keyword">public</span> <a class="code" href="classPassenger_1_1AbstractSpawnManager.html" title="Spawning of application processes.">AbstractSpawnManager</a> {
120
+ <a name="l00095"></a>00095 <span class="keyword">private</span>:
121
+ <a name="l00096"></a>00096 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> SERVER_SOCKET_FD = 3;
122
+ <a name="l00097"></a>00097 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> OWNER_SOCKET_FD = 4;
123
+ <a name="l00098"></a>00098 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> HIGHEST_FD = OWNER_SOCKET_FD;
124
+ <a name="l00099"></a>00099
125
+ <a name="l00100"></a>00100 <span class="keywordtype">string</span> spawnServerCommand;
126
+ <a name="l00101"></a>00101 ServerInstanceDir::GenerationPtr generation;
127
+ <a name="l00102"></a>00102 AccountsDatabasePtr accountsDatabase;
128
+ <a name="l00103"></a>00103 <span class="keywordtype">string</span> rubyCommand;
129
+ <a name="l00104"></a>00104 AnalyticsLoggerPtr analyticsLogger;
130
+ <a name="l00105"></a>00105 <span class="keywordtype">int</span> logLevel;
131
+ <a name="l00106"></a>00106 <span class="keywordtype">string</span> debugLogFile;
132
+ <a name="l00107"></a>00107
133
+ <a name="l00108"></a>00108 boost::mutex lock;
134
+ <a name="l00109"></a>00109 <a class="code" href="classPassenger_1_1RandomGenerator.html" title="A random data generator.">RandomGenerator</a> random;
135
+ <a name="l00110"></a>00110
136
+ <a name="l00111"></a>00111 pid_t pid;
137
+ <a name="l00112"></a>00112 <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> ownerSocket;
138
+ <a name="l00113"></a>00113 <span class="keywordtype">string</span> socketFilename;
139
+ <a name="l00114"></a>00114 <span class="keywordtype">string</span> socketPassword;
140
+ <a name="l00115"></a>00115 <span class="keywordtype">bool</span> serverNeedsRestart;
141
+ <a name="l00116"></a>00116
142
+ <a name="l00117"></a>00117 <span class="keyword">static</span> <span class="keywordtype">void</span> deleteAccount(AccountsDatabasePtr accountsDatabase, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;username) {
143
+ <a name="l00118"></a>00118 accountsDatabase-&gt;remove(username);
144
+ <a name="l00119"></a>00119 }
145
+ <a name="l00120"></a>00120 <span class="comment"></span>
146
+ <a name="l00121"></a>00121 <span class="comment"> /**</span>
147
+ <a name="l00122"></a>00122 <span class="comment"> * Restarts the spawn server.</span>
148
+ <a name="l00123"></a>00123 <span class="comment"> *</span>
149
+ <a name="l00124"></a>00124 <span class="comment"> * @pre System call interruption is disabled.</span>
150
+ <a name="l00125"></a>00125 <span class="comment"> * @throws RuntimeException An error occurred while creating a Unix server socket.</span>
151
+ <a name="l00126"></a>00126 <span class="comment"> * @throws SystemException An error occured while trying to setup the spawn server.</span>
152
+ <a name="l00127"></a>00127 <span class="comment"> * @throws IOException An error occurred while generating random data.</span>
153
+ <a name="l00128"></a>00128 <span class="comment"> */</span>
154
+ <a name="l00129"></a>00129 <span class="keywordtype">void</span> restartServer() {
155
+ <a name="l00130"></a>00130 TRACE_POINT();
156
+ <a name="l00131"></a>00131 <span class="keywordflow">if</span> (pid != 0) {
157
+ <a name="l00132"></a>00132 UPDATE_TRACE_POINT();
158
+ <a name="l00133"></a>00133 ownerSocket.<a class="code" href="classPassenger_1_1FileDescriptor.html#a02062f3cfb689b32781e11114c0abe5b" title="Close the underlying file descriptor.">close</a>();
159
+ <a name="l00134"></a>00134
160
+ <a name="l00135"></a>00135 <span class="comment">/* Wait at most 5 seconds for the spawn server to exit.</span>
161
+ <a name="l00136"></a>00136 <span class="comment"> * If that doesn&#39;t work, kill it, then wait at most 5 seconds</span>
162
+ <a name="l00137"></a>00137 <span class="comment"> * for it to exit.</span>
163
+ <a name="l00138"></a>00138 <span class="comment"> */</span>
164
+ <a name="l00139"></a>00139 time_t begin = syscalls::time(NULL);
165
+ <a name="l00140"></a>00140 <span class="keywordtype">bool</span> done = <span class="keyword">false</span>;
166
+ <a name="l00141"></a>00141 <span class="keywordflow">while</span> (!done &amp;&amp; syscalls::time(NULL) - begin &lt; 5) {
167
+ <a name="l00142"></a>00142 <span class="keywordflow">if</span> (syscalls::waitpid(pid, NULL, WNOHANG) &gt; 0) {
168
+ <a name="l00143"></a>00143 done = <span class="keyword">true</span>;
169
+ <a name="l00144"></a>00144 } <span class="keywordflow">else</span> {
170
+ <a name="l00145"></a>00145 syscalls::usleep(100000);
171
+ <a name="l00146"></a>00146 }
172
+ <a name="l00147"></a>00147 }
173
+ <a name="l00148"></a>00148 UPDATE_TRACE_POINT();
174
+ <a name="l00149"></a>00149 <span class="keywordflow">if</span> (!done) {
175
+ <a name="l00150"></a>00150 UPDATE_TRACE_POINT();
176
+ <a name="l00151"></a>00151 P_TRACE(2, <span class="stringliteral">&quot;Spawn server did not exit in time, killing it...&quot;</span>);
177
+ <a name="l00152"></a>00152 syscalls::kill(pid, SIGTERM);
178
+ <a name="l00153"></a>00153 begin = syscalls::time(NULL);
179
+ <a name="l00154"></a>00154 <span class="keywordflow">while</span> (syscalls::time(NULL) - begin &lt; 5) {
180
+ <a name="l00155"></a>00155 <span class="keywordflow">if</span> (syscalls::waitpid(pid, NULL, WNOHANG) &gt; 0) {
181
+ <a name="l00156"></a>00156 <span class="keywordflow">break</span>;
182
+ <a name="l00157"></a>00157 } <span class="keywordflow">else</span> {
183
+ <a name="l00158"></a>00158 syscalls::usleep(100000);
184
+ <a name="l00159"></a>00159 }
185
+ <a name="l00160"></a>00160 }
186
+ <a name="l00161"></a>00161 }
187
+ <a name="l00162"></a>00162 pid = 0;
188
+ <a name="l00163"></a>00163 }
189
+ <a name="l00164"></a>00164
190
+ <a name="l00165"></a>00165 <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> serverSocket;
191
+ <a name="l00166"></a>00166 <span class="keywordtype">string</span> socketFilename;
192
+ <a name="l00167"></a>00167 <span class="keywordtype">string</span> socketPassword;
193
+ <a name="l00168"></a>00168 <span class="keywordtype">int</span> ret, fds[2];
194
+ <a name="l00169"></a>00169
195
+ <a name="l00170"></a>00170 UPDATE_TRACE_POINT();
196
+ <a name="l00171"></a>00171 socketFilename = generation-&gt;getPath() + <span class="stringliteral">&quot;/spawn-server/socket.&quot;</span> +
197
+ <a name="l00172"></a>00172 toString(getpid()) + <span class="stringliteral">&quot;.&quot;</span> +
198
+ <a name="l00173"></a>00173 pointerToIntString(<span class="keyword">this</span>);
199
+ <a name="l00174"></a>00174 socketPassword = Base64::encode(random.generateByteString(32));
200
+ <a name="l00175"></a>00175 serverSocket = createUnixServer(socketFilename.c_str());
201
+ <a name="l00176"></a>00176 <span class="keywordflow">do</span> {
202
+ <a name="l00177"></a>00177 ret = chmod(socketFilename.c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
203
+ <a name="l00178"></a>00178 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
204
+ <a name="l00179"></a>00179 <span class="keywordflow">if</span> (ret == -1) {
205
+ <a name="l00180"></a>00180 <span class="keywordtype">int</span> e = errno;
206
+ <a name="l00181"></a>00181 syscalls::unlink(socketFilename.c_str());
207
+ <a name="l00182"></a>00182 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1FileSystemException.html" title="A filesystem error, as returned by the operating system.">FileSystemException</a>(<span class="stringliteral">&quot;Cannot set permissions on &#39;&quot;</span> + socketFilename + <span class="stringliteral">&quot;&#39;&quot;</span>,
208
+ <a name="l00183"></a>00183 e, socketFilename);
209
+ <a name="l00184"></a>00184 }
210
+ <a name="l00185"></a>00185
211
+ <a name="l00186"></a>00186 <span class="keywordflow">if</span> (syscalls::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
212
+ <a name="l00187"></a>00187 <span class="keywordtype">int</span> e = errno;
213
+ <a name="l00188"></a>00188 syscalls::unlink(socketFilename.c_str());
214
+ <a name="l00189"></a>00189 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">&quot;Cannot create a Unix socket&quot;</span>, e);
215
+ <a name="l00190"></a>00190 }
216
+ <a name="l00191"></a>00191
217
+ <a name="l00192"></a>00192 UPDATE_TRACE_POINT();
218
+ <a name="l00193"></a>00193 pid = syscalls::fork();
219
+ <a name="l00194"></a>00194 <span class="keywordflow">if</span> (pid == 0) {
220
+ <a name="l00195"></a>00195 dup2(serverSocket, HIGHEST_FD + 1);
221
+ <a name="l00196"></a>00196 dup2(fds[1], HIGHEST_FD + 2);
222
+ <a name="l00197"></a>00197 dup2(HIGHEST_FD + 1, SERVER_SOCKET_FD);
223
+ <a name="l00198"></a>00198 dup2(HIGHEST_FD + 2, OWNER_SOCKET_FD);
224
+ <a name="l00199"></a>00199
225
+ <a name="l00200"></a>00200 <span class="comment">// Close all unnecessary file descriptors</span>
226
+ <a name="l00201"></a>00201 <span class="keywordflow">for</span> (<span class="keywordtype">long</span> i = sysconf(_SC_OPEN_MAX) - 1; i &gt; HIGHEST_FD; i--) {
227
+ <a name="l00202"></a>00202 close(i);
228
+ <a name="l00203"></a>00203 }
229
+ <a name="l00204"></a>00204
230
+ <a name="l00205"></a>00205 execlp(rubyCommand.c_str(),
231
+ <a name="l00206"></a>00206 rubyCommand.c_str(),
232
+ <a name="l00207"></a>00207 spawnServerCommand.c_str(),
233
+ <a name="l00208"></a>00208 <span class="comment">/* The spawn server changes the process names of the subservers</span>
234
+ <a name="l00209"></a>00209 <span class="comment"> * that it starts, for better usability. However, the process name length</span>
235
+ <a name="l00210"></a>00210 <span class="comment"> * (as shown by ps) is limited. Here, we try to expand that limit by</span>
236
+ <a name="l00211"></a>00211 <span class="comment"> * deliberately passing a useless whitespace string to the spawn server.</span>
237
+ <a name="l00212"></a>00212 <span class="comment"> * This argument is ignored by the spawn server. This works on some</span>
238
+ <a name="l00213"></a>00213 <span class="comment"> * systems, such as Ubuntu Linux.</span>
239
+ <a name="l00214"></a>00214 <span class="comment"> */</span>
240
+ <a name="l00215"></a>00215 <span class="stringliteral">&quot; &quot;</span>,
241
+ <a name="l00216"></a>00216 (<span class="keywordtype">char</span> *) NULL);
242
+ <a name="l00217"></a>00217 <span class="keywordtype">int</span> e = errno;
243
+ <a name="l00218"></a>00218 fprintf(stderr, <span class="stringliteral">&quot;*** Passenger ERROR (%s:%d):\n&quot;</span>
244
+ <a name="l00219"></a>00219 <span class="stringliteral">&quot;Could not start the spawn server: %s: %s (%d)\n&quot;</span>,
245
+ <a name="l00220"></a>00220 __FILE__, __LINE__,
246
+ <a name="l00221"></a>00221 rubyCommand.c_str(), strerror(e), e);
247
+ <a name="l00222"></a>00222 fflush(stderr);
248
+ <a name="l00223"></a>00223 _exit(1);
249
+ <a name="l00224"></a>00224 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (pid == -1) {
250
+ <a name="l00225"></a>00225 <span class="keywordtype">int</span> e = errno;
251
+ <a name="l00226"></a>00226 syscalls::unlink(socketFilename.c_str());
252
+ <a name="l00227"></a>00227 syscalls::close(fds[0]);
253
+ <a name="l00228"></a>00228 syscalls::close(fds[1]);
254
+ <a name="l00229"></a>00229 pid = 0;
255
+ <a name="l00230"></a>00230 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">&quot;Unable to fork a process&quot;</span>, e);
256
+ <a name="l00231"></a>00231 } <span class="keywordflow">else</span> {
257
+ <a name="l00232"></a>00232 <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> ownerSocket = fds[0];
258
+ <a name="l00233"></a>00233 syscalls::close(fds[1]);
259
+ <a name="l00234"></a>00234 serverSocket.close();
260
+ <a name="l00235"></a>00235
261
+ <a name="l00236"></a>00236 <span class="comment">// Pass arguments to spawn server.</span>
262
+ <a name="l00237"></a>00237 writeExact(ownerSocket, socketFilename + <span class="stringliteral">&quot;\n&quot;</span>);
263
+ <a name="l00238"></a>00238 writeExact(ownerSocket, socketPassword + <span class="stringliteral">&quot;\n&quot;</span>);
264
+ <a name="l00239"></a>00239 writeExact(ownerSocket, generation-&gt;getPath() + <span class="stringliteral">&quot;\n&quot;</span>);
265
265
  <a name="l00240"></a>00240 <span class="keywordflow">if</span> (analyticsLogger != NULL) {
266
- <a name="l00241"></a>00241 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(analyticsLogger-&gt;getAddress() + <span class="stringliteral">&quot;\n&quot;</span>);
267
- <a name="l00242"></a>00242 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(analyticsLogger-&gt;getUsername() + <span class="stringliteral">&quot;\n&quot;</span>);
268
- <a name="l00243"></a>00243 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(Base64::encode(analyticsLogger-&gt;getPassword()) + <span class="stringliteral">&quot;\n&quot;</span>);
269
- <a name="l00244"></a>00244 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(analyticsLogger-&gt;getNodeName() + <span class="stringliteral">&quot;\n&quot;</span>);
266
+ <a name="l00241"></a>00241 writeExact(ownerSocket, analyticsLogger-&gt;getAddress() + <span class="stringliteral">&quot;\n&quot;</span>);
267
+ <a name="l00242"></a>00242 writeExact(ownerSocket, analyticsLogger-&gt;getUsername() + <span class="stringliteral">&quot;\n&quot;</span>);
268
+ <a name="l00243"></a>00243 writeExact(ownerSocket, Base64::encode(analyticsLogger-&gt;getPassword()) + <span class="stringliteral">&quot;\n&quot;</span>);
269
+ <a name="l00244"></a>00244 writeExact(ownerSocket, analyticsLogger-&gt;getNodeName() + <span class="stringliteral">&quot;\n&quot;</span>);
270
270
  <a name="l00245"></a>00245 } <span class="keywordflow">else</span> {
271
- <a name="l00246"></a>00246 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="stringliteral">&quot;\n&quot;</span>);
272
- <a name="l00247"></a>00247 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="stringliteral">&quot;\n&quot;</span>);
273
- <a name="l00248"></a>00248 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="stringliteral">&quot;\n&quot;</span>);
274
- <a name="l00249"></a>00249 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="stringliteral">&quot;\n&quot;</span>);
271
+ <a name="l00246"></a>00246 writeExact(ownerSocket, <span class="stringliteral">&quot;\n&quot;</span>);
272
+ <a name="l00247"></a>00247 writeExact(ownerSocket, <span class="stringliteral">&quot;\n&quot;</span>);
273
+ <a name="l00248"></a>00248 writeExact(ownerSocket, <span class="stringliteral">&quot;\n&quot;</span>);
274
+ <a name="l00249"></a>00249 writeExact(ownerSocket, <span class="stringliteral">&quot;\n&quot;</span>);
275
275
  <a name="l00250"></a>00250 }
276
- <a name="l00251"></a>00251 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(toString(logLevel) + <span class="stringliteral">&quot;\n&quot;</span>);
277
- <a name="l00252"></a>00252 ownerSocketChannel.<a class="code" href="classPassenger_1_1MessageChannel.html#a069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(debugLogFile + <span class="stringliteral">&quot;\n&quot;</span>);
276
+ <a name="l00251"></a>00251 writeExact(ownerSocket, toString(logLevel) + <span class="stringliteral">&quot;\n&quot;</span>);
277
+ <a name="l00252"></a>00252 writeExact(ownerSocket, debugLogFile + <span class="stringliteral">&quot;\n&quot;</span>);
278
278
  <a name="l00253"></a>00253
279
279
  <a name="l00254"></a>00254 this-&gt;ownerSocket = ownerSocket;
280
280
  <a name="l00255"></a>00255 this-&gt;socketFilename = socketFilename;
@@ -523,8 +523,8 @@
523
523
  <a name="l00498"></a>00498 }
524
524
  <a name="l00499"></a>00499
525
525
  <a name="l00500"></a>00500 <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a> prependMessageToException(<span class="keyword">const</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a> &amp;e, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;message) {
526
- <a name="l00501"></a>00501 <span class="keywordflow">return</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(message + <span class="stringliteral">&quot;: &quot;</span> + e.what());
527
- <a name="l00502"></a><a class="code" href="classPassenger_1_1SpawnManager.html#ab4dfcb11c58b07d8144b18dd99abed45">00502</a> }
526
+ <a name="l00501"></a><a class="code" href="classPassenger_1_1SpawnManager.html#ab4dfcb11c58b07d8144b18dd99abed45">00501</a> <span class="keywordflow">return</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(message + <span class="stringliteral">&quot;: &quot;</span> + e.what());
527
+ <a name="l00502"></a>00502 }
528
528
  <a name="l00503"></a>00503
529
529
  <a name="l00504"></a>00504 <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> prependMessageToException(<span class="keyword">const</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> &amp;e, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;message) {
530
530
  <a name="l00505"></a>00505 <span class="keywordflow">return</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(message + <span class="stringliteral">&quot;: &quot;</span> + e.<a class="code" href="classPassenger_1_1SystemException.html#a84fa2ab4f5b7b96704734fcdfdaa0269" title="Returns a brief version of the exception message.">brief</a>(), e.<a class="code" href="classPassenger_1_1SystemException.html#aee7a6672bf79b72a4c3ee70c57d6a47c" title="The value of errno at the time the error occured.">code</a>());
@@ -542,8 +542,8 @@
542
542
  <a name="l00517"></a>00517 <span class="comment"> * Construct a new SpawnManager.</span>
543
543
  <a name="l00518"></a>00518 <span class="comment"> *</span>
544
544
  <a name="l00519"></a>00519 <span class="comment"> * @param spawnServerCommand The filename of the spawn server to use.</span>
545
- <a name="l00520"></a>00520 <span class="comment"> * @param generation The server instance dir generation in which</span>
546
- <a name="l00521"></a><a class="code" href="classPassenger_1_1SpawnManager.html#a50cf2d13d1a5ab8809108d3de7d9326b">00521</a> <span class="comment"> * generation-specific are stored.</span>
545
+ <a name="l00520"></a><a class="code" href="classPassenger_1_1SpawnManager.html#a50cf2d13d1a5ab8809108d3de7d9326b">00520</a> <span class="comment"> * @param generation The server instance dir generation in which</span>
546
+ <a name="l00521"></a>00521 <span class="comment"> * generation-specific are stored.</span>
547
547
  <a name="l00522"></a>00522 <span class="comment"> * @param accountsDatabase An accounts database. SpawnManager will automatically</span>
548
548
  <a name="l00523"></a>00523 <span class="comment"> * create a new account for each spawned process, assigning</span>
549
549
  <a name="l00524"></a>00524 <span class="comment"> * it the rights as set in the PoolOptions object. This</span>
@@ -582,27 +582,27 @@
582
582
  <a name="l00557"></a>00557 }
583
583
  <a name="l00558"></a>00558 }
584
584
  <a name="l00559"></a>00559
585
- <a name="l00560"></a>00560 <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1SpawnManager.html" title="An AbstractSpawnManager implementation.">SpawnManager</a>() {
586
- <a name="l00561"></a><a class="code" href="classPassenger_1_1SpawnManager.html#a88a94ba4d41dab492cb1dc8a0f998973">00561</a> TRACE_POINT();
585
+ <a name="l00560"></a><a class="code" href="classPassenger_1_1SpawnManager.html#a88a94ba4d41dab492cb1dc8a0f998973">00560</a> <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1SpawnManager.html" title="An AbstractSpawnManager implementation.">SpawnManager</a>() {
586
+ <a name="l00561"></a>00561 TRACE_POINT();
587
587
  <a name="l00562"></a>00562 <span class="keywordflow">if</span> (pid != 0) {
588
588
  <a name="l00563"></a>00563 UPDATE_TRACE_POINT();
589
589
  <a name="l00564"></a>00564 this_thread::disable_interruption di;
590
590
  <a name="l00565"></a>00565 this_thread::disable_syscall_interruption dsi;
591
591
  <a name="l00566"></a>00566 syscalls::unlink(socketFilename.c_str());
592
- <a name="l00567"></a>00567 ownerSocket.<a class="code" href="classPassenger_1_1FileDescriptor.html#ad7c1a99531181878cbab74a7400c5432" title="Close the underlying file descriptor.">close</a>();
592
+ <a name="l00567"></a>00567 ownerSocket.<a class="code" href="classPassenger_1_1FileDescriptor.html#a02062f3cfb689b32781e11114c0abe5b" title="Close the underlying file descriptor.">close</a>();
593
593
  <a name="l00568"></a>00568 syscalls::waitpid(pid, NULL, 0);
594
594
  <a name="l00569"></a>00569 }
595
595
  <a name="l00570"></a>00570 }
596
596
  <a name="l00571"></a>00571
597
- <a name="l00572"></a>00572 <span class="keyword">virtual</span> <a class="code" href="namespacePassenger.html#aced1f248465136b313c6dec5fe6ca492" title="Convenient alias for Process smart pointer.">ProcessPtr</a> <a class="code" href="classPassenger_1_1SpawnManager.html#a88a94ba4d41dab492cb1dc8a0f998973" title="Spawn a new application process.">spawn</a>(<span class="keyword">const</span> PoolOptions &amp;options) {
597
+ <a name="l00572"></a>00572 <span class="keyword">virtual</span> <a class="code" href="namespacePassenger.html#aced1f248465136b313c6dec5fe6ca492" title="Convenient alias for Process smart pointer.">ProcessPtr</a> <a class="code" href="classPassenger_1_1SpawnManager.html#a88a94ba4d41dab492cb1dc8a0f998973" title="Spawn a new application process.">spawn</a>(<span class="keyword">const</span> <a class="code" href="structPassenger_1_1PoolOptions.html" title="This struct encapsulates information for ApplicationPool::get() and for SpawnManager::spawn()...">PoolOptions</a> &amp;options) {
598
598
  <a name="l00573"></a>00573 TRACE_POINT();
599
- <a name="l00574"></a>00574 AnalyticsScopeLog scope(options.log, <span class="stringliteral">&quot;spawn app process&quot;</span>);
599
+ <a name="l00574"></a>00574 AnalyticsScopeLog scope(options.<a class="code" href="structPassenger_1_1PoolOptions.html#ace54185a9981f103a036a7ac3e768612" title="An analytics log object to log things to.">log</a>, <span class="stringliteral">&quot;spawn app process&quot;</span>);
600
600
  <a name="l00575"></a>00575 <a class="code" href="namespacePassenger.html#aced1f248465136b313c6dec5fe6ca492" title="Convenient alias for Process smart pointer.">ProcessPtr</a> result;
601
601
  <a name="l00576"></a>00576 boost::mutex::scoped_lock l(lock);
602
602
  <a name="l00577"></a>00577
603
603
  <a name="l00578"></a>00578 <span class="keywordflow">try</span> {
604
- <a name="l00579"></a>00579 result = sendSpawnCommand(options);
605
- <a name="l00580"></a><a class="code" href="classPassenger_1_1SpawnManager.html#aad71b2ea9431f3286f23a6e6f80e0981">00580</a> } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a class="code" href="classPassenger_1_1SpawnException.html" title="Thrown when SpawnManager or ApplicationPool fails to spawn an application instance...">SpawnException</a> &amp;e) {
604
+ <a name="l00579"></a><a class="code" href="classPassenger_1_1SpawnManager.html#aad71b2ea9431f3286f23a6e6f80e0981">00579</a> result = sendSpawnCommand(options);
605
+ <a name="l00580"></a>00580 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a class="code" href="classPassenger_1_1SpawnException.html" title="Thrown when SpawnManager or ApplicationPool fails to spawn an application instance...">SpawnException</a> &amp;e) {
606
606
  <a name="l00581"></a>00581 <span class="keywordflow">if</span> (e.<a class="code" href="classPassenger_1_1SpawnException.html#ae65dc272e183fd9e5637a4091cc6bbf4" title="Check whether an error page is available.">hasErrorPage</a>()) {
607
607
  <a name="l00582"></a>00582 <span class="keywordflow">throw</span>;
608
608
  <a name="l00583"></a>00583 } <span class="keywordflow">else</span> {
@@ -612,18 +612,18 @@
612
612
  <a name="l00587"></a>00587 scope.success();
613
613
  <a name="l00588"></a>00588 <span class="keywordflow">return</span> result;
614
614
  <a name="l00589"></a>00589 }
615
- <a name="l00590"></a>00590
616
- <a name="l00591"></a><a class="code" href="classPassenger_1_1SpawnManager.html#a9210212c23c5a8ee5ee4dd5c9dcdf57d">00591</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1SpawnManager.html#aad71b2ea9431f3286f23a6e6f80e0981" title="Shutdown the ApplicationSpawner server that&amp;#39;s running at the given application...">reload</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot) {
615
+ <a name="l00590"></a><a class="code" href="classPassenger_1_1SpawnManager.html#a9210212c23c5a8ee5ee4dd5c9dcdf57d">00590</a>
616
+ <a name="l00591"></a>00591 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1SpawnManager.html#aad71b2ea9431f3286f23a6e6f80e0981" title="Shutdown the ApplicationSpawner server that&amp;#39;s running at the given application...">reload</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot) {
617
617
  <a name="l00592"></a>00592 TRACE_POINT();
618
618
  <a name="l00593"></a>00593 this_thread::disable_interruption di;
619
- <a name="l00594"></a>00594 this_thread::disable_syscall_interruption dsi;
620
- <a name="l00595"></a><a class="code" href="classPassenger_1_1SpawnManager.html#af34df8cfccfc64507999f1b48bc5a126">00595</a> <span class="keywordflow">try</span> {
619
+ <a name="l00594"></a><a class="code" href="classPassenger_1_1SpawnManager.html#af34df8cfccfc64507999f1b48bc5a126">00594</a> this_thread::disable_syscall_interruption dsi;
620
+ <a name="l00595"></a>00595 <span class="keywordflow">try</span> {
621
621
  <a name="l00596"></a>00596 <span class="keywordflow">return</span> sendReloadCommand(appRoot);
622
622
  <a name="l00597"></a>00597 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> &amp;e) {
623
623
  <a name="l00598"></a>00598 <span class="keywordflow">return</span> handleReloadException(e, appRoot);
624
624
  <a name="l00599"></a>00599 }
625
- <a name="l00600"></a>00600 }
626
- <a name="l00601"></a><a class="code" href="namespacePassenger.html#a6ab2d566ff87a2676c23d8aa40204587">00601</a>
625
+ <a name="l00600"></a><a class="code" href="namespacePassenger.html#a6ab2d566ff87a2676c23d8aa40204587">00600</a> }
626
+ <a name="l00601"></a>00601
627
627
  <a name="l00602"></a>00602 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1SpawnManager.html#a9210212c23c5a8ee5ee4dd5c9dcdf57d" title="Forcefully kill the spawn server.">killSpawnServer</a>()<span class="keyword"> const </span>{
628
628
  <a name="l00603"></a>00603 kill(pid, SIGKILL);
629
629
  <a name="l00604"></a>00604 }