passenger 2.1.2 → 2.1.3

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 (244) hide show
  1. data/Rakefile +7 -5
  2. data/doc/Architectural overview.html +729 -1
  3. data/doc/Architectural overview.txt +0 -5
  4. data/doc/Security of user switching support.html +605 -1
  5. data/doc/Users guide.html +110 -106
  6. data/doc/Users guide.txt +49 -0
  7. data/doc/cxxapi/ApplicationPoolServer_8h-source.html +400 -372
  8. data/doc/cxxapi/ApplicationPool_8h-source.html +1 -1
  9. data/doc/cxxapi/Application_8h-source.html +1 -1
  10. data/doc/cxxapi/Bucket_8h-source.html +1 -1
  11. data/doc/cxxapi/CachedFileStat_8h-source.html +56 -65
  12. data/doc/cxxapi/Configuration_8h-source.html +40 -32
  13. data/doc/cxxapi/DirectoryMapper_8h-source.html +1 -1
  14. data/doc/cxxapi/DummySpawnManager_8h-source.html +1 -1
  15. data/doc/cxxapi/Exceptions_8h-source.html +1 -1
  16. data/doc/cxxapi/FileChecker_8h-source.html +29 -30
  17. data/doc/cxxapi/Hooks_8h-source.html +1 -1
  18. data/doc/cxxapi/Logging_8h-source.html +1 -1
  19. data/doc/cxxapi/MessageChannel_8h-source.html +1 -1
  20. data/doc/cxxapi/PoolOptions_8h-source.html +1 -1
  21. data/doc/cxxapi/SpawnManager_8h-source.html +225 -219
  22. data/doc/cxxapi/StandardApplicationPool_8h-source.html +451 -445
  23. data/doc/cxxapi/SystemTime_8h-source.html +1 -1
  24. data/doc/cxxapi/Utils_8h-source.html +201 -140
  25. data/doc/cxxapi/annotated.html +2 -2
  26. data/doc/cxxapi/classClient-members.html +1 -1
  27. data/doc/cxxapi/classClient.html +1 -1
  28. data/doc/cxxapi/classHooks-members.html +1 -1
  29. data/doc/cxxapi/classHooks.html +1 -1
  30. data/doc/cxxapi/classPassenger_1_1Application-members.html +1 -1
  31. data/doc/cxxapi/classPassenger_1_1Application.html +1 -1
  32. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +1 -1
  33. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +1 -1
  34. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -1
  35. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +1 -1
  36. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
  37. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +1 -1
  38. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +1 -1
  39. data/doc/cxxapi/{classPassenger_1_1TempFile-members.html → classPassenger_1_1BufferedUpload-members.html} +5 -5
  40. data/doc/cxxapi/{classPassenger_1_1TempFile.html → classPassenger_1_1BufferedUpload.html} +33 -43
  41. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +1 -1
  42. data/doc/cxxapi/classPassenger_1_1BusyException.html +1 -1
  43. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +1 -1
  44. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +1 -1
  45. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +1 -1
  46. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +1 -1
  47. data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -1
  48. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +1 -1
  49. data/doc/cxxapi/classPassenger_1_1FileChecker-members.html +1 -1
  50. data/doc/cxxapi/classPassenger_1_1FileChecker.html +2 -2
  51. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -1
  52. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +1 -1
  53. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  54. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +1 -1
  55. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +1 -1
  56. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  57. data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -1
  58. data/doc/cxxapi/classPassenger_1_1IOException.html +1 -1
  59. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  60. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +1 -1
  61. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +1 -1
  62. data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +1 -1
  63. data/doc/cxxapi/classPassenger_1_1RuntimeException.html +1 -1
  64. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -1
  65. data/doc/cxxapi/classPassenger_1_1SpawnException.html +1 -1
  66. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +1 -1
  67. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +1 -1
  68. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +1 -1
  69. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +1 -1
  70. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
  71. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +1 -1
  72. data/doc/cxxapi/classPassenger_1_1SystemException.html +1 -1
  73. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  74. data/doc/cxxapi/classPassenger_1_1SystemTime-members.html +1 -1
  75. data/doc/cxxapi/classPassenger_1_1SystemTime.html +1 -1
  76. data/doc/cxxapi/definitions_8h-source.html +1 -1
  77. data/doc/cxxapi/files.html +1 -1
  78. data/doc/cxxapi/functions.html +12 -11
  79. data/doc/cxxapi/functions_func.html +9 -7
  80. data/doc/cxxapi/functions_type.html +1 -1
  81. data/doc/cxxapi/functions_vars.html +2 -4
  82. data/doc/cxxapi/graph_legend.html +1 -1
  83. data/doc/cxxapi/graph_legend.png +0 -0
  84. data/doc/cxxapi/group__Configuration.html +3 -3
  85. data/doc/cxxapi/group__Configuration.png +0 -0
  86. data/doc/cxxapi/group__Core.html +1 -1
  87. data/doc/cxxapi/group__Core.png +0 -0
  88. data/doc/cxxapi/group__Exceptions.html +1 -1
  89. data/doc/cxxapi/group__Hooks.html +1 -1
  90. data/doc/cxxapi/group__Hooks.png +0 -0
  91. data/doc/cxxapi/group__Support.html +33 -16
  92. data/doc/cxxapi/hierarchy.html +2 -2
  93. data/doc/cxxapi/inherit__graph__0.png +0 -0
  94. data/doc/cxxapi/inherit__graph__1.png +0 -0
  95. data/doc/cxxapi/inherit__graph__10.map +1 -1
  96. data/doc/cxxapi/inherit__graph__10.md5 +1 -1
  97. data/doc/cxxapi/inherit__graph__10.png +0 -0
  98. data/doc/cxxapi/inherit__graph__11.map +1 -1
  99. data/doc/cxxapi/inherit__graph__11.md5 +1 -1
  100. data/doc/cxxapi/inherit__graph__11.png +0 -0
  101. data/doc/cxxapi/inherit__graph__12.map +1 -2
  102. data/doc/cxxapi/inherit__graph__12.md5 +1 -1
  103. data/doc/cxxapi/inherit__graph__12.png +0 -0
  104. data/doc/cxxapi/inherit__graph__13.map +2 -1
  105. data/doc/cxxapi/inherit__graph__13.md5 +1 -1
  106. data/doc/cxxapi/inherit__graph__13.png +0 -0
  107. data/doc/cxxapi/inherit__graph__14.map +1 -1
  108. data/doc/cxxapi/inherit__graph__14.md5 +1 -1
  109. data/doc/cxxapi/inherit__graph__14.png +0 -0
  110. data/doc/cxxapi/inherit__graph__15.map +1 -1
  111. data/doc/cxxapi/inherit__graph__15.md5 +1 -1
  112. data/doc/cxxapi/inherit__graph__15.png +0 -0
  113. data/doc/cxxapi/inherit__graph__16.map +1 -1
  114. data/doc/cxxapi/inherit__graph__16.md5 +1 -1
  115. data/doc/cxxapi/inherit__graph__16.png +0 -0
  116. data/doc/cxxapi/inherit__graph__17.map +1 -1
  117. data/doc/cxxapi/inherit__graph__17.md5 +1 -1
  118. data/doc/cxxapi/inherit__graph__17.png +0 -0
  119. data/doc/cxxapi/inherit__graph__18.map +1 -1
  120. data/doc/cxxapi/inherit__graph__18.md5 +1 -1
  121. data/doc/cxxapi/inherit__graph__18.png +0 -0
  122. data/doc/cxxapi/inherit__graph__19.map +1 -2
  123. data/doc/cxxapi/inherit__graph__19.md5 +1 -1
  124. data/doc/cxxapi/inherit__graph__19.png +0 -0
  125. data/doc/cxxapi/inherit__graph__2.png +0 -0
  126. data/doc/cxxapi/inherit__graph__20.map +2 -1
  127. data/doc/cxxapi/inherit__graph__20.md5 +1 -1
  128. data/doc/cxxapi/inherit__graph__20.png +0 -0
  129. data/doc/cxxapi/inherit__graph__21.map +1 -1
  130. data/doc/cxxapi/inherit__graph__21.md5 +1 -1
  131. data/doc/cxxapi/inherit__graph__21.png +0 -0
  132. data/doc/cxxapi/inherit__graph__3.png +0 -0
  133. data/doc/cxxapi/inherit__graph__4.png +0 -0
  134. data/doc/cxxapi/inherit__graph__5.png +0 -0
  135. data/doc/cxxapi/inherit__graph__6.png +0 -0
  136. data/doc/cxxapi/inherit__graph__7.map +1 -1
  137. data/doc/cxxapi/inherit__graph__7.md5 +1 -1
  138. data/doc/cxxapi/inherit__graph__7.png +0 -0
  139. data/doc/cxxapi/inherit__graph__8.map +1 -1
  140. data/doc/cxxapi/inherit__graph__8.md5 +1 -1
  141. data/doc/cxxapi/inherit__graph__8.png +0 -0
  142. data/doc/cxxapi/inherit__graph__9.map +1 -1
  143. data/doc/cxxapi/inherit__graph__9.md5 +1 -1
  144. data/doc/cxxapi/inherit__graph__9.png +0 -0
  145. data/doc/cxxapi/inherits.html +18 -18
  146. data/doc/cxxapi/main.html +1 -1
  147. data/doc/cxxapi/modules.html +1 -1
  148. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -1
  149. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +1 -1
  150. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -1
  151. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +1 -1
  152. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +1 -1
  153. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +1 -1
  154. data/doc/cxxapi/tree.html +4 -4
  155. data/doc/rdoc/classes/ConditionVariable.html +58 -58
  156. data/doc/rdoc/classes/Exception.html +11 -11
  157. data/doc/rdoc/classes/GC.html +4 -4
  158. data/doc/rdoc/classes/IO.html +14 -14
  159. data/doc/rdoc/classes/PhusionPassenger.html +11 -11
  160. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +1 -1
  161. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +40 -39
  162. data/doc/rdoc/classes/PhusionPassenger/Application.html +14 -14
  163. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +12 -12
  164. data/doc/rdoc/classes/PhusionPassenger/Railz.html +1 -1
  165. data/doc/rdoc/classes/PhusionPassenger/Utils.html +15 -8
  166. data/doc/rdoc/classes/PlatformInfo.html +257 -253
  167. data/doc/rdoc/classes/RakeExtensions.html +2 -2
  168. data/doc/rdoc/classes/Signal.html +26 -26
  169. data/doc/rdoc/created.rid +1 -1
  170. data/doc/rdoc/files/DEVELOPERS_TXT.html +1 -1
  171. data/doc/rdoc/files/README.html +1 -1
  172. data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +1 -1
  173. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +1 -1
  174. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +1 -1
  175. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +1 -1
  176. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +1 -1
  177. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +1 -1
  178. data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +1 -1
  179. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +1 -1
  180. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +1 -1
  181. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +1 -1
  182. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +1 -1
  183. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +1 -1
  184. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +1 -1
  185. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +1 -1
  186. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +1 -1
  187. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +1 -1
  188. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +1 -1
  189. data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +1 -1
  190. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +1 -1
  191. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +1 -1
  192. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +1 -1
  193. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +1 -1
  194. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +1 -1
  195. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +9 -9
  196. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +1 -1
  197. data/doc/rdoc/files/{lib → misc}/rake/extensions_rb.html +2 -2
  198. data/doc/rdoc/fr_file_index.html +1 -1
  199. data/doc/rdoc/fr_method_index.html +22 -22
  200. data/ext/apache2/ApplicationPoolServer.h +43 -15
  201. data/ext/apache2/ApplicationPoolServerExecutable.cpp +27 -52
  202. data/ext/apache2/CachedFileStat.h +7 -16
  203. data/ext/apache2/Configuration.h +9 -1
  204. data/ext/apache2/FileChecker.h +4 -5
  205. data/ext/apache2/Hooks.cpp +20 -22
  206. data/ext/apache2/SpawnManager.h +6 -0
  207. data/ext/apache2/StandardApplicationPool.h +6 -0
  208. data/ext/apache2/Utils.cpp +174 -16
  209. data/ext/apache2/Utils.h +99 -38
  210. data/ext/boost/cstdint.hpp +2 -1
  211. data/ext/oxt/system_calls.cpp +20 -2
  212. data/ext/oxt/system_calls.hpp +2 -0
  213. data/lib/phusion_passenger/abstract_request_handler.rb +5 -1
  214. data/lib/phusion_passenger/admin_tools.rb +1 -1
  215. data/lib/phusion_passenger/admin_tools/control_process.rb +2 -1
  216. data/lib/phusion_passenger/dependencies.rb +7 -4
  217. data/lib/phusion_passenger/platform_info.rb +8 -2
  218. data/lib/phusion_passenger/rack/application_spawner.rb +1 -1
  219. data/lib/phusion_passenger/templates/version_not_found.html.erb +9 -0
  220. data/lib/phusion_passenger/utils.rb +13 -6
  221. data/lib/phusion_passenger/wsgi/application_spawner.rb +1 -1
  222. data/{lib → misc}/rake/cplusplus.rb +0 -0
  223. data/{lib → misc}/rake/extensions.rb +0 -0
  224. data/{lib → misc}/rake/gempackagetask.rb +0 -0
  225. data/{lib → misc}/rake/packagetask.rb +0 -0
  226. data/{lib → misc}/rake/rdoctask.rb +0 -0
  227. data/misc/render_error_pages.rb +6 -5
  228. data/test/CxxTestMain.cpp +109 -7
  229. data/test/UtilsTest.cpp +61 -51
  230. data/test/config.yml.example +6 -2
  231. data/test/integration_tests.rb +4 -0
  232. data/test/ruby/abstract_request_handler_spec.rb +9 -3
  233. data/test/ruby/rack/application_spawner_spec.rb +3 -2
  234. data/test/ruby/rails/application_spawner_spec.rb +15 -4
  235. data/test/ruby/rails/framework_spawner_spec.rb +4 -2
  236. data/test/ruby/rails/spawner_error_handling_spec.rb +4 -4
  237. data/test/ruby/spawn_manager_spec.rb +22 -9
  238. data/test/ruby/utils_spec.rb +18 -12
  239. data/test/ruby/wsgi/application_spawner_spec.rb +16 -7
  240. data/test/stub/apache2/httpd.conf.erb +1 -0
  241. data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
  242. metadata +1064 -1090
  243. data/doc/Users guide Apache.html +0 -3127
  244. data/doc/Users guide Nginx.html +0 -1458
@@ -235,6 +235,12 @@ Next, add a <<RailsBaseURI,RailsBaseURI>> option to the virtual host configurati
235
235
  -------------------------------------------
236
236
  Then restart Apache. The application has now been deployed.
237
237
 
238
+ NOTE: If you're deploying to a sub-URI then please make sure that your view
239
+ templates correctly handles references to sub-URI static assets! Otherwise
240
+ you may find broken links to images, CSS files, JavaScripts, etc. Please read
241
+ <<sub_uri_deployment_uri_fix,How to fix broken images/CSS/JavaScript URIs in sub-URI deployments>>
242
+ for more information.
243
+
238
244
  [TIP]
239
245
  ======================================
240
246
  You can deploy multiple Rails applications under a virtual host, by specifying
@@ -1887,6 +1893,49 @@ then Rails will automatically reload your application code after each request.
1887
1893
  or when you're not developing a Rails application and your web framework
1888
1894
  does not support code reloading.
1889
1895
 
1896
+ [[sub_uri_deployment_uri_fix]]
1897
+ === How to fix broken images/CSS/JavaScript URIs in sub-URI deployments
1898
+
1899
+ Some people experience broken images and other broken static assets when they
1900
+ deploy their application to a sub-URI (i.e. 'http://mysite.com/railsapp/').
1901
+ The reason for this usually is that you used a
1902
+ static URI for your image in the views. This means your 'img' source probably refers
1903
+ to something like '/images/foo.jpg'. The leading slash means that it's an absolute URI:
1904
+ you're telling the browser to always load 'http://mysite.com/images/foo.jpg' no
1905
+ matter what. The problem is that the image is actually at
1906
+ 'http://mysite.com/railsapp/images/foo.jpg'. There are two ways to fix this.
1907
+
1908
+ The first way (not recommended) is to change your view templates to refer to
1909
+ 'images/foo.jpg'. This is a relative URI: note the lack of a leading slash). What
1910
+ this does is making the path relative to the current URI. The problem is that if you
1911
+ use restful URIs, then your images will probably break again when you add a level to
1912
+ the URI.
1913
+ For example, when you're at 'http://mysite.com/railsapp' the browser will look for
1914
+ 'http://mysite.com/railsapp/images/foo.jpg'. But when you're at
1915
+ 'http://mysite.com/railsapp/controller'. the browser will look for
1916
+ 'http://mysite.com/railsapp/controller/images/foo.jpg'.
1917
+ So relative URIs usually don't work well with layout templates.
1918
+
1919
+ The second and highly recommended way is to always use Rails helper methods to
1920
+ output tags for static assets. These helper methods automatically take care
1921
+ of prepending the base URI that you've deployed the application to. For images
1922
+ there is `image_tag`, for JavaScript there is `javascript_include_tag` and for
1923
+ CSS there is `stylesheet_link_tag`. In the above example you would simply remove
1924
+ the '<img>' HTML tag and replace it with inline Ruby like this:
1925
+
1926
+ ---------------------------------------
1927
+ <%= image_tag("foo.jpg") %>
1928
+ ---------------------------------------
1929
+
1930
+ This will generate the proper image tag to `$RAILS_ROOT/public/images/foo.jpg`
1931
+ so that your images will always work no matter what sub-URI you've deployed to.
1932
+
1933
+ These helper methods are more valuable than you may think. For example they also
1934
+ append a timestamp to the URI to better facilitate HTTP caching. For more information,
1935
+ please refer to
1936
+ link:http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html[the Rails API docs].
1937
+
1938
+
1890
1939
  == Appendix A: About this document ==
1891
1940
 
1892
1941
  The text of this document is licensed under the
@@ -419,381 +419,409 @@
419
419
  <a name="l00403"></a>00403 UPDATE_TRACE_POINT();
420
420
  <a name="l00404"></a>00404 data-&gt;disconnect();
421
421
  <a name="l00405"></a>00405 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"The ApplicationPool server unexpectedly "</span>
422
- <a name="l00406"></a>00406 <span class="stringliteral">"closed the connection."</span>);
423
- <a name="l00407"></a>00407 }
424
- <a name="l00408"></a>00408 <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"ok"</span>) {
425
- <a name="l00409"></a>00409 UPDATE_TRACE_POINT();
426
- <a name="l00410"></a>00410 pid_t pid = (pid_t) <a class="code" href="group__Support.html#g7b50461f1bc2b370c956967870da2762" title="Converts the given string to a long integer.">atol</a>(args[1]);
427
- <a name="l00411"></a>00411 <span class="keywordtype">int</span> sessionID = <a class="code" href="group__Support.html#g73b17b509ee44938a56bf16cbf82fb48" title="Converts the given string to an integer.">atoi</a>(args[2]);
428
- <a name="l00412"></a>00412
429
- <a name="l00413"></a>00413 <span class="keywordflow">try</span> {
430
- <a name="l00414"></a>00414 stream = channel.<a class="code" href="classPassenger_1_1MessageChannel.html#1561b7e4a0f4d39ea431f456e5655488" title="Receive a file descriptor, which had been passed over the underlying file descriptor...">readFileDescriptor</a>();
431
- <a name="l00415"></a>00415 } <span class="keywordflow">catch</span> (...) {
432
- <a name="l00416"></a>00416 UPDATE_TRACE_POINT();
433
- <a name="l00417"></a>00417 data-&gt;disconnect();
434
- <a name="l00418"></a>00418 <span class="keywordflow">throw</span>;
435
- <a name="l00419"></a>00419 }
436
- <a name="l00420"></a>00420
437
- <a name="l00421"></a>00421 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> RemoteSession(dataSmartPointer,
438
- <a name="l00422"></a>00422 pid, sessionID, stream));
439
- <a name="l00423"></a>00423 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"SpawnException"</span>) {
440
- <a name="l00424"></a>00424 UPDATE_TRACE_POINT();
441
- <a name="l00425"></a>00425 <span class="keywordflow">if</span> (args[2] == <span class="stringliteral">"true"</span>) {
442
- <a name="l00426"></a>00426 <span class="keywordtype">string</span> errorPage;
443
- <a name="l00427"></a>00427
444
- <a name="l00428"></a>00428 <span class="keywordflow">try</span> {
445
- <a name="l00429"></a>00429 result = channel.<a class="code" href="classPassenger_1_1MessageChannel.html#4ce6a0e751b5e3563bee583c231569bc" title="Read a scalar message from the underlying file descriptor.">readScalar</a>(errorPage);
446
- <a name="l00430"></a>00430 } <span class="keywordflow">catch</span> (...) {
447
- <a name="l00431"></a>00431 data-&gt;disconnect();
448
- <a name="l00432"></a>00432 <span class="keywordflow">throw</span>;
449
- <a name="l00433"></a>00433 }
450
- <a name="l00434"></a>00434 <span class="keywordflow">if</span> (!result) {
451
- <a name="l00435"></a>00435 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"The ApplicationPool server "</span>
452
- <a name="l00436"></a>00436 <span class="stringliteral">"unexpectedly closed the connection."</span>);
453
- <a name="l00437"></a>00437 }
454
- <a name="l00438"></a>00438 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SpawnException.html" title="Thrown when SpawnManager or ApplicationPool fails to spawn an application instance...">SpawnException</a>(args[1], errorPage);
455
- <a name="l00439"></a>00439 } <span class="keywordflow">else</span> {
456
- <a name="l00440"></a>00440 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SpawnException.html" title="Thrown when SpawnManager or ApplicationPool fails to spawn an application instance...">SpawnException</a>(args[1]);
457
- <a name="l00441"></a>00441 }
458
- <a name="l00442"></a>00442 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"BusyException"</span>) {
459
- <a name="l00443"></a>00443 UPDATE_TRACE_POINT();
460
- <a name="l00444"></a>00444 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1BusyException.html" title="The application pool is too busy and cannot fulfill a get() request.">BusyException</a>(args[1]);
461
- <a name="l00445"></a>00445 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"IOException"</span>) {
462
- <a name="l00446"></a>00446 UPDATE_TRACE_POINT();
463
- <a name="l00447"></a>00447 data-&gt;disconnect();
464
- <a name="l00448"></a>00448 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(args[1]);
465
- <a name="l00449"></a>00449 } <span class="keywordflow">else</span> {
466
- <a name="l00450"></a>00450 UPDATE_TRACE_POINT();
467
- <a name="l00451"></a>00451 data-&gt;disconnect();
468
- <a name="l00452"></a>00452 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"The ApplicationPool server returned "</span>
469
- <a name="l00453"></a>00453 <span class="stringliteral">"an unknown message: "</span> + <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(args));
470
- <a name="l00454"></a>00454 }
471
- <a name="l00455"></a>00455 }
472
- <a name="l00456"></a>00456 };
473
- <a name="l00457"></a>00457
474
- <a name="l00458"></a>00458
475
- <a name="l00459"></a>00459 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> SERVER_SOCKET_FD = 3;
422
+ <a name="l00406"></a>00406 <span class="stringliteral">"closed the connection while we're reading a response "</span>
423
+ <a name="l00407"></a>00407 <span class="stringliteral">"for the 'get' command."</span>);
424
+ <a name="l00408"></a>00408 }
425
+ <a name="l00409"></a>00409 <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"ok"</span>) {
426
+ <a name="l00410"></a>00410 UPDATE_TRACE_POINT();
427
+ <a name="l00411"></a>00411 pid_t pid = (pid_t) <a class="code" href="group__Support.html#g7b50461f1bc2b370c956967870da2762" title="Converts the given string to a long integer.">atol</a>(args[1]);
428
+ <a name="l00412"></a>00412 <span class="keywordtype">int</span> sessionID = <a class="code" href="group__Support.html#g73b17b509ee44938a56bf16cbf82fb48" title="Converts the given string to an integer.">atoi</a>(args[2]);
429
+ <a name="l00413"></a>00413
430
+ <a name="l00414"></a>00414 <span class="keywordflow">try</span> {
431
+ <a name="l00415"></a>00415 stream = channel.<a class="code" href="classPassenger_1_1MessageChannel.html#1561b7e4a0f4d39ea431f456e5655488" title="Receive a file descriptor, which had been passed over the underlying file descriptor...">readFileDescriptor</a>();
432
+ <a name="l00416"></a>00416 } <span class="keywordflow">catch</span> (...) {
433
+ <a name="l00417"></a>00417 UPDATE_TRACE_POINT();
434
+ <a name="l00418"></a>00418 data-&gt;disconnect();
435
+ <a name="l00419"></a>00419 <span class="keywordflow">throw</span>;
436
+ <a name="l00420"></a>00420 }
437
+ <a name="l00421"></a>00421
438
+ <a name="l00422"></a>00422 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> RemoteSession(dataSmartPointer,
439
+ <a name="l00423"></a>00423 pid, sessionID, stream));
440
+ <a name="l00424"></a>00424 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"SpawnException"</span>) {
441
+ <a name="l00425"></a>00425 UPDATE_TRACE_POINT();
442
+ <a name="l00426"></a>00426 <span class="keywordflow">if</span> (args[2] == <span class="stringliteral">"true"</span>) {
443
+ <a name="l00427"></a>00427 <span class="keywordtype">string</span> errorPage;
444
+ <a name="l00428"></a>00428
445
+ <a name="l00429"></a>00429 <span class="keywordflow">try</span> {
446
+ <a name="l00430"></a>00430 result = channel.<a class="code" href="classPassenger_1_1MessageChannel.html#4ce6a0e751b5e3563bee583c231569bc" title="Read a scalar message from the underlying file descriptor.">readScalar</a>(errorPage);
447
+ <a name="l00431"></a>00431 } <span class="keywordflow">catch</span> (...) {
448
+ <a name="l00432"></a>00432 data-&gt;disconnect();
449
+ <a name="l00433"></a>00433 <span class="keywordflow">throw</span>;
450
+ <a name="l00434"></a>00434 }
451
+ <a name="l00435"></a>00435 <span class="keywordflow">if</span> (!result) {
452
+ <a name="l00436"></a>00436 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"The ApplicationPool server "</span>
453
+ <a name="l00437"></a>00437 <span class="stringliteral">"unexpectedly closed the connection while "</span>
454
+ <a name="l00438"></a>00438 <span class="stringliteral">"we're reading the error page data."</span>);
455
+ <a name="l00439"></a>00439 }
456
+ <a name="l00440"></a>00440 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SpawnException.html" title="Thrown when SpawnManager or ApplicationPool fails to spawn an application instance...">SpawnException</a>(args[1], errorPage);
457
+ <a name="l00441"></a>00441 } <span class="keywordflow">else</span> {
458
+ <a name="l00442"></a>00442 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SpawnException.html" title="Thrown when SpawnManager or ApplicationPool fails to spawn an application instance...">SpawnException</a>(args[1]);
459
+ <a name="l00443"></a>00443 }
460
+ <a name="l00444"></a>00444 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"BusyException"</span>) {
461
+ <a name="l00445"></a>00445 UPDATE_TRACE_POINT();
462
+ <a name="l00446"></a>00446 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1BusyException.html" title="The application pool is too busy and cannot fulfill a get() request.">BusyException</a>(args[1]);
463
+ <a name="l00447"></a>00447 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"IOException"</span>) {
464
+ <a name="l00448"></a>00448 UPDATE_TRACE_POINT();
465
+ <a name="l00449"></a>00449 data-&gt;disconnect();
466
+ <a name="l00450"></a>00450 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(args[1]);
467
+ <a name="l00451"></a>00451 } <span class="keywordflow">else</span> {
468
+ <a name="l00452"></a>00452 UPDATE_TRACE_POINT();
469
+ <a name="l00453"></a>00453 data-&gt;disconnect();
470
+ <a name="l00454"></a>00454 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"The ApplicationPool server returned "</span>
471
+ <a name="l00455"></a>00455 <span class="stringliteral">"an unknown message: "</span> + <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(args));
472
+ <a name="l00456"></a>00456 }
473
+ <a name="l00457"></a>00457 }
474
+ <a name="l00458"></a>00458 };
475
+ <a name="l00459"></a>00459
476
476
  <a name="l00460"></a>00460
477
- <a name="l00461"></a>00461 <span class="keywordtype">string</span> m_serverExecutable;
478
- <a name="l00462"></a>00462 <span class="keywordtype">string</span> m_spawnServerCommand;
479
- <a name="l00463"></a>00463 <span class="keywordtype">string</span> m_logFile;
480
- <a name="l00464"></a>00464 <span class="keywordtype">string</span> m_rubyCommand;
481
- <a name="l00465"></a>00465 <span class="keywordtype">string</span> m_user;
482
- <a name="l00466"></a>00466 <span class="keywordtype">string</span> statusReportFIFO;
483
- <a name="l00467"></a>00467 <span class="comment"></span>
484
- <a name="l00468"></a>00468 <span class="comment"> /**</span>
485
- <a name="l00469"></a>00469 <span class="comment"> * The PID of the ApplicationPool server process. If no server process</span>
486
- <a name="l00470"></a>00470 <span class="comment"> * is running, then &lt;tt&gt;serverPid == 0&lt;/tt&gt;.</span>
487
- <a name="l00471"></a>00471 <span class="comment"> *</span>
488
- <a name="l00472"></a>00472 <span class="comment"> * @invariant</span>
489
- <a name="l00473"></a>00473 <span class="comment"> * if serverPid == 0:</span>
490
- <a name="l00474"></a>00474 <span class="comment"> * serverSocket == -1</span>
491
- <a name="l00475"></a>00475 <span class="comment"> */</span>
492
- <a name="l00476"></a>00476 pid_t serverPid;
493
- <a name="l00477"></a>00477 <span class="comment"></span>
494
- <a name="l00478"></a>00478 <span class="comment"> /**</span>
495
- <a name="l00479"></a>00479 <span class="comment"> * The connection to the ApplicationPool server process. If no server</span>
496
- <a name="l00480"></a>00480 <span class="comment"> * process is running, then &lt;tt&gt;serverSocket == -1&lt;/tt&gt;.</span>
497
- <a name="l00481"></a>00481 <span class="comment"> *</span>
498
- <a name="l00482"></a>00482 <span class="comment"> * @invariant</span>
499
- <a name="l00483"></a>00483 <span class="comment"> * if serverPid == 0:</span>
500
- <a name="l00484"></a>00484 <span class="comment"> * serverSocket == -1</span>
501
- <a name="l00485"></a>00485 <span class="comment"> */</span>
502
- <a name="l00486"></a>00486 <span class="keywordtype">int</span> serverSocket;
503
- <a name="l00487"></a>00487 <span class="comment"></span>
504
- <a name="l00488"></a>00488 <span class="comment"> /**</span>
505
- <a name="l00489"></a>00489 <span class="comment"> * Shutdown the currently running ApplicationPool server process.</span>
506
- <a name="l00490"></a>00490 <span class="comment"> *</span>
507
- <a name="l00491"></a>00491 <span class="comment"> * @pre System call interruption is disabled.</span>
508
- <a name="l00492"></a>00492 <span class="comment"> * @pre serverSocket != -1 &amp;&amp; serverPid != 0</span>
509
- <a name="l00493"></a>00493 <span class="comment"> * @post serverSocket == -1 &amp;&amp; serverPid == 0</span>
510
- <a name="l00494"></a>00494 <span class="comment"> */</span>
511
- <a name="l00495"></a>00495 <span class="keywordtype">void</span> shutdownServer() {
512
- <a name="l00496"></a>00496 TRACE_POINT();
513
- <a name="l00497"></a>00497 this_thread::disable_syscall_interruption dsi;
514
- <a name="l00498"></a>00498 <span class="keywordtype">int</span> ret;
515
- <a name="l00499"></a>00499 time_t begin;
516
- <a name="l00500"></a>00500 <span class="keywordtype">bool</span> done = <span class="keyword">false</span>;
517
- <a name="l00501"></a>00501
518
- <a name="l00502"></a>00502 syscalls::close(serverSocket);
519
- <a name="l00503"></a>00503 <span class="keywordflow">if</span> (!statusReportFIFO.empty()) {
520
- <a name="l00504"></a>00504 <span class="keywordflow">do</span> {
521
- <a name="l00505"></a>00505 ret = unlink(statusReportFIFO.c_str());
522
- <a name="l00506"></a>00506 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
523
- <a name="l00507"></a>00507 }
524
- <a name="l00508"></a>00508
525
- <a name="l00509"></a>00509 P_TRACE(2, <span class="stringliteral">"Waiting for existing ApplicationPoolServerExecutable (PID "</span> &lt;&lt;
526
- <a name="l00510"></a>00510 serverPid &lt;&lt; <span class="stringliteral">") to exit..."</span>);
527
- <a name="l00511"></a>00511 begin = syscalls::time(NULL);
528
- <a name="l00512"></a>00512 <span class="keywordflow">while</span> (!done &amp;&amp; syscalls::time(NULL) &lt; begin + 5) {
529
- <a name="l00513"></a>00513 <span class="comment">/*</span>
530
- <a name="l00514"></a>00514 <span class="comment"> * Some Apache modules fork(), but don't close file descriptors.</span>
531
- <a name="l00515"></a>00515 <span class="comment"> * mod_wsgi is one such example. Because of that, closing serverSocket</span>
532
- <a name="l00516"></a>00516 <span class="comment"> * won't always cause the ApplicationPool server to exit. So we send it a</span>
533
- <a name="l00517"></a>00517 <span class="comment"> * signal.</span>
534
- <a name="l00518"></a>00518 <span class="comment"> */</span>
535
- <a name="l00519"></a>00519 syscalls::kill(serverPid, SIGINT);
536
- <a name="l00520"></a>00520
537
- <a name="l00521"></a>00521 ret = syscalls::waitpid(serverPid, NULL, WNOHANG);
538
- <a name="l00522"></a>00522 done = ret &gt; 0 || ret == -1;
539
- <a name="l00523"></a>00523 <span class="keywordflow">if</span> (!done) {
540
- <a name="l00524"></a>00524 syscalls::usleep(100000);
541
- <a name="l00525"></a>00525 }
542
- <a name="l00526"></a>00526 }
543
- <a name="l00527"></a>00527 <span class="keywordflow">if</span> (done) {
544
- <a name="l00528"></a>00528 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited."</span>);
545
- <a name="l00529"></a>00529 } <span class="keywordflow">else</span> {
546
- <a name="l00530"></a>00530 P_DEBUG(<span class="stringliteral">"ApplicationPoolServerExecutable not exited in time. Killing it..."</span>);
547
- <a name="l00531"></a>00531 syscalls::kill(serverPid, SIGTERM);
548
- <a name="l00532"></a>00532 syscalls::waitpid(serverPid, NULL, 0);
549
- <a name="l00533"></a>00533 }
550
- <a name="l00534"></a>00534
551
- <a name="l00535"></a>00535 serverSocket = -1;
552
- <a name="l00536"></a>00536 serverPid = 0;
553
- <a name="l00537"></a>00537 }
554
- <a name="l00538"></a>00538 <span class="comment"></span>
555
- <a name="l00539"></a>00539 <span class="comment"> /**</span>
556
- <a name="l00540"></a>00540 <span class="comment"> * Start an ApplicationPool server process. If there's already one running,</span>
557
- <a name="l00541"></a>00541 <span class="comment"> * then the currently running one will be shutdown.</span>
558
- <a name="l00542"></a>00542 <span class="comment"> *</span>
559
- <a name="l00543"></a>00543 <span class="comment"> * @pre System call interruption is disabled.</span>
560
- <a name="l00544"></a>00544 <span class="comment"> * @post serverSocket != -1 &amp;&amp; serverPid != 0</span>
561
- <a name="l00545"></a>00545 <span class="comment"> * @throw SystemException Something went wrong.</span>
562
- <a name="l00546"></a>00546 <span class="comment"> */</span>
563
- <a name="l00547"></a>00547 <span class="keywordtype">void</span> restartServer() {
564
- <a name="l00548"></a>00548 TRACE_POINT();
565
- <a name="l00549"></a>00549 <span class="keywordtype">int</span> fds[2];
566
- <a name="l00550"></a>00550 pid_t pid;
567
- <a name="l00551"></a>00551
568
- <a name="l00552"></a>00552 <span class="keywordflow">if</span> (serverPid != 0) {
569
- <a name="l00553"></a>00553 shutdownServer();
570
- <a name="l00554"></a>00554 }
571
- <a name="l00555"></a>00555
572
- <a name="l00556"></a>00556 <span class="keywordflow">if</span> (syscalls::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
573
- <a name="l00557"></a>00557 <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">"Cannot create a Unix socket pair"</span>, errno);
574
- <a name="l00558"></a>00558 }
575
- <a name="l00559"></a>00559
576
- <a name="l00560"></a>00560 createStatusReportFIFO();
577
- <a name="l00561"></a>00561
578
- <a name="l00562"></a>00562 pid = syscalls::fork();
579
- <a name="l00563"></a>00563 <span class="keywordflow">if</span> (pid == 0) { <span class="comment">// Child process.</span>
580
- <a name="l00564"></a>00564 dup2(STDERR_FILENO, STDOUT_FILENO); <span class="comment">// Redirect stdout to the same channel as stderr.</span>
581
- <a name="l00565"></a>00565 dup2(fds[0], SERVER_SOCKET_FD);
582
- <a name="l00566"></a>00566
583
- <a name="l00567"></a>00567 <span class="comment">// Close all unnecessary file descriptors</span>
584
- <a name="l00568"></a>00568 <span class="keywordflow">for</span> (<span class="keywordtype">long</span> i = sysconf(_SC_OPEN_MAX) - 1; i &gt; SERVER_SOCKET_FD; i--) {
585
- <a name="l00569"></a>00569 close(i);
586
- <a name="l00570"></a>00570 }
587
- <a name="l00571"></a>00571
588
- <a name="l00572"></a>00572 execlp(
589
- <a name="l00573"></a>00573 #<span class="keywordflow">if</span> 0
590
- <a name="l00574"></a>00574 <span class="stringliteral">"valgrind"</span>,
591
- <a name="l00575"></a>00575 <span class="stringliteral">"valgrind"</span>,
592
- <a name="l00576"></a>00576 #<span class="keywordflow">else</span>
593
- <a name="l00577"></a>00577 m_serverExecutable.c_str(),
594
- <a name="l00578"></a>00578 <span class="preprocessor"> #endif</span>
595
- <a name="l00579"></a>00579 <span class="preprocessor"></span> m_serverExecutable.c_str(),
596
- <a name="l00580"></a>00580 <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(Passenger::getLogLevel()).c_str(),
597
- <a name="l00581"></a>00581 m_spawnServerCommand.c_str(),
598
- <a name="l00582"></a>00582 m_logFile.c_str(),
599
- <a name="l00583"></a>00583 m_rubyCommand.c_str(),
600
- <a name="l00584"></a>00584 m_user.c_str(),
601
- <a name="l00585"></a>00585 statusReportFIFO.c_str(),
602
- <a name="l00586"></a>00586 (<span class="keywordtype">char</span> *) 0);
603
- <a name="l00587"></a>00587 <span class="keywordtype">int</span> e = errno;
604
- <a name="l00588"></a>00588 fprintf(stderr, <span class="stringliteral">"*** Passenger ERROR (%s:%d):\n"</span>
605
- <a name="l00589"></a>00589 <span class="stringliteral">"Cannot execute %s: %s (%d)\n"</span>,
606
- <a name="l00590"></a>00590 __FILE__, __LINE__,
607
- <a name="l00591"></a>00591 m_serverExecutable.c_str(), strerror(e), e);
608
- <a name="l00592"></a>00592 fflush(stderr);
609
- <a name="l00593"></a>00593 _exit(1);
610
- <a name="l00594"></a>00594 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (pid == -1) { <span class="comment">// Error.</span>
611
- <a name="l00595"></a>00595 syscalls::close(fds[0]);
612
- <a name="l00596"></a>00596 syscalls::close(fds[1]);
613
- <a name="l00597"></a>00597 <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">"Cannot create a new process"</span>, errno);
614
- <a name="l00598"></a>00598 } <span class="keywordflow">else</span> { <span class="comment">// Parent process.</span>
615
- <a name="l00599"></a>00599 syscalls::close(fds[0]);
616
- <a name="l00600"></a>00600 serverSocket = fds[1];
617
- <a name="l00601"></a>00601
618
- <a name="l00602"></a>00602 <span class="keywordtype">int</span> flags = fcntl(serverSocket, F_GETFD);
619
- <a name="l00603"></a>00603 <span class="keywordflow">if</span> (flags != -1) {
620
- <a name="l00604"></a>00604 fcntl(serverSocket, F_SETFD, flags | FD_CLOEXEC);
621
- <a name="l00605"></a>00605 }
622
- <a name="l00606"></a>00606
623
- <a name="l00607"></a>00607 serverPid = pid;
624
- <a name="l00608"></a>00608 }
625
- <a name="l00609"></a>00609 }
626
- <a name="l00610"></a>00610
627
- <a name="l00611"></a>00611 <span class="keywordtype">void</span> createStatusReportFIFO() {
628
- <a name="l00612"></a>00612 TRACE_POINT();
629
- <a name="l00613"></a>00613 <span class="keywordtype">char</span> filename[PATH_MAX];
630
- <a name="l00614"></a>00614 <span class="keywordtype">int</span> ret;
631
- <a name="l00615"></a>00615 mode_t permissions;
632
- <a name="l00616"></a>00616
633
- <a name="l00617"></a>00617 createPassengerTempDir();
634
- <a name="l00618"></a>00618
635
- <a name="l00619"></a>00619 <span class="keywordflow">if</span> (m_user.empty()) {
636
- <a name="l00620"></a>00620 permissions = S_IRUSR | S_IWUSR;
637
- <a name="l00621"></a>00621 } <span class="keywordflow">else</span> {
638
- <a name="l00622"></a>00622 permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
477
+ <a name="l00461"></a>00461 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> SERVER_SOCKET_FD = 3;
478
+ <a name="l00462"></a>00462
479
+ <a name="l00463"></a>00463 <span class="keywordtype">string</span> m_serverExecutable;
480
+ <a name="l00464"></a>00464 <span class="keywordtype">string</span> m_spawnServerCommand;
481
+ <a name="l00465"></a>00465 <span class="keywordtype">string</span> m_logFile;
482
+ <a name="l00466"></a>00466 <span class="keywordtype">string</span> m_rubyCommand;
483
+ <a name="l00467"></a>00467 <span class="keywordtype">string</span> m_user;
484
+ <a name="l00468"></a>00468 <span class="keywordtype">string</span> statusReportFIFO;
485
+ <a name="l00469"></a>00469 <span class="comment"></span>
486
+ <a name="l00470"></a>00470 <span class="comment"> /**</span>
487
+ <a name="l00471"></a>00471 <span class="comment"> * The PID of the ApplicationPool server process. If no server process</span>
488
+ <a name="l00472"></a>00472 <span class="comment"> * is running, then &lt;tt&gt;serverPid == 0&lt;/tt&gt;.</span>
489
+ <a name="l00473"></a>00473 <span class="comment"> *</span>
490
+ <a name="l00474"></a>00474 <span class="comment"> * @invariant</span>
491
+ <a name="l00475"></a>00475 <span class="comment"> * if serverPid == 0:</span>
492
+ <a name="l00476"></a>00476 <span class="comment"> * serverSocket == -1</span>
493
+ <a name="l00477"></a>00477 <span class="comment"> */</span>
494
+ <a name="l00478"></a>00478 pid_t serverPid;
495
+ <a name="l00479"></a>00479 <span class="comment"></span>
496
+ <a name="l00480"></a>00480 <span class="comment"> /**</span>
497
+ <a name="l00481"></a>00481 <span class="comment"> * The connection to the ApplicationPool server process. If no server</span>
498
+ <a name="l00482"></a>00482 <span class="comment"> * process is running, then &lt;tt&gt;serverSocket == -1&lt;/tt&gt;.</span>
499
+ <a name="l00483"></a>00483 <span class="comment"> *</span>
500
+ <a name="l00484"></a>00484 <span class="comment"> * @invariant</span>
501
+ <a name="l00485"></a>00485 <span class="comment"> * if serverPid == 0:</span>
502
+ <a name="l00486"></a>00486 <span class="comment"> * serverSocket == -1</span>
503
+ <a name="l00487"></a>00487 <span class="comment"> */</span>
504
+ <a name="l00488"></a>00488 <span class="keywordtype">int</span> serverSocket;
505
+ <a name="l00489"></a>00489 <span class="comment"></span>
506
+ <a name="l00490"></a>00490 <span class="comment"> /**</span>
507
+ <a name="l00491"></a>00491 <span class="comment"> * Shutdown the currently running ApplicationPool server process.</span>
508
+ <a name="l00492"></a>00492 <span class="comment"> *</span>
509
+ <a name="l00493"></a>00493 <span class="comment"> * @pre System call interruption is disabled.</span>
510
+ <a name="l00494"></a>00494 <span class="comment"> * @pre serverSocket != -1 &amp;&amp; serverPid != 0</span>
511
+ <a name="l00495"></a>00495 <span class="comment"> * @post serverSocket == -1 &amp;&amp; serverPid == 0</span>
512
+ <a name="l00496"></a>00496 <span class="comment"> */</span>
513
+ <a name="l00497"></a>00497 <span class="keywordtype">void</span> shutdownServer() {
514
+ <a name="l00498"></a>00498 TRACE_POINT();
515
+ <a name="l00499"></a>00499 this_thread::disable_syscall_interruption dsi;
516
+ <a name="l00500"></a>00500 <span class="keywordtype">int</span> ret, status;
517
+ <a name="l00501"></a>00501 time_t begin;
518
+ <a name="l00502"></a>00502 <span class="keywordtype">bool</span> done = <span class="keyword">false</span>;
519
+ <a name="l00503"></a>00503
520
+ <a name="l00504"></a>00504 syscalls::close(serverSocket);
521
+ <a name="l00505"></a>00505 <span class="keywordflow">if</span> (!statusReportFIFO.empty()) {
522
+ <a name="l00506"></a>00506 <span class="keywordflow">do</span> {
523
+ <a name="l00507"></a>00507 ret = unlink(statusReportFIFO.c_str());
524
+ <a name="l00508"></a>00508 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
525
+ <a name="l00509"></a>00509 }
526
+ <a name="l00510"></a>00510
527
+ <a name="l00511"></a>00511 P_TRACE(2, <span class="stringliteral">"Waiting for existing ApplicationPoolServerExecutable (PID "</span> &lt;&lt;
528
+ <a name="l00512"></a>00512 serverPid &lt;&lt; <span class="stringliteral">") to exit..."</span>);
529
+ <a name="l00513"></a>00513 begin = syscalls::time(NULL);
530
+ <a name="l00514"></a>00514 <span class="keywordflow">while</span> (!done &amp;&amp; syscalls::time(NULL) &lt; begin + 5) {
531
+ <a name="l00515"></a>00515 <span class="comment">/*</span>
532
+ <a name="l00516"></a>00516 <span class="comment"> * Some Apache modules fork(), but don't close file descriptors.</span>
533
+ <a name="l00517"></a>00517 <span class="comment"> * mod_wsgi is one such example. Because of that, closing serverSocket</span>
534
+ <a name="l00518"></a>00518 <span class="comment"> * won't always cause the ApplicationPool server to exit. So we send it a</span>
535
+ <a name="l00519"></a>00519 <span class="comment"> * signal. This must be the same as the oxt/system_calls.hpp interruption</span>
536
+ <a name="l00520"></a>00520 <span class="comment"> * signal.</span>
537
+ <a name="l00521"></a>00521 <span class="comment"> */</span>
538
+ <a name="l00522"></a>00522 syscalls::kill(serverPid, SIGINT);
539
+ <a name="l00523"></a>00523
540
+ <a name="l00524"></a>00524 ret = syscalls::waitpid(serverPid, &amp;status, WNOHANG);
541
+ <a name="l00525"></a>00525 done = ret &gt; 0 || ret == -1;
542
+ <a name="l00526"></a>00526 <span class="keywordflow">if</span> (!done) {
543
+ <a name="l00527"></a>00527 syscalls::usleep(100000);
544
+ <a name="l00528"></a>00528 }
545
+ <a name="l00529"></a>00529 }
546
+ <a name="l00530"></a>00530 <span class="keywordflow">if</span> (done) {
547
+ <a name="l00531"></a>00531 <span class="keywordflow">if</span> (ret &gt; 0) {
548
+ <a name="l00532"></a>00532 <span class="keywordflow">if</span> (WIFEXITED(status)) {
549
+ <a name="l00533"></a>00533 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited with exit status "</span> &lt;&lt;
550
+ <a name="l00534"></a>00534 WEXITSTATUS(status) &lt;&lt; <span class="stringliteral">"."</span>);
551
+ <a name="l00535"></a>00535 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (WIFSIGNALED(status)) {
552
+ <a name="l00536"></a>00536 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited because of signal "</span> &lt;&lt;
553
+ <a name="l00537"></a>00537 WTERMSIG(status) &lt;&lt; <span class="stringliteral">"."</span>);
554
+ <a name="l00538"></a>00538 } <span class="keywordflow">else</span> {
555
+ <a name="l00539"></a>00539 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited for an unknown reason."</span>);
556
+ <a name="l00540"></a>00540 }
557
+ <a name="l00541"></a>00541 } <span class="keywordflow">else</span> {
558
+ <a name="l00542"></a>00542 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited."</span>);
559
+ <a name="l00543"></a>00543 }
560
+ <a name="l00544"></a>00544 } <span class="keywordflow">else</span> {
561
+ <a name="l00545"></a>00545 P_DEBUG(<span class="stringliteral">"ApplicationPoolServerExecutable not exited in time. Killing it..."</span>);
562
+ <a name="l00546"></a>00546 syscalls::kill(serverPid, SIGKILL);
563
+ <a name="l00547"></a>00547 syscalls::waitpid(serverPid, NULL, 0);
564
+ <a name="l00548"></a>00548 }
565
+ <a name="l00549"></a>00549
566
+ <a name="l00550"></a>00550 serverSocket = -1;
567
+ <a name="l00551"></a>00551 serverPid = 0;
568
+ <a name="l00552"></a>00552 }
569
+ <a name="l00553"></a>00553 <span class="comment"></span>
570
+ <a name="l00554"></a>00554 <span class="comment"> /**</span>
571
+ <a name="l00555"></a>00555 <span class="comment"> * Start an ApplicationPool server process. If there's already one running,</span>
572
+ <a name="l00556"></a>00556 <span class="comment"> * then the currently running one will be shutdown.</span>
573
+ <a name="l00557"></a>00557 <span class="comment"> *</span>
574
+ <a name="l00558"></a>00558 <span class="comment"> * @pre System call interruption is disabled.</span>
575
+ <a name="l00559"></a>00559 <span class="comment"> * @post serverSocket != -1 &amp;&amp; serverPid != 0</span>
576
+ <a name="l00560"></a>00560 <span class="comment"> * @throw SystemException Something went wrong.</span>
577
+ <a name="l00561"></a>00561 <span class="comment"> */</span>
578
+ <a name="l00562"></a>00562 <span class="keywordtype">void</span> restartServer() {
579
+ <a name="l00563"></a>00563 TRACE_POINT();
580
+ <a name="l00564"></a>00564 <span class="keywordtype">int</span> fds[2];
581
+ <a name="l00565"></a>00565 pid_t pid;
582
+ <a name="l00566"></a>00566
583
+ <a name="l00567"></a>00567 <span class="keywordflow">if</span> (serverPid != 0) {
584
+ <a name="l00568"></a>00568 shutdownServer();
585
+ <a name="l00569"></a>00569 }
586
+ <a name="l00570"></a>00570
587
+ <a name="l00571"></a>00571 <span class="keywordflow">if</span> (syscalls::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
588
+ <a name="l00572"></a>00572 <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">"Cannot create a Unix socket pair"</span>, errno);
589
+ <a name="l00573"></a>00573 }
590
+ <a name="l00574"></a>00574
591
+ <a name="l00575"></a>00575 createStatusReportFIFO();
592
+ <a name="l00576"></a>00576
593
+ <a name="l00577"></a>00577 pid = syscalls::fork();
594
+ <a name="l00578"></a>00578 <span class="keywordflow">if</span> (pid == 0) { <span class="comment">// Child process.</span>
595
+ <a name="l00579"></a>00579 dup2(STDERR_FILENO, STDOUT_FILENO); <span class="comment">// Redirect stdout to the same channel as stderr.</span>
596
+ <a name="l00580"></a>00580 dup2(fds[0], SERVER_SOCKET_FD);
597
+ <a name="l00581"></a>00581
598
+ <a name="l00582"></a>00582 <span class="comment">// Close all unnecessary file descriptors</span>
599
+ <a name="l00583"></a>00583 <span class="keywordflow">for</span> (<span class="keywordtype">long</span> i = sysconf(_SC_OPEN_MAX) - 1; i &gt; SERVER_SOCKET_FD; i--) {
600
+ <a name="l00584"></a>00584 close(i);
601
+ <a name="l00585"></a>00585 }
602
+ <a name="l00586"></a>00586
603
+ <a name="l00587"></a>00587 execlp(
604
+ <a name="l00588"></a>00588 #<span class="keywordflow">if</span> 0
605
+ <a name="l00589"></a>00589 <span class="stringliteral">"valgrind"</span>,
606
+ <a name="l00590"></a>00590 <span class="stringliteral">"valgrind"</span>,
607
+ <a name="l00591"></a>00591 #<span class="keywordflow">else</span>
608
+ <a name="l00592"></a>00592 m_serverExecutable.c_str(),
609
+ <a name="l00593"></a>00593 <span class="preprocessor"> #endif</span>
610
+ <a name="l00594"></a>00594 <span class="preprocessor"></span> m_serverExecutable.c_str(),
611
+ <a name="l00595"></a>00595 <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(Passenger::getLogLevel()).c_str(),
612
+ <a name="l00596"></a>00596 m_spawnServerCommand.c_str(),
613
+ <a name="l00597"></a>00597 m_logFile.c_str(),
614
+ <a name="l00598"></a>00598 m_rubyCommand.c_str(),
615
+ <a name="l00599"></a>00599 m_user.c_str(),
616
+ <a name="l00600"></a>00600 statusReportFIFO.c_str(),
617
+ <a name="l00601"></a>00601 (<span class="keywordtype">char</span> *) 0);
618
+ <a name="l00602"></a>00602 <span class="keywordtype">int</span> e = errno;
619
+ <a name="l00603"></a>00603 fprintf(stderr, <span class="stringliteral">"*** Passenger ERROR (%s:%d):\n"</span>
620
+ <a name="l00604"></a>00604 <span class="stringliteral">"Cannot execute %s: %s (%d)\n"</span>,
621
+ <a name="l00605"></a>00605 __FILE__, __LINE__,
622
+ <a name="l00606"></a>00606 m_serverExecutable.c_str(), strerror(e), e);
623
+ <a name="l00607"></a>00607 fflush(stderr);
624
+ <a name="l00608"></a>00608 _exit(1);
625
+ <a name="l00609"></a>00609 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (pid == -1) { <span class="comment">// Error.</span>
626
+ <a name="l00610"></a>00610 syscalls::close(fds[0]);
627
+ <a name="l00611"></a>00611 syscalls::close(fds[1]);
628
+ <a name="l00612"></a>00612 <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">"Cannot create a new process"</span>, errno);
629
+ <a name="l00613"></a>00613 } <span class="keywordflow">else</span> { <span class="comment">// Parent process.</span>
630
+ <a name="l00614"></a>00614 syscalls::close(fds[0]);
631
+ <a name="l00615"></a>00615 serverSocket = fds[1];
632
+ <a name="l00616"></a>00616
633
+ <a name="l00617"></a>00617 <span class="keywordtype">int</span> flags = fcntl(serverSocket, F_GETFD);
634
+ <a name="l00618"></a>00618 <span class="keywordflow">if</span> (flags != -1) {
635
+ <a name="l00619"></a>00619 fcntl(serverSocket, F_SETFD, flags | FD_CLOEXEC);
636
+ <a name="l00620"></a>00620 }
637
+ <a name="l00621"></a>00621
638
+ <a name="l00622"></a>00622 serverPid = pid;
639
639
  <a name="l00623"></a>00623 }
640
- <a name="l00624"></a>00624
641
- <a name="l00625"></a>00625 snprintf(filename, <span class="keyword">sizeof</span>(filename), <span class="stringliteral">"%s/status.fifo"</span>,
642
- <a name="l00626"></a>00626 <a class="code" href="group__Support.html#g5d3a5c5fe2944a898e425e30b53ac0ac" title="Return the path name for the directory in which Phusion Passenger-specific temporary...">getPassengerTempDir</a>().c_str());
643
- <a name="l00627"></a>00627 filename[PATH_MAX - 1] = <span class="charliteral">'\0'</span>;
644
- <a name="l00628"></a>00628 <span class="keywordflow">do</span> {
645
- <a name="l00629"></a>00629 ret = mkfifo(filename, permissions);
646
- <a name="l00630"></a>00630 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
647
- <a name="l00631"></a>00631 <span class="keywordflow">if</span> (ret == -1 &amp;&amp; errno != EEXIST) {
648
- <a name="l00632"></a>00632 <span class="keywordtype">int</span> e = errno;
649
- <a name="l00633"></a>00633 P_WARN(<span class="stringliteral">"*** WARNING: Could not create FIFO '"</span> &lt;&lt; filename &lt;&lt;
650
- <a name="l00634"></a>00634 <span class="stringliteral">"': "</span> &lt;&lt; strerror(e) &lt;&lt; <span class="stringliteral">" ("</span> &lt;&lt; e &lt;&lt; <span class="stringliteral">")"</span> &lt;&lt; endl &lt;&lt;
651
- <a name="l00635"></a>00635 <span class="stringliteral">"Disabling Passenger ApplicationPool status reporting."</span>);
652
- <a name="l00636"></a>00636 statusReportFIFO = <span class="stringliteral">""</span>;
653
- <a name="l00637"></a>00637 } <span class="keywordflow">else</span> {
654
- <a name="l00638"></a>00638 statusReportFIFO = filename;
655
- <a name="l00639"></a>00639
656
- <a name="l00640"></a>00640 <span class="comment">// It seems that the permissions passed to mkfifo()</span>
657
- <a name="l00641"></a>00641 <span class="comment">// aren't respected, so here we chmod the file.</span>
658
- <a name="l00642"></a>00642 <span class="keywordflow">do</span> {
659
- <a name="l00643"></a>00643 ret = chmod(filename, permissions);
660
- <a name="l00644"></a>00644 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
661
- <a name="l00645"></a>00645 }
662
- <a name="l00646"></a>00646 }
663
- <a name="l00647"></a>00647
664
- <a name="l00648"></a>00648 <span class="keyword">public</span>:<span class="comment"></span>
665
- <a name="l00649"></a>00649 <span class="comment"> /**</span>
666
- <a name="l00650"></a>00650 <span class="comment"> * Create a new ApplicationPoolServer object.</span>
667
- <a name="l00651"></a>00651 <span class="comment"> *</span>
668
- <a name="l00652"></a>00652 <span class="comment"> * @param serverExecutable The filename of the ApplicationPool server</span>
669
- <a name="l00653"></a>00653 <span class="comment"> * executable to use.</span>
670
- <a name="l00654"></a>00654 <span class="comment"> * @param spawnServerCommand The filename of the spawn server to use.</span>
671
- <a name="l00655"></a>00655 <span class="comment"> * @param logFile Specify a log file that the spawn server should use.</span>
672
- <a name="l00656"></a>00656 <span class="comment"> * Messages on its standard output and standard error channels</span>
673
- <a name="l00657"></a>00657 <span class="comment"> * will be written to this log file. If an empty string is</span>
674
- <a name="l00658"></a>00658 <span class="comment"> * specified, no log file will be used, and the spawn server</span>
675
- <a name="l00659"></a>00659 <span class="comment"> * will use the same standard output/error channels as the</span>
676
- <a name="l00660"></a>00660 <span class="comment"> * current process.</span>
677
- <a name="l00661"></a>00661 <span class="comment"> * @param rubyCommand The Ruby interpreter's command.</span>
678
- <a name="l00662"></a>00662 <span class="comment"> * @param user The user that the spawn manager should run as. This</span>
679
- <a name="l00663"></a>00663 <span class="comment"> * parameter only has effect if the current process is</span>
680
- <a name="l00664"></a>00664 <span class="comment"> * running as root. If the empty string is given, or if</span>
681
- <a name="l00665"></a>00665 <span class="comment"> * the &lt;tt&gt;user&lt;/tt&gt; is not a valid username, then</span>
682
- <a name="l00666"></a>00666 <span class="comment"> * the spawn manager will be run as the current user.</span>
683
- <a name="l00667"></a>00667 <span class="comment"> * @throws SystemException An error occured while trying to setup the spawn server</span>
684
- <a name="l00668"></a>00668 <span class="comment"> * or the server socket.</span>
685
- <a name="l00669"></a>00669 <span class="comment"> * @throws IOException The specified log file could not be opened.</span>
686
- <a name="l00670"></a>00670 <span class="comment"> */</span>
687
- <a name="l00671"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html#2203db62a022579d569ceddff8ef6ca9">00671</a> <a class="code" href="classPassenger_1_1ApplicationPoolServer.html#2203db62a022579d569ceddff8ef6ca9" title="Create a new ApplicationPoolServer object.">ApplicationPoolServer</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;serverExecutable,
688
- <a name="l00672"></a>00672 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;spawnServerCommand,
689
- <a name="l00673"></a>00673 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;logFile = <span class="stringliteral">""</span>,
690
- <a name="l00674"></a>00674 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;rubyCommand = <span class="stringliteral">"ruby"</span>,
691
- <a name="l00675"></a>00675 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;user = <span class="stringliteral">""</span>)
692
- <a name="l00676"></a>00676 : m_serverExecutable(serverExecutable),
693
- <a name="l00677"></a>00677 m_spawnServerCommand(spawnServerCommand),
694
- <a name="l00678"></a>00678 m_logFile(logFile),
695
- <a name="l00679"></a>00679 m_rubyCommand(rubyCommand),
696
- <a name="l00680"></a>00680 m_user(user) {
697
- <a name="l00681"></a>00681 TRACE_POINT();
698
- <a name="l00682"></a>00682 serverSocket = -1;
699
- <a name="l00683"></a>00683 serverPid = 0;
700
- <a name="l00684"></a>00684 this_thread::disable_syscall_interruption dsi;
701
- <a name="l00685"></a>00685 restartServer();
702
- <a name="l00686"></a>00686 }
703
- <a name="l00687"></a>00687
704
- <a name="l00688"></a>00688 ~<a class="code" href="classPassenger_1_1ApplicationPoolServer.html" title="Multi-process usage support for ApplicationPool.">ApplicationPoolServer</a>() {
705
- <a name="l00689"></a>00689 TRACE_POINT();
706
- <a name="l00690"></a>00690 <span class="keywordflow">if</span> (serverSocket != -1) {
707
- <a name="l00691"></a>00691 UPDATE_TRACE_POINT();
708
- <a name="l00692"></a>00692 this_thread::disable_syscall_interruption dsi;
709
- <a name="l00693"></a>00693 shutdownServer();
710
- <a name="l00694"></a>00694 }
711
- <a name="l00695"></a>00695 }
712
- <a name="l00696"></a>00696 <span class="comment"></span>
713
- <a name="l00697"></a>00697 <span class="comment"> /**</span>
714
- <a name="l00698"></a>00698 <span class="comment"> * Connects to the server and returns a usable ApplicationPool object.</span>
715
- <a name="l00699"></a>00699 <span class="comment"> * All cache/pool data of this ApplicationPool is actually stored on</span>
716
- <a name="l00700"></a>00700 <span class="comment"> * the server and shared with other clients, but that is totally</span>
717
- <a name="l00701"></a>00701 <span class="comment"> * transparent to the user of the ApplicationPool object.</span>
718
- <a name="l00702"></a>00702 <span class="comment"> *</span>
719
- <a name="l00703"></a>00703 <span class="comment"> * @note</span>
720
- <a name="l00704"></a>00704 <span class="comment"> * All methods of the returned ApplicationPool object may throw</span>
721
- <a name="l00705"></a>00705 <span class="comment"> * SystemException, IOException or boost::thread_interrupted.</span>
722
- <a name="l00706"></a>00706 <span class="comment"> *</span>
723
- <a name="l00707"></a>00707 <span class="comment"> * @warning</span>
724
- <a name="l00708"></a>00708 <span class="comment"> * One may only use the returned ApplicationPool object for handling</span>
725
- <a name="l00709"></a>00709 <span class="comment"> * one session at a time. For example, don't do stuff like this:</span>
726
- <a name="l00710"></a>00710 <span class="comment"> * @code</span>
727
- <a name="l00711"></a>00711 <span class="comment"> * ApplicationPoolPtr pool = server.connect();</span>
728
- <a name="l00712"></a>00712 <span class="comment"> * Application::SessionPtr session1 = pool-&gt;get(...);</span>
729
- <a name="l00713"></a>00713 <span class="comment"> * Application::SessionPtr session2 = pool-&gt;get(...);</span>
730
- <a name="l00714"></a>00714 <span class="comment"> * @endcode</span>
731
- <a name="l00715"></a>00715 <span class="comment"> * Otherwise, a deadlock can occur under certain circumstances.</span>
732
- <a name="l00716"></a>00716 <span class="comment"> * @warning</span>
733
- <a name="l00717"></a>00717 <span class="comment"> * Instead, one should call connect() multiple times:</span>
734
- <a name="l00718"></a>00718 <span class="comment"> * @code</span>
735
- <a name="l00719"></a>00719 <span class="comment"> * ApplicationPoolPtr pool1 = server.connect();</span>
736
- <a name="l00720"></a>00720 <span class="comment"> * Application::SessionPtr session1 = pool1-&gt;get(...);</span>
737
- <a name="l00721"></a>00721 <span class="comment"> * </span>
738
- <a name="l00722"></a>00722 <span class="comment"> * ApplicationPoolPtr pool2 = server.connect();</span>
739
- <a name="l00723"></a>00723 <span class="comment"> * Application::SessionPtr session2 = pool2-&gt;get(...);</span>
740
- <a name="l00724"></a>00724 <span class="comment"> * @endcode</span>
741
- <a name="l00725"></a>00725 <span class="comment"> *</span>
742
- <a name="l00726"></a>00726 <span class="comment"> * @throws SystemException Something went wrong.</span>
743
- <a name="l00727"></a>00727 <span class="comment"> * @throws IOException Something went wrong.</span>
744
- <a name="l00728"></a>00728 <span class="comment"> */</span>
745
- <a name="l00729"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html#18f77057cc28e7924a8f4d1397aa0468">00729</a> ApplicationPoolPtr <a class="code" href="classPassenger_1_1ApplicationPoolServer.html#18f77057cc28e7924a8f4d1397aa0468" title="Connects to the server and returns a usable ApplicationPool object.">connect</a>() {
746
- <a name="l00730"></a>00730 TRACE_POINT();
747
- <a name="l00731"></a>00731 <span class="keywordflow">try</span> {
748
- <a name="l00732"></a>00732 this_thread::disable_syscall_interruption dsi;
749
- <a name="l00733"></a>00733 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(serverSocket);
750
- <a name="l00734"></a>00734 <span class="keywordtype">int</span> clientConnection;
751
- <a name="l00735"></a>00735
752
- <a name="l00736"></a>00736 <span class="comment">// Write some random data to wake up the server.</span>
753
- <a name="l00737"></a>00737 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="stringliteral">"x"</span>, 1);
754
- <a name="l00738"></a>00738
755
- <a name="l00739"></a>00739 clientConnection = channel.<a class="code" href="classPassenger_1_1MessageChannel.html#1561b7e4a0f4d39ea431f456e5655488" title="Receive a file descriptor, which had been passed over the underlying file descriptor...">readFileDescriptor</a>();
756
- <a name="l00740"></a>00740 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> Client(clientConnection));
757
- <a name="l00741"></a>00741 } <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) {
758
- <a name="l00742"></a>00742 <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">"Could not connect to the ApplicationPool server"</span>, e.<a class="code" href="classPassenger_1_1SystemException.html#ee7a6672bf79b72a4c3ee70c57d6a47c" title="The value of errno at the time the error occured.">code</a>());
759
- <a name="l00743"></a>00743 } <span class="keywordflow">catch</span> (<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) {
760
- <a name="l00744"></a>00744 <span class="keywordtype">string</span> message(<span class="stringliteral">"Could not connect to the ApplicationPool server: "</span>);
761
- <a name="l00745"></a>00745 message.append(e.<a class="code" href="classPassenger_1_1IOException.html#1b65d0fdb9bc5136f5b7df759c14768a">what</a>());
762
- <a name="l00746"></a>00746 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(message);
763
- <a name="l00747"></a>00747 }
764
- <a name="l00748"></a>00748 }
765
- <a name="l00749"></a>00749 <span class="comment"></span>
766
- <a name="l00750"></a>00750 <span class="comment"> /**</span>
767
- <a name="l00751"></a>00751 <span class="comment"> * Detach the server, thereby telling it that we don't want to connect</span>
768
- <a name="l00752"></a>00752 <span class="comment"> * to it anymore. This frees up some resources in the current process,</span>
769
- <a name="l00753"></a>00753 <span class="comment"> * such as file descriptors.</span>
770
- <a name="l00754"></a>00754 <span class="comment"> *</span>
771
- <a name="l00755"></a>00755 <span class="comment"> * This method is particularily useful to Apache worker processes that</span>
772
- <a name="l00756"></a>00756 <span class="comment"> * have just established a connection with the ApplicationPool server.</span>
773
- <a name="l00757"></a>00757 <span class="comment"> * Any sessions that are opened prior to calling detach(), will keep</span>
774
- <a name="l00758"></a>00758 <span class="comment"> * working even after a detach().</span>
775
- <a name="l00759"></a>00759 <span class="comment"> *</span>
776
- <a name="l00760"></a>00760 <span class="comment"> * This method may only be called once. The ApplicationPoolServer object</span>
777
- <a name="l00761"></a>00761 <span class="comment"> * will become unusable once detach() has been called, so call connect()</span>
778
- <a name="l00762"></a>00762 <span class="comment"> * before calling detach().</span>
779
- <a name="l00763"></a>00763 <span class="comment"> */</span>
780
- <a name="l00764"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html#b13957e32ae8ca36ba85f2e6ffefd5ce">00764</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1ApplicationPoolServer.html#b13957e32ae8ca36ba85f2e6ffefd5ce" title="Detach the server, thereby telling it that we don&amp;#39;t want to connect to it anymore...">detach</a>() {
781
- <a name="l00765"></a>00765 TRACE_POINT();
782
- <a name="l00766"></a>00766 <span class="keywordtype">int</span> ret;
783
- <a name="l00767"></a>00767 <span class="keywordflow">do</span> {
784
- <a name="l00768"></a>00768 ret = close(serverSocket);
785
- <a name="l00769"></a>00769 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
786
- <a name="l00770"></a>00770 serverSocket = -1;
787
- <a name="l00771"></a>00771 }
788
- <a name="l00772"></a>00772 };
789
- <a name="l00773"></a>00773
790
- <a name="l00774"></a>00774 <span class="keyword">typedef</span> shared_ptr&lt;ApplicationPoolServer&gt; ApplicationPoolServerPtr;
791
- <a name="l00775"></a>00775
792
- <a name="l00776"></a>00776 } <span class="comment">// namespace Passenger</span>
793
- <a name="l00777"></a>00777
794
- <a name="l00778"></a>00778 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_APPLICATION_POOL_SERVER_H_ */</span>
640
+ <a name="l00624"></a>00624 }
641
+ <a name="l00625"></a>00625
642
+ <a name="l00626"></a>00626 <span class="keywordtype">void</span> createStatusReportFIFO() {
643
+ <a name="l00627"></a>00627 TRACE_POINT();
644
+ <a name="l00628"></a>00628 <span class="keywordtype">char</span> filename[PATH_MAX];
645
+ <a name="l00629"></a>00629 <span class="keywordtype">int</span> ret;
646
+ <a name="l00630"></a>00630 mode_t permissions = S_IRUSR | S_IWUSR;
647
+ <a name="l00631"></a>00631
648
+ <a name="l00632"></a>00632 createPassengerTempDir(<a class="code" href="group__Support.html#g68f4105c5a8e510520b5ea3eecb66213" title="Return the path name for the directory in which the system stores general temporary...">getSystemTempDir</a>(), m_user.empty(),
649
+ <a name="l00633"></a>00633 <span class="stringliteral">"nobody"</span>, geteuid(), getegid());
650
+ <a name="l00634"></a>00634
651
+ <a name="l00635"></a>00635 snprintf(filename, <span class="keyword">sizeof</span>(filename), <span class="stringliteral">"%s/info/status.fifo"</span>,
652
+ <a name="l00636"></a>00636 <a class="code" href="group__Support.html#g69deb6b299b45039dc24b60ad9175541" title="Return the path name for the directory in which Phusion Passenger-specific temporary...">getPassengerTempDir</a>().c_str());
653
+ <a name="l00637"></a>00637 filename[PATH_MAX - 1] = <span class="charliteral">'\0'</span>;
654
+ <a name="l00638"></a>00638 <span class="keywordflow">do</span> {
655
+ <a name="l00639"></a>00639 ret = mkfifo(filename, permissions);
656
+ <a name="l00640"></a>00640 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
657
+ <a name="l00641"></a>00641 <span class="keywordflow">if</span> (ret == -1 &amp;&amp; errno != EEXIST) {
658
+ <a name="l00642"></a>00642 <span class="keywordtype">int</span> e = errno;
659
+ <a name="l00643"></a>00643 P_WARN(<span class="stringliteral">"*** WARNING: Could not create FIFO '"</span> &lt;&lt; filename &lt;&lt;
660
+ <a name="l00644"></a>00644 <span class="stringliteral">"': "</span> &lt;&lt; strerror(e) &lt;&lt; <span class="stringliteral">" ("</span> &lt;&lt; e &lt;&lt; <span class="stringliteral">")"</span> &lt;&lt; endl &lt;&lt;
661
+ <a name="l00645"></a>00645 <span class="stringliteral">"Disabling Passenger ApplicationPool status reporting."</span>);
662
+ <a name="l00646"></a>00646 statusReportFIFO = <span class="stringliteral">""</span>;
663
+ <a name="l00647"></a>00647 } <span class="keywordflow">else</span> {
664
+ <a name="l00648"></a>00648 statusReportFIFO = filename;
665
+ <a name="l00649"></a>00649
666
+ <a name="l00650"></a>00650 <span class="comment">// It seems that the permissions passed to mkfifo()</span>
667
+ <a name="l00651"></a>00651 <span class="comment">// aren't respected, so here we chmod the file.</span>
668
+ <a name="l00652"></a>00652 <span class="keywordflow">do</span> {
669
+ <a name="l00653"></a>00653 ret = chmod(filename, permissions);
670
+ <a name="l00654"></a>00654 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
671
+ <a name="l00655"></a>00655
672
+ <a name="l00656"></a>00656 <span class="comment">// Set the FIFO's owner according to whether we're running as root</span>
673
+ <a name="l00657"></a>00657 <span class="comment">// and whether user switching is enabled.</span>
674
+ <a name="l00658"></a>00658 <span class="keywordflow">if</span> (geteuid() == 0 &amp;&amp; !m_user.empty()) {
675
+ <a name="l00659"></a>00659 uid_t uid;
676
+ <a name="l00660"></a>00660 gid_t gid;
677
+ <a name="l00661"></a>00661
678
+ <a name="l00662"></a>00662 determineLowestUserAndGroup(m_user, uid, gid);
679
+ <a name="l00663"></a>00663 <span class="keywordflow">do</span> {
680
+ <a name="l00664"></a>00664 ret = chown(filename, uid, gid);
681
+ <a name="l00665"></a>00665 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
682
+ <a name="l00666"></a>00666 <span class="keywordflow">if</span> (errno == -1) {
683
+ <a name="l00667"></a>00667 <span class="keywordtype">int</span> e = errno;
684
+ <a name="l00668"></a>00668 P_WARN(<span class="stringliteral">"*** WARNING: Unable to set the FIFO file '"</span> &lt;&lt;
685
+ <a name="l00669"></a>00669 filename &lt;&lt; <span class="stringliteral">"' its owner and group to that of user "</span> &lt;&lt;
686
+ <a name="l00670"></a>00670 m_user &lt;&lt; <span class="stringliteral">": "</span> &lt;&lt; strerror(e) &lt;&lt; <span class="stringliteral">" ("</span> &lt;&lt; e &lt;&lt; <span class="stringliteral">")"</span>);
687
+ <a name="l00671"></a>00671 }
688
+ <a name="l00672"></a>00672 }
689
+ <a name="l00673"></a>00673 }
690
+ <a name="l00674"></a>00674 }
691
+ <a name="l00675"></a>00675
692
+ <a name="l00676"></a>00676 <span class="keyword">public</span>:<span class="comment"></span>
693
+ <a name="l00677"></a>00677 <span class="comment"> /**</span>
694
+ <a name="l00678"></a>00678 <span class="comment"> * Create a new ApplicationPoolServer object.</span>
695
+ <a name="l00679"></a>00679 <span class="comment"> *</span>
696
+ <a name="l00680"></a>00680 <span class="comment"> * @param serverExecutable The filename of the ApplicationPool server</span>
697
+ <a name="l00681"></a>00681 <span class="comment"> * executable to use.</span>
698
+ <a name="l00682"></a>00682 <span class="comment"> * @param spawnServerCommand The filename of the spawn server to use.</span>
699
+ <a name="l00683"></a>00683 <span class="comment"> * @param logFile Specify a log file that the spawn server should use.</span>
700
+ <a name="l00684"></a>00684 <span class="comment"> * Messages on its standard output and standard error channels</span>
701
+ <a name="l00685"></a>00685 <span class="comment"> * will be written to this log file. If an empty string is</span>
702
+ <a name="l00686"></a>00686 <span class="comment"> * specified, no log file will be used, and the spawn server</span>
703
+ <a name="l00687"></a>00687 <span class="comment"> * will use the same standard output/error channels as the</span>
704
+ <a name="l00688"></a>00688 <span class="comment"> * current process.</span>
705
+ <a name="l00689"></a>00689 <span class="comment"> * @param rubyCommand The Ruby interpreter's command.</span>
706
+ <a name="l00690"></a>00690 <span class="comment"> * @param user The user that the spawn manager should run as. This</span>
707
+ <a name="l00691"></a>00691 <span class="comment"> * parameter only has effect if the current process is</span>
708
+ <a name="l00692"></a>00692 <span class="comment"> * running as root. If the empty string is given, or if</span>
709
+ <a name="l00693"></a>00693 <span class="comment"> * the &lt;tt&gt;user&lt;/tt&gt; is not a valid username, then</span>
710
+ <a name="l00694"></a>00694 <span class="comment"> * the spawn manager will be run as the current user.</span>
711
+ <a name="l00695"></a>00695 <span class="comment"> * @throws SystemException An error occured while trying to setup the spawn server</span>
712
+ <a name="l00696"></a>00696 <span class="comment"> * or the server socket.</span>
713
+ <a name="l00697"></a>00697 <span class="comment"> * @throws IOException The specified log file could not be opened.</span>
714
+ <a name="l00698"></a>00698 <span class="comment"> */</span>
715
+ <a name="l00699"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html#2203db62a022579d569ceddff8ef6ca9">00699</a> <a class="code" href="classPassenger_1_1ApplicationPoolServer.html#2203db62a022579d569ceddff8ef6ca9" title="Create a new ApplicationPoolServer object.">ApplicationPoolServer</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;serverExecutable,
716
+ <a name="l00700"></a>00700 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;spawnServerCommand,
717
+ <a name="l00701"></a>00701 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;logFile = <span class="stringliteral">""</span>,
718
+ <a name="l00702"></a>00702 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;rubyCommand = <span class="stringliteral">"ruby"</span>,
719
+ <a name="l00703"></a>00703 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;user = <span class="stringliteral">""</span>)
720
+ <a name="l00704"></a>00704 : m_serverExecutable(serverExecutable),
721
+ <a name="l00705"></a>00705 m_spawnServerCommand(spawnServerCommand),
722
+ <a name="l00706"></a>00706 m_logFile(logFile),
723
+ <a name="l00707"></a>00707 m_rubyCommand(rubyCommand),
724
+ <a name="l00708"></a>00708 m_user(user) {
725
+ <a name="l00709"></a>00709 TRACE_POINT();
726
+ <a name="l00710"></a>00710 serverSocket = -1;
727
+ <a name="l00711"></a>00711 serverPid = 0;
728
+ <a name="l00712"></a>00712 this_thread::disable_syscall_interruption dsi;
729
+ <a name="l00713"></a>00713 restartServer();
730
+ <a name="l00714"></a>00714 }
731
+ <a name="l00715"></a>00715
732
+ <a name="l00716"></a>00716 ~<a class="code" href="classPassenger_1_1ApplicationPoolServer.html" title="Multi-process usage support for ApplicationPool.">ApplicationPoolServer</a>() {
733
+ <a name="l00717"></a>00717 TRACE_POINT();
734
+ <a name="l00718"></a>00718 <span class="keywordflow">if</span> (serverSocket != -1) {
735
+ <a name="l00719"></a>00719 UPDATE_TRACE_POINT();
736
+ <a name="l00720"></a>00720 this_thread::disable_syscall_interruption dsi;
737
+ <a name="l00721"></a>00721 shutdownServer();
738
+ <a name="l00722"></a>00722 }
739
+ <a name="l00723"></a>00723 }
740
+ <a name="l00724"></a>00724 <span class="comment"></span>
741
+ <a name="l00725"></a>00725 <span class="comment"> /**</span>
742
+ <a name="l00726"></a>00726 <span class="comment"> * Connects to the server and returns a usable ApplicationPool object.</span>
743
+ <a name="l00727"></a>00727 <span class="comment"> * All cache/pool data of this ApplicationPool is actually stored on</span>
744
+ <a name="l00728"></a>00728 <span class="comment"> * the server and shared with other clients, but that is totally</span>
745
+ <a name="l00729"></a>00729 <span class="comment"> * transparent to the user of the ApplicationPool object.</span>
746
+ <a name="l00730"></a>00730 <span class="comment"> *</span>
747
+ <a name="l00731"></a>00731 <span class="comment"> * @note</span>
748
+ <a name="l00732"></a>00732 <span class="comment"> * All methods of the returned ApplicationPool object may throw</span>
749
+ <a name="l00733"></a>00733 <span class="comment"> * SystemException, IOException or boost::thread_interrupted.</span>
750
+ <a name="l00734"></a>00734 <span class="comment"> *</span>
751
+ <a name="l00735"></a>00735 <span class="comment"> * @warning</span>
752
+ <a name="l00736"></a>00736 <span class="comment"> * One may only use the returned ApplicationPool object for handling</span>
753
+ <a name="l00737"></a>00737 <span class="comment"> * one session at a time. For example, don't do stuff like this:</span>
754
+ <a name="l00738"></a>00738 <span class="comment"> * @code</span>
755
+ <a name="l00739"></a>00739 <span class="comment"> * ApplicationPoolPtr pool = server.connect();</span>
756
+ <a name="l00740"></a>00740 <span class="comment"> * Application::SessionPtr session1 = pool-&gt;get(...);</span>
757
+ <a name="l00741"></a>00741 <span class="comment"> * Application::SessionPtr session2 = pool-&gt;get(...);</span>
758
+ <a name="l00742"></a>00742 <span class="comment"> * @endcode</span>
759
+ <a name="l00743"></a>00743 <span class="comment"> * Otherwise, a deadlock can occur under certain circumstances.</span>
760
+ <a name="l00744"></a>00744 <span class="comment"> * @warning</span>
761
+ <a name="l00745"></a>00745 <span class="comment"> * Instead, one should call connect() multiple times:</span>
762
+ <a name="l00746"></a>00746 <span class="comment"> * @code</span>
763
+ <a name="l00747"></a>00747 <span class="comment"> * ApplicationPoolPtr pool1 = server.connect();</span>
764
+ <a name="l00748"></a>00748 <span class="comment"> * Application::SessionPtr session1 = pool1-&gt;get(...);</span>
765
+ <a name="l00749"></a>00749 <span class="comment"> * </span>
766
+ <a name="l00750"></a>00750 <span class="comment"> * ApplicationPoolPtr pool2 = server.connect();</span>
767
+ <a name="l00751"></a>00751 <span class="comment"> * Application::SessionPtr session2 = pool2-&gt;get(...);</span>
768
+ <a name="l00752"></a>00752 <span class="comment"> * @endcode</span>
769
+ <a name="l00753"></a>00753 <span class="comment"> *</span>
770
+ <a name="l00754"></a>00754 <span class="comment"> * @throws SystemException Something went wrong.</span>
771
+ <a name="l00755"></a>00755 <span class="comment"> * @throws IOException Something went wrong.</span>
772
+ <a name="l00756"></a>00756 <span class="comment"> */</span>
773
+ <a name="l00757"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html#18f77057cc28e7924a8f4d1397aa0468">00757</a> ApplicationPoolPtr <a class="code" href="classPassenger_1_1ApplicationPoolServer.html#18f77057cc28e7924a8f4d1397aa0468" title="Connects to the server and returns a usable ApplicationPool object.">connect</a>() {
774
+ <a name="l00758"></a>00758 TRACE_POINT();
775
+ <a name="l00759"></a>00759 <span class="keywordflow">try</span> {
776
+ <a name="l00760"></a>00760 this_thread::disable_syscall_interruption dsi;
777
+ <a name="l00761"></a>00761 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(serverSocket);
778
+ <a name="l00762"></a>00762 <span class="keywordtype">int</span> clientConnection;
779
+ <a name="l00763"></a>00763
780
+ <a name="l00764"></a>00764 <span class="comment">// Write some random data to wake up the server.</span>
781
+ <a name="l00765"></a>00765 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="stringliteral">"x"</span>, 1);
782
+ <a name="l00766"></a>00766
783
+ <a name="l00767"></a>00767 clientConnection = channel.<a class="code" href="classPassenger_1_1MessageChannel.html#1561b7e4a0f4d39ea431f456e5655488" title="Receive a file descriptor, which had been passed over the underlying file descriptor...">readFileDescriptor</a>();
784
+ <a name="l00768"></a>00768 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> Client(clientConnection));
785
+ <a name="l00769"></a>00769 } <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) {
786
+ <a name="l00770"></a>00770 <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">"Could not connect to the ApplicationPool server"</span>, e.<a class="code" href="classPassenger_1_1SystemException.html#ee7a6672bf79b72a4c3ee70c57d6a47c" title="The value of errno at the time the error occured.">code</a>());
787
+ <a name="l00771"></a>00771 } <span class="keywordflow">catch</span> (<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) {
788
+ <a name="l00772"></a>00772 <span class="keywordtype">string</span> message(<span class="stringliteral">"Could not connect to the ApplicationPool server: "</span>);
789
+ <a name="l00773"></a>00773 message.append(e.<a class="code" href="classPassenger_1_1IOException.html#1b65d0fdb9bc5136f5b7df759c14768a">what</a>());
790
+ <a name="l00774"></a>00774 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(message);
791
+ <a name="l00775"></a>00775 }
792
+ <a name="l00776"></a>00776 }
793
+ <a name="l00777"></a>00777 <span class="comment"></span>
794
+ <a name="l00778"></a>00778 <span class="comment"> /**</span>
795
+ <a name="l00779"></a>00779 <span class="comment"> * Detach the server, thereby telling it that we don't want to connect</span>
796
+ <a name="l00780"></a>00780 <span class="comment"> * to it anymore. This frees up some resources in the current process,</span>
797
+ <a name="l00781"></a>00781 <span class="comment"> * such as file descriptors.</span>
798
+ <a name="l00782"></a>00782 <span class="comment"> *</span>
799
+ <a name="l00783"></a>00783 <span class="comment"> * This method is particularily useful to Apache worker processes that</span>
800
+ <a name="l00784"></a>00784 <span class="comment"> * have just established a connection with the ApplicationPool server.</span>
801
+ <a name="l00785"></a>00785 <span class="comment"> * Any sessions that are opened prior to calling detach(), will keep</span>
802
+ <a name="l00786"></a>00786 <span class="comment"> * working even after a detach().</span>
803
+ <a name="l00787"></a>00787 <span class="comment"> *</span>
804
+ <a name="l00788"></a>00788 <span class="comment"> * This method may only be called once. The ApplicationPoolServer object</span>
805
+ <a name="l00789"></a>00789 <span class="comment"> * will become unusable once detach() has been called, so call connect()</span>
806
+ <a name="l00790"></a>00790 <span class="comment"> * before calling detach().</span>
807
+ <a name="l00791"></a>00791 <span class="comment"> */</span>
808
+ <a name="l00792"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html#b13957e32ae8ca36ba85f2e6ffefd5ce">00792</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1ApplicationPoolServer.html#b13957e32ae8ca36ba85f2e6ffefd5ce" title="Detach the server, thereby telling it that we don&amp;#39;t want to connect to it anymore...">detach</a>() {
809
+ <a name="l00793"></a>00793 TRACE_POINT();
810
+ <a name="l00794"></a>00794 <span class="keywordtype">int</span> ret;
811
+ <a name="l00795"></a>00795 <span class="keywordflow">do</span> {
812
+ <a name="l00796"></a>00796 ret = close(serverSocket);
813
+ <a name="l00797"></a>00797 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
814
+ <a name="l00798"></a>00798 serverSocket = -1;
815
+ <a name="l00799"></a>00799 }
816
+ <a name="l00800"></a>00800 };
817
+ <a name="l00801"></a>00801
818
+ <a name="l00802"></a>00802 <span class="keyword">typedef</span> shared_ptr&lt;ApplicationPoolServer&gt; ApplicationPoolServerPtr;
819
+ <a name="l00803"></a>00803
820
+ <a name="l00804"></a>00804 } <span class="comment">// namespace Passenger</span>
821
+ <a name="l00805"></a>00805
822
+ <a name="l00806"></a>00806 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_APPLICATION_POOL_SERVER_H_ */</span>
795
823
  </pre></div></div>
796
- <hr size="1"><address style="text-align: right;"><small>Generated on Fri Mar 13 19:24:32 2009 for Passenger by&nbsp;
824
+ <hr size="1"><address style="text-align: right;"><small>Generated on Tue Mar 31 14:00:27 2009 for Passenger by&nbsp;
797
825
  <a href="http://www.doxygen.org/index.html">
798
826
  <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
799
827
  </body>