passenger 2.0.1 → 2.0.2

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 (243) hide show
  1. data/Rakefile +2 -1
  2. data/doc/Security of user switching support.html +1 -1
  3. data/doc/Users guide.html +1 -1
  4. data/ext/apache2/ApplicationPoolServerExecutable.cpp +4 -2
  5. data/ext/apache2/Bucket.cpp +104 -0
  6. data/ext/apache2/Bucket.h +36 -0
  7. data/ext/apache2/Configuration.h +1 -1
  8. data/ext/apache2/Hooks.cpp +2 -5
  9. data/ext/apache2/Utils.h +1 -1
  10. data/ext/boost/non_type.hpp +27 -0
  11. metadata +7 -247
  12. data/doc/Architectural overview.html +0 -740
  13. data/doc/cxxapi/ApplicationPoolServer_8h-source.html +0 -677
  14. data/doc/cxxapi/ApplicationPool_8h-source.html +0 -212
  15. data/doc/cxxapi/Application_8h-source.html +0 -448
  16. data/doc/cxxapi/Configuration_8h-source.html +0 -180
  17. data/doc/cxxapi/DummySpawnManager_8h-source.html +0 -126
  18. data/doc/cxxapi/Exceptions_8h-source.html +0 -244
  19. data/doc/cxxapi/Hooks_8h-source.html +0 -63
  20. data/doc/cxxapi/Logging_8h-source.html +0 -136
  21. data/doc/cxxapi/MessageChannel_8h-source.html +0 -524
  22. data/doc/cxxapi/SpawnManager_8h-source.html +0 -593
  23. data/doc/cxxapi/StandardApplicationPool_8h-source.html +0 -713
  24. data/doc/cxxapi/System_8h-source.html +0 -251
  25. data/doc/cxxapi/Utils_8h-source.html +0 -283
  26. data/doc/cxxapi/annotated.html +0 -59
  27. data/doc/cxxapi/classClient-members.html +0 -35
  28. data/doc/cxxapi/classClient.html +0 -117
  29. data/doc/cxxapi/classDirectoryMapper-members.html +0 -38
  30. data/doc/cxxapi/classDirectoryMapper.html +0 -203
  31. data/doc/cxxapi/classHooks-members.html +0 -33
  32. data/doc/cxxapi/classHooks.html +0 -43
  33. data/doc/cxxapi/classPassenger_1_1Application-members.html +0 -38
  34. data/doc/cxxapi/classPassenger_1_1Application.html +0 -229
  35. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +0 -40
  36. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +0 -331
  37. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +0 -36
  38. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +0 -225
  39. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.map +0 -1
  40. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.md5 +0 -1
  41. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
  42. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +0 -43
  43. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +0 -329
  44. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +0 -33
  45. data/doc/cxxapi/classPassenger_1_1BusyException.html +0 -47
  46. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +0 -33
  47. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +0 -44
  48. data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +0 -33
  49. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +0 -51
  50. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +0 -33
  51. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +0 -51
  52. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.map +0 -1
  53. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.md5 +0 -1
  54. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  55. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +0 -38
  56. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +0 -61
  57. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.map +0 -1
  58. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.md5 +0 -1
  59. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  60. data/doc/cxxapi/classPassenger_1_1IOException-members.html +0 -33
  61. data/doc/cxxapi/classPassenger_1_1IOException.html +0 -54
  62. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.map +0 -1
  63. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.md5 +0 -1
  64. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  65. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +0 -47
  66. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +0 -591
  67. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +0 -35
  68. data/doc/cxxapi/classPassenger_1_1SpawnException.html +0 -77
  69. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +0 -37
  70. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +0 -255
  71. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +0 -42
  72. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +0 -372
  73. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.map +0 -1
  74. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.md5 +0 -1
  75. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
  76. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +0 -37
  77. data/doc/cxxapi/classPassenger_1_1SystemException.html +0 -154
  78. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.map +0 -1
  79. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.md5 +0 -1
  80. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  81. data/doc/cxxapi/classPassenger_1_1TempFile-members.html +0 -36
  82. data/doc/cxxapi/classPassenger_1_1TempFile.html +0 -128
  83. data/doc/cxxapi/classPassenger_1_1Thread-members.html +0 -35
  84. data/doc/cxxapi/classPassenger_1_1Thread.html +0 -100
  85. data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption-members.html +0 -33
  86. data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption.html +0 -46
  87. data/doc/cxxapi/classboost_1_1this__thread_1_1enable__syscall__interruption-members.html +0 -33
  88. data/doc/cxxapi/classboost_1_1this__thread_1_1enable__syscall__interruption.html +0 -44
  89. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption-members.html +0 -33
  90. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption.html +0 -44
  91. data/doc/cxxapi/definitions_8h-source.html +0 -28
  92. data/doc/cxxapi/doxygen.css +0 -433
  93. data/doc/cxxapi/doxygen.png +0 -0
  94. data/doc/cxxapi/files.html +0 -41
  95. data/doc/cxxapi/ftv2blank.png +0 -0
  96. data/doc/cxxapi/ftv2doc.png +0 -0
  97. data/doc/cxxapi/ftv2folderclosed.png +0 -0
  98. data/doc/cxxapi/ftv2folderopen.png +0 -0
  99. data/doc/cxxapi/ftv2lastnode.png +0 -0
  100. data/doc/cxxapi/ftv2link.png +0 -0
  101. data/doc/cxxapi/ftv2mlastnode.png +0 -0
  102. data/doc/cxxapi/ftv2mnode.png +0 -0
  103. data/doc/cxxapi/ftv2node.png +0 -0
  104. data/doc/cxxapi/ftv2plastnode.png +0 -0
  105. data/doc/cxxapi/ftv2pnode.png +0 -0
  106. data/doc/cxxapi/ftv2vertline.png +0 -0
  107. data/doc/cxxapi/functions.html +0 -212
  108. data/doc/cxxapi/functions_func.html +0 -207
  109. data/doc/cxxapi/functions_type.html +0 -46
  110. data/doc/cxxapi/functions_vars.html +0 -48
  111. data/doc/cxxapi/graph_legend.dot +0 -22
  112. data/doc/cxxapi/graph_legend.html +0 -87
  113. data/doc/cxxapi/graph_legend.png +0 -0
  114. data/doc/cxxapi/group__Configuration.html +0 -236
  115. data/doc/cxxapi/group__Configuration.png +0 -0
  116. data/doc/cxxapi/group__Core.html +0 -51
  117. data/doc/cxxapi/group__Core.png +0 -0
  118. data/doc/cxxapi/group__Exceptions.html +0 -43
  119. data/doc/cxxapi/group__Hooks.html +0 -46
  120. data/doc/cxxapi/group__Hooks.png +0 -0
  121. data/doc/cxxapi/group__Support.html +0 -406
  122. data/doc/cxxapi/hierarchy.html +0 -67
  123. data/doc/cxxapi/index.html +0 -11
  124. data/doc/cxxapi/inherit__graph__0.map +0 -1
  125. data/doc/cxxapi/inherit__graph__0.md5 +0 -1
  126. data/doc/cxxapi/inherit__graph__0.png +0 -0
  127. data/doc/cxxapi/inherit__graph__1.map +0 -1
  128. data/doc/cxxapi/inherit__graph__1.md5 +0 -1
  129. data/doc/cxxapi/inherit__graph__1.png +0 -0
  130. data/doc/cxxapi/inherit__graph__10.map +0 -1
  131. data/doc/cxxapi/inherit__graph__10.md5 +0 -1
  132. data/doc/cxxapi/inherit__graph__10.png +0 -0
  133. data/doc/cxxapi/inherit__graph__11.map +0 -1
  134. data/doc/cxxapi/inherit__graph__11.md5 +0 -1
  135. data/doc/cxxapi/inherit__graph__11.png +0 -0
  136. data/doc/cxxapi/inherit__graph__12.map +0 -1
  137. data/doc/cxxapi/inherit__graph__12.md5 +0 -1
  138. data/doc/cxxapi/inherit__graph__12.png +0 -0
  139. data/doc/cxxapi/inherit__graph__13.map +0 -1
  140. data/doc/cxxapi/inherit__graph__13.md5 +0 -1
  141. data/doc/cxxapi/inherit__graph__13.png +0 -0
  142. data/doc/cxxapi/inherit__graph__14.map +0 -2
  143. data/doc/cxxapi/inherit__graph__14.md5 +0 -1
  144. data/doc/cxxapi/inherit__graph__14.png +0 -0
  145. data/doc/cxxapi/inherit__graph__15.map +0 -1
  146. data/doc/cxxapi/inherit__graph__15.md5 +0 -1
  147. data/doc/cxxapi/inherit__graph__15.png +0 -0
  148. data/doc/cxxapi/inherit__graph__16.map +0 -1
  149. data/doc/cxxapi/inherit__graph__16.md5 +0 -1
  150. data/doc/cxxapi/inherit__graph__16.png +0 -0
  151. data/doc/cxxapi/inherit__graph__17.map +0 -1
  152. data/doc/cxxapi/inherit__graph__17.md5 +0 -1
  153. data/doc/cxxapi/inherit__graph__17.png +0 -0
  154. data/doc/cxxapi/inherit__graph__2.map +0 -1
  155. data/doc/cxxapi/inherit__graph__2.md5 +0 -1
  156. data/doc/cxxapi/inherit__graph__2.png +0 -0
  157. data/doc/cxxapi/inherit__graph__3.map +0 -1
  158. data/doc/cxxapi/inherit__graph__3.md5 +0 -1
  159. data/doc/cxxapi/inherit__graph__3.png +0 -0
  160. data/doc/cxxapi/inherit__graph__4.map +0 -1
  161. data/doc/cxxapi/inherit__graph__4.md5 +0 -1
  162. data/doc/cxxapi/inherit__graph__4.png +0 -0
  163. data/doc/cxxapi/inherit__graph__5.map +0 -1
  164. data/doc/cxxapi/inherit__graph__5.md5 +0 -1
  165. data/doc/cxxapi/inherit__graph__5.png +0 -0
  166. data/doc/cxxapi/inherit__graph__6.map +0 -1
  167. data/doc/cxxapi/inherit__graph__6.md5 +0 -1
  168. data/doc/cxxapi/inherit__graph__6.png +0 -0
  169. data/doc/cxxapi/inherit__graph__7.map +0 -1
  170. data/doc/cxxapi/inherit__graph__7.md5 +0 -1
  171. data/doc/cxxapi/inherit__graph__7.png +0 -0
  172. data/doc/cxxapi/inherit__graph__8.map +0 -1
  173. data/doc/cxxapi/inherit__graph__8.md5 +0 -1
  174. data/doc/cxxapi/inherit__graph__8.png +0 -0
  175. data/doc/cxxapi/inherit__graph__9.map +0 -2
  176. data/doc/cxxapi/inherit__graph__9.md5 +0 -1
  177. data/doc/cxxapi/inherit__graph__9.png +0 -0
  178. data/doc/cxxapi/inherits.html +0 -102
  179. data/doc/cxxapi/main.html +0 -27
  180. data/doc/cxxapi/modules.html +0 -34
  181. data/doc/cxxapi/namespacePassenger.html +0 -208
  182. data/doc/cxxapi/namespacePassenger_1_1InterruptableCalls.html +0 -43
  183. data/doc/cxxapi/namespacemembers.html +0 -70
  184. data/doc/cxxapi/namespacemembers_func.html +0 -66
  185. data/doc/cxxapi/namespacemembers_type.html +0 -46
  186. data/doc/cxxapi/namespaces.html +0 -35
  187. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +0 -33
  188. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +0 -49
  189. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +0 -33
  190. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +0 -49
  191. data/doc/cxxapi/tab_b.gif +0 -0
  192. data/doc/cxxapi/tab_l.gif +0 -0
  193. data/doc/cxxapi/tab_r.gif +0 -0
  194. data/doc/cxxapi/tabs.css +0 -102
  195. data/doc/cxxapi/tree.html +0 -166
  196. data/doc/rdoc/classes/ConditionVariable.html +0 -160
  197. data/doc/rdoc/classes/Exception.html +0 -120
  198. data/doc/rdoc/classes/GC.html +0 -113
  199. data/doc/rdoc/classes/IO.html +0 -150
  200. data/doc/rdoc/classes/Passenger.html +0 -136
  201. data/doc/rdoc/classes/Passenger/AbstractRequestHandler.html +0 -401
  202. data/doc/rdoc/classes/Passenger/AbstractServer.html +0 -649
  203. data/doc/rdoc/classes/Passenger/AbstractServer/ServerAlreadyStarted.html +0 -97
  204. data/doc/rdoc/classes/Passenger/AbstractServer/ServerError.html +0 -96
  205. data/doc/rdoc/classes/Passenger/AbstractServer/ServerNotStarted.html +0 -97
  206. data/doc/rdoc/classes/Passenger/AbstractServer/UnknownMessage.html +0 -96
  207. data/doc/rdoc/classes/Passenger/AppInitError.html +0 -137
  208. data/doc/rdoc/classes/Passenger/Application.html +0 -296
  209. data/doc/rdoc/classes/Passenger/ConsoleTextTemplate.html +0 -172
  210. data/doc/rdoc/classes/Passenger/FrameworkInitError.html +0 -143
  211. data/doc/rdoc/classes/Passenger/HTMLTemplate.html +0 -175
  212. data/doc/rdoc/classes/Passenger/InitializationError.html +0 -141
  213. data/doc/rdoc/classes/Passenger/MessageChannel.html +0 -488
  214. data/doc/rdoc/classes/Passenger/NativeSupport.html +0 -320
  215. data/doc/rdoc/classes/Passenger/SpawnManager.html +0 -375
  216. data/doc/rdoc/classes/Passenger/UnknownError.html +0 -125
  217. data/doc/rdoc/classes/Passenger/Utils.html +0 -580
  218. data/doc/rdoc/classes/Passenger/VersionNotFound.html +0 -140
  219. data/doc/rdoc/classes/PlatformInfo.html +0 -292
  220. data/doc/rdoc/classes/RakeExtensions.html +0 -197
  221. data/doc/rdoc/created.rid +0 -1
  222. data/doc/rdoc/files/DEVELOPERS_TXT.html +0 -230
  223. data/doc/rdoc/files/README.html +0 -150
  224. data/doc/rdoc/files/ext/passenger/native_support_c.html +0 -92
  225. data/doc/rdoc/files/lib/passenger/abstract_request_handler_rb.html +0 -125
  226. data/doc/rdoc/files/lib/passenger/abstract_server_rb.html +0 -127
  227. data/doc/rdoc/files/lib/passenger/application_rb.html +0 -123
  228. data/doc/rdoc/files/lib/passenger/console_text_template_rb.html +0 -122
  229. data/doc/rdoc/files/lib/passenger/constants_rb.html +0 -114
  230. data/doc/rdoc/files/lib/passenger/dependencies_rb.html +0 -130
  231. data/doc/rdoc/files/lib/passenger/exceptions_rb.html +0 -118
  232. data/doc/rdoc/files/lib/passenger/html_template_rb.html +0 -122
  233. data/doc/rdoc/files/lib/passenger/message_channel_rb.html +0 -118
  234. data/doc/rdoc/files/lib/passenger/platform_info_rb.html +0 -122
  235. data/doc/rdoc/files/lib/passenger/simple_benchmarking_rb.html +0 -118
  236. data/doc/rdoc/files/lib/passenger/spawn_manager_rb.html +0 -139
  237. data/doc/rdoc/files/lib/passenger/utils_rb.html +0 -130
  238. data/doc/rdoc/files/lib/rake/extensions_rb.html +0 -122
  239. data/doc/rdoc/fr_class_index.html +0 -71
  240. data/doc/rdoc/fr_file_index.html +0 -63
  241. data/doc/rdoc/fr_method_index.html +0 -120
  242. data/doc/rdoc/index.html +0 -26
  243. data/doc/rdoc/rdoc-style.css +0 -187
@@ -1,677 +0,0 @@
1
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
- <html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
3
- <title>Passenger: ApplicationPoolServer.h Source File</title>
4
- <link href="doxygen.css" rel="stylesheet" type="text/css">
5
- <link href="tabs.css" rel="stylesheet" type="text/css">
6
- </head><body>
7
- <!-- Generated by Doxygen 1.5.5 -->
8
- <div class="navigation" id="top">
9
- <div class="tabs">
10
- <ul>
11
- <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
12
- <li><a href="modules.html"><span>Modules</span></a></li>
13
- <li><a href="namespaces.html"><span>Namespaces</span></a></li>
14
- <li><a href="annotated.html"><span>Classes</span></a></li>
15
- <li class="current"><a href="files.html"><span>Files</span></a></li>
16
- </ul>
17
- </div>
18
- <h1>ApplicationPoolServer.h</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
19
- <a name="l00002"></a>00002 <span class="comment"> * Phusion Passenger - http://www.modrails.com/</span>
20
- <a name="l00003"></a>00003 <span class="comment"> * Copyright (C) 2008 Phusion</span>
21
- <a name="l00004"></a>00004 <span class="comment"> *</span>
22
- <a name="l00005"></a>00005 <span class="comment"> * Phusion Passenger is a trademark of Hongli Lai &amp; Ninh Bui.</span>
23
- <a name="l00006"></a>00006 <span class="comment"> *</span>
24
- <a name="l00007"></a>00007 <span class="comment"> * This program is free software; you can redistribute it and/or modify</span>
25
- <a name="l00008"></a>00008 <span class="comment"> * it under the terms of the GNU General Public License as published by</span>
26
- <a name="l00009"></a>00009 <span class="comment"> * the Free Software Foundation; version 2 of the License.</span>
27
- <a name="l00010"></a>00010 <span class="comment"> *</span>
28
- <a name="l00011"></a>00011 <span class="comment"> * This program is distributed in the hope that it will be useful,</span>
29
- <a name="l00012"></a>00012 <span class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
30
- <a name="l00013"></a>00013 <span class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
31
- <a name="l00014"></a>00014 <span class="comment"> * GNU General Public License for more details.</span>
32
- <a name="l00015"></a>00015 <span class="comment"> *</span>
33
- <a name="l00016"></a>00016 <span class="comment"> * You should have received a copy of the GNU General Public License along</span>
34
- <a name="l00017"></a>00017 <span class="comment"> * with this program; if not, write to the Free Software Foundation, Inc.,</span>
35
- <a name="l00018"></a>00018 <span class="comment"> * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span>
36
- <a name="l00019"></a>00019 <span class="comment"> */</span>
37
- <a name="l00020"></a>00020 <span class="preprocessor">#ifndef _PASSENGER_APPLICATION_POOL_SERVER_H_</span>
38
- <a name="l00021"></a>00021 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_APPLICATION_POOL_SERVER_H_</span>
39
- <a name="l00022"></a>00022 <span class="preprocessor"></span>
40
- <a name="l00023"></a>00023 <span class="preprocessor">#include &lt;boost/shared_ptr.hpp&gt;</span>
41
- <a name="l00024"></a>00024 <span class="preprocessor">#include &lt;boost/thread/mutex.hpp&gt;</span>
42
- <a name="l00025"></a>00025
43
- <a name="l00026"></a>00026 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
44
- <a name="l00027"></a>00027 <span class="preprocessor">#include &lt;sys/stat.h&gt;</span>
45
- <a name="l00028"></a>00028 <span class="preprocessor">#include &lt;sys/wait.h&gt;</span>
46
- <a name="l00029"></a>00029 <span class="preprocessor">#include &lt;sys/socket.h&gt;</span>
47
- <a name="l00030"></a>00030 <span class="preprocessor">#include &lt;cstdio&gt;</span>
48
- <a name="l00031"></a>00031 <span class="preprocessor">#include &lt;cstdlib&gt;</span>
49
- <a name="l00032"></a>00032 <span class="preprocessor">#include &lt;limits.h&gt;</span>
50
- <a name="l00033"></a>00033 <span class="preprocessor">#include &lt;errno.h&gt;</span>
51
- <a name="l00034"></a>00034 <span class="preprocessor">#include &lt;unistd.h&gt;</span>
52
- <a name="l00035"></a>00035 <span class="preprocessor">#include &lt;signal.h&gt;</span>
53
- <a name="l00036"></a>00036
54
- <a name="l00037"></a>00037 <span class="preprocessor">#include "MessageChannel.h"</span>
55
- <a name="l00038"></a>00038 <span class="preprocessor">#include "ApplicationPool.h"</span>
56
- <a name="l00039"></a>00039 <span class="preprocessor">#include "Application.h"</span>
57
- <a name="l00040"></a>00040 <span class="preprocessor">#include "Exceptions.h"</span>
58
- <a name="l00041"></a>00041 <span class="preprocessor">#include "Logging.h"</span>
59
- <a name="l00042"></a>00042 <span class="preprocessor">#include "System.h"</span>
60
- <a name="l00043"></a>00043
61
- <a name="l00044"></a>00044 <span class="keyword">namespace </span>Passenger {
62
- <a name="l00045"></a>00045
63
- <a name="l00046"></a>00046 <span class="keyword">using namespace </span>std;
64
- <a name="l00047"></a>00047 <span class="keyword">using namespace </span>boost;
65
- <a name="l00048"></a>00048
66
- <a name="l00049"></a>00049 <span class="comment"></span>
67
- <a name="l00050"></a>00050 <span class="comment">/**</span>
68
- <a name="l00051"></a>00051 <span class="comment"> * Multi-process usage support for ApplicationPool.</span>
69
- <a name="l00052"></a>00052 <span class="comment"> *</span>
70
- <a name="l00053"></a>00053 <span class="comment"> * ApplicationPoolServer implements a client/server architecture for ApplicationPool.</span>
71
- <a name="l00054"></a>00054 <span class="comment"> * This allows one to use ApplicationPool in a multi-process environment (unlike</span>
72
- <a name="l00055"></a>00055 <span class="comment"> * StandardApplicationPool). The cache/pool data is stored in the server. Different</span>
73
- <a name="l00056"></a>00056 <span class="comment"> * processes can then access the pool through the server.</span>
74
- <a name="l00057"></a>00057 <span class="comment"> *</span>
75
- <a name="l00058"></a>00058 <span class="comment"> * ApplicationPoolServer itself does not inherit ApplicationPool. Instead, it returns</span>
76
- <a name="l00059"></a>00059 <span class="comment"> * an ApplicationPool object via the connect() call. For example:</span>
77
- <a name="l00060"></a>00060 <span class="comment"> * @code</span>
78
- <a name="l00061"></a>00061 <span class="comment"> * // Create an ApplicationPoolServer.</span>
79
- <a name="l00062"></a>00062 <span class="comment"> * ApplicationPoolServer server(...);</span>
80
- <a name="l00063"></a>00063 <span class="comment"> * </span>
81
- <a name="l00064"></a>00064 <span class="comment"> * // Now fork a child process, like Apache's prefork MPM eventually will.</span>
82
- <a name="l00065"></a>00065 <span class="comment"> * pid_t pid = fork();</span>
83
- <a name="l00066"></a>00066 <span class="comment"> * if (pid == 0) {</span>
84
- <a name="l00067"></a>00067 <span class="comment"> * // Child process</span>
85
- <a name="l00068"></a>00068 <span class="comment"> * </span>
86
- <a name="l00069"></a>00069 <span class="comment"> * // Connect to the server. After connection, we have an ApplicationPool</span>
87
- <a name="l00070"></a>00070 <span class="comment"> * // object!</span>
88
- <a name="l00071"></a>00071 <span class="comment"> * ApplicationPoolPtr pool(server.connect());</span>
89
- <a name="l00072"></a>00072 <span class="comment"> *</span>
90
- <a name="l00073"></a>00073 <span class="comment"> * // We don't need to connect to the server anymore, so we detach from it.</span>
91
- <a name="l00074"></a>00074 <span class="comment"> * // This frees up some resources, such as file descriptors.</span>
92
- <a name="l00075"></a>00075 <span class="comment"> * server.detach();</span>
93
- <a name="l00076"></a>00076 <span class="comment"> *</span>
94
- <a name="l00077"></a>00077 <span class="comment"> * ApplicationPool::SessionPtr session(pool-&gt;get("/home/webapps/foo"));</span>
95
- <a name="l00078"></a>00078 <span class="comment"> * do_something_with(session);</span>
96
- <a name="l00079"></a>00079 <span class="comment"> *</span>
97
- <a name="l00080"></a>00080 <span class="comment"> * _exit(0);</span>
98
- <a name="l00081"></a>00081 <span class="comment"> * } else {</span>
99
- <a name="l00082"></a>00082 <span class="comment"> * // Parent process</span>
100
- <a name="l00083"></a>00083 <span class="comment"> * waitpid(pid, NULL, 0);</span>
101
- <a name="l00084"></a>00084 <span class="comment"> * }</span>
102
- <a name="l00085"></a>00085 <span class="comment"> * @endcode</span>
103
- <a name="l00086"></a>00086 <span class="comment"> *</span>
104
- <a name="l00087"></a>00087 <span class="comment"> * &lt;h2&gt;Implementation notes&lt;/h2&gt;</span>
105
- <a name="l00088"></a>00088 <span class="comment"> *</span>
106
- <a name="l00089"></a>00089 <span class="comment"> * &lt;h3&gt;Separate server executable&lt;/h3&gt;</span>
107
- <a name="l00090"></a>00090 <span class="comment"> * The actual server is implemented in ApplicationPoolServerExecutable.cpp, this class is</span>
108
- <a name="l00091"></a>00091 <span class="comment"> * just a convenience class for starting/stopping the server executable and connecting</span>
109
- <a name="l00092"></a>00092 <span class="comment"> * to it.</span>
110
- <a name="l00093"></a>00093 <span class="comment"> *</span>
111
- <a name="l00094"></a>00094 <span class="comment"> * In the past, the server logic itself was implemented in this class. This implies that</span>
112
- <a name="l00095"></a>00095 <span class="comment"> * the ApplicationPool server ran inside the Apache process. This presented us with several</span>
113
- <a name="l00096"></a>00096 <span class="comment"> * problems:</span>
114
- <a name="l00097"></a>00097 <span class="comment"> * - Because of the usage of threads in the ApplicationPool server, the Apache VM size would</span>
115
- <a name="l00098"></a>00098 <span class="comment"> * go way up. This gave people the (wrong) impression that Passenger uses a lot of memory,</span>
116
- <a name="l00099"></a>00099 <span class="comment"> * or that it leaks memory.</span>
117
- <a name="l00100"></a>00100 <span class="comment"> * - Although it's not entirely confirmed, we suspect that it caused heap fragmentation as</span>
118
- <a name="l00101"></a>00101 <span class="comment"> * well. Apache allocates lots and lots of small objects on the heap, and ApplicationPool</span>
119
- <a name="l00102"></a>00102 <span class="comment"> * server isn't exactly helping. This too gave people the (wrong) impression that</span>
120
- <a name="l00103"></a>00103 <span class="comment"> * Passenger leaks memory.</span>
121
- <a name="l00104"></a>00104 <span class="comment"> * - It would unnecessarily bloat the VM size of Apache worker processes.</span>
122
- <a name="l00105"></a>00105 <span class="comment"> * - We had to resort to all kinds of tricks to make sure that fork()ing a process doesn't</span>
123
- <a name="l00106"></a>00106 <span class="comment"> * result in file descriptor leaks.</span>
124
- <a name="l00107"></a>00107 <span class="comment"> * - Despite everything, there was still a small chance that file descriptor leaks would</span>
125
- <a name="l00108"></a>00108 <span class="comment"> * occur, and this could not be fixed. The reason for this is that the Apache control</span>
126
- <a name="l00109"></a>00109 <span class="comment"> * process may call fork() right after the ApplicationPool server has established a new</span>
127
- <a name="l00110"></a>00110 <span class="comment"> * connection with a client.</span>
128
- <a name="l00111"></a>00111 <span class="comment"> *</span>
129
- <a name="l00112"></a>00112 <span class="comment"> * Because of these problems, it was decided to split the ApplicationPool server to a</span>
130
- <a name="l00113"></a>00113 <span class="comment"> * separate executable. This comes with no performance hit.</span>
131
- <a name="l00114"></a>00114 <span class="comment"> *</span>
132
- <a name="l00115"></a>00115 <span class="comment"> * &lt;h3&gt;Anonymous server socket&lt;/h3&gt;</span>
133
- <a name="l00116"></a>00116 <span class="comment"> * Notice that ApplicationPoolServer does do not use TCP sockets at all, or even named Unix</span>
134
- <a name="l00117"></a>00117 <span class="comment"> * sockets, despite being a server that can handle multiple clients! So ApplicationPoolServer</span>
135
- <a name="l00118"></a>00118 <span class="comment"> * will expose no open ports or temporary Unix socket files. Only child processes are able</span>
136
- <a name="l00119"></a>00119 <span class="comment"> * to use the ApplicationPoolServer.</span>
137
- <a name="l00120"></a>00120 <span class="comment"> *</span>
138
- <a name="l00121"></a>00121 <span class="comment"> * This is implemented through anonymous Unix sockets (&lt;tt&gt;socketpair()&lt;/tt&gt;) and file descriptor</span>
139
- <a name="l00122"></a>00122 <span class="comment"> * passing. It allows one to emulate &lt;tt&gt;accept()&lt;/tt&gt;. ApplicationPoolServer is connected to</span>
140
- <a name="l00123"></a>00123 <span class="comment"> * the server executable through a Unix socket pair. connect() sends a connect request to the</span>
141
- <a name="l00124"></a>00124 <span class="comment"> * server through that socket. The server will then create a new socket pair, and pass one of</span>
142
- <a name="l00125"></a>00125 <span class="comment"> * them back. This new socket pair represents the newly established connection.</span>
143
- <a name="l00126"></a>00126 <span class="comment"> *</span>
144
- <a name="l00127"></a>00127 <span class="comment"> * @ingroup Support</span>
145
- <a name="l00128"></a>00128 <span class="comment"> */</span>
146
- <a name="l00129"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html">00129</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1ApplicationPoolServer.html" title="Multi-process usage support for ApplicationPool.">ApplicationPoolServer</a> {
147
- <a name="l00130"></a>00130 <span class="keyword">private</span>:<span class="comment"></span>
148
- <a name="l00131"></a>00131 <span class="comment"> /**</span>
149
- <a name="l00132"></a>00132 <span class="comment"> * Contains data shared between RemoteSession and Client.</span>
150
- <a name="l00133"></a>00133 <span class="comment"> * Since RemoteSession and Client have different life times, i.e. one may be</span>
151
- <a name="l00134"></a>00134 <span class="comment"> * destroyed before the other, they both use a smart pointer that points to</span>
152
- <a name="l00135"></a>00135 <span class="comment"> * a SharedData. This way, the SharedData object is only destroyed when</span>
153
- <a name="l00136"></a>00136 <span class="comment"> * both the RemoteSession and the Client object has been destroyed.</span>
154
- <a name="l00137"></a>00137 <span class="comment"> */</span>
155
- <a name="l00138"></a>00138 <span class="keyword">struct </span>SharedData {<span class="comment"></span>
156
- <a name="l00139"></a>00139 <span class="comment"> /**</span>
157
- <a name="l00140"></a>00140 <span class="comment"> * The socket connection to the ApplicationPool server, as was</span>
158
- <a name="l00141"></a>00141 <span class="comment"> * established by ApplicationPoolServer::connect().</span>
159
- <a name="l00142"></a>00142 <span class="comment"> */</span>
160
- <a name="l00143"></a>00143 <span class="keywordtype">int</span> server;
161
- <a name="l00144"></a>00144
162
- <a name="l00145"></a>00145 mutex lock;
163
- <a name="l00146"></a>00146
164
- <a name="l00147"></a>00147 ~SharedData() {
165
- <a name="l00148"></a>00148 <span class="keywordtype">int</span> ret;
166
- <a name="l00149"></a>00149 <span class="keywordflow">do</span> {
167
- <a name="l00150"></a>00150 ret = close(server);
168
- <a name="l00151"></a>00151 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
169
- <a name="l00152"></a>00152 }
170
- <a name="l00153"></a>00153 };
171
- <a name="l00154"></a>00154
172
- <a name="l00155"></a>00155 <span class="keyword">typedef</span> shared_ptr&lt;SharedData&gt; SharedDataPtr;
173
- <a name="l00156"></a>00156 <span class="comment"></span>
174
- <a name="l00157"></a>00157 <span class="comment"> /**</span>
175
- <a name="l00158"></a>00158 <span class="comment"> * An Application::Session which works together with ApplicationPoolServer.</span>
176
- <a name="l00159"></a>00159 <span class="comment"> */</span>
177
- <a name="l00160"></a>00160 <span class="keyword">class </span>RemoteSession: <span class="keyword">public</span> <a class="code" href="classPassenger_1_1Application.html" title="Represents a single Ruby on Rails or Rack application instance.">Application</a>::Session {
178
- <a name="l00161"></a>00161 <span class="keyword">private</span>:
179
- <a name="l00162"></a>00162 SharedDataPtr data;
180
- <a name="l00163"></a>00163 <span class="keywordtype">int</span> id;
181
- <a name="l00164"></a>00164 <span class="keywordtype">int</span> fd;
182
- <a name="l00165"></a>00165 pid_t pid;
183
- <a name="l00166"></a>00166 <span class="keyword">public</span>:
184
- <a name="l00167"></a>00167 RemoteSession(SharedDataPtr data, pid_t pid, <span class="keywordtype">int</span> <span class="keywordtype">id</span>, <span class="keywordtype">int</span> fd) {
185
- <a name="l00168"></a>00168 this-&gt;data = data;
186
- <a name="l00169"></a>00169 this-&gt;pid = pid;
187
- <a name="l00170"></a>00170 this-&gt;<span class="keywordtype">id</span> = id;
188
- <a name="l00171"></a>00171 this-&gt;fd = fd;
189
- <a name="l00172"></a>00172 }
190
- <a name="l00173"></a>00173
191
- <a name="l00174"></a>00174 <span class="keyword">virtual</span> ~RemoteSession() {
192
- <a name="l00175"></a>00175 closeStream();
193
- <a name="l00176"></a>00176 mutex::scoped_lock(data-&gt;lock);
194
- <a name="l00177"></a>00177 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a>(data-&gt;server).write(<span class="stringliteral">"close"</span>, <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(<span class="keywordtype">id</span>).c_str(), NULL);
195
- <a name="l00178"></a>00178 }
196
- <a name="l00179"></a>00179
197
- <a name="l00180"></a>00180 <span class="keyword">virtual</span> <span class="keywordtype">int</span> getStream()<span class="keyword"> const </span>{
198
- <a name="l00181"></a>00181 <span class="keywordflow">return</span> fd;
199
- <a name="l00182"></a>00182 }
200
- <a name="l00183"></a>00183
201
- <a name="l00184"></a>00184 <span class="keyword">virtual</span> <span class="keywordtype">void</span> shutdownReader() {
202
- <a name="l00185"></a>00185 <span class="keywordflow">if</span> (fd != -1) {
203
- <a name="l00186"></a>00186 <span class="keywordtype">int</span> ret = InterruptableCalls::shutdown(fd, SHUT_RD);
204
- <a name="l00187"></a>00187 <span class="keywordflow">if</span> (ret == -1) {
205
- <a name="l00188"></a>00188 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">"Cannot shutdown the writer stream"</span>,
206
- <a name="l00189"></a>00189 errno);
207
- <a name="l00190"></a>00190 }
208
- <a name="l00191"></a>00191 }
209
- <a name="l00192"></a>00192 }
210
- <a name="l00193"></a>00193
211
- <a name="l00194"></a>00194 <span class="keyword">virtual</span> <span class="keywordtype">void</span> shutdownWriter() {
212
- <a name="l00195"></a>00195 <span class="keywordflow">if</span> (fd != -1) {
213
- <a name="l00196"></a>00196 <span class="keywordtype">int</span> ret = InterruptableCalls::shutdown(fd, SHUT_WR);
214
- <a name="l00197"></a>00197 <span class="keywordflow">if</span> (ret == -1) {
215
- <a name="l00198"></a>00198 <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 shutdown the writer stream"</span>,
216
- <a name="l00199"></a>00199 errno);
217
- <a name="l00200"></a>00200 }
218
- <a name="l00201"></a>00201 }
219
- <a name="l00202"></a>00202 }
220
- <a name="l00203"></a>00203
221
- <a name="l00204"></a>00204 <span class="keyword">virtual</span> <span class="keywordtype">void</span> closeStream() {
222
- <a name="l00205"></a>00205 <span class="keywordflow">if</span> (fd != -1) {
223
- <a name="l00206"></a>00206 <span class="keywordtype">int</span> ret = InterruptableCalls::close(fd);
224
- <a name="l00207"></a>00207 <span class="keywordflow">if</span> (ret == -1) {
225
- <a name="l00208"></a>00208 <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 close the session stream"</span>,
226
- <a name="l00209"></a>00209 errno);
227
- <a name="l00210"></a>00210 }
228
- <a name="l00211"></a>00211 fd = -1;
229
- <a name="l00212"></a>00212 }
230
- <a name="l00213"></a>00213 }
231
- <a name="l00214"></a>00214
232
- <a name="l00215"></a>00215 <span class="keyword">virtual</span> <span class="keywordtype">void</span> discardStream() {
233
- <a name="l00216"></a>00216 fd = -1;
234
- <a name="l00217"></a>00217 }
235
- <a name="l00218"></a>00218
236
- <a name="l00219"></a>00219 <span class="keyword">virtual</span> pid_t getPid()<span class="keyword"> const </span>{
237
- <a name="l00220"></a>00220 <span class="keywordflow">return</span> pid;
238
- <a name="l00221"></a>00221 }
239
- <a name="l00222"></a>00222 };
240
- <a name="l00223"></a>00223 <span class="comment"></span>
241
- <a name="l00224"></a>00224 <span class="comment"> /**</span>
242
- <a name="l00225"></a>00225 <span class="comment"> * An ApplicationPool implementation that works together with ApplicationPoolServer.</span>
243
- <a name="l00226"></a>00226 <span class="comment"> * It doesn't do much by itself, its job is mostly to forward queries/commands to</span>
244
- <a name="l00227"></a>00227 <span class="comment"> * the server and returning the result. Most of the logic is in the server executable.</span>
245
- <a name="l00228"></a>00228 <span class="comment"> */</span>
246
- <a name="l00229"></a>00229 <span class="keyword">class </span><a class="code" href="classClient.html#e625bb32c95bde75bfa4bdfdb8ee56db" title="Create a new Client object.">Client</a>: <span class="keyword">public</span> <a class="code" href="classPassenger_1_1ApplicationPool.html" title="A persistent pool of Applications.">ApplicationPool</a> {
247
- <a name="l00230"></a>00230 <span class="keyword">private</span>:
248
- <a name="l00231"></a>00231 <span class="comment">// The smart pointer only serves to keep the shared data alive.</span>
249
- <a name="l00232"></a>00232 <span class="comment">// We access the shared data via a normal pointer, for performance.</span>
250
- <a name="l00233"></a>00233 SharedDataPtr dataSmartPointer;
251
- <a name="l00234"></a>00234 SharedData *data;
252
- <a name="l00235"></a>00235
253
- <a name="l00236"></a>00236 <span class="keyword">public</span>:<span class="comment"></span>
254
- <a name="l00237"></a>00237 <span class="comment"> /**</span>
255
- <a name="l00238"></a>00238 <span class="comment"> * Create a new Client.</span>
256
- <a name="l00239"></a>00239 <span class="comment"> *</span>
257
- <a name="l00240"></a>00240 <span class="comment"> * @param sock The newly established socket connection with the ApplicationPoolServer.</span>
258
- <a name="l00241"></a>00241 <span class="comment"> */</span>
259
- <a name="l00242"></a>00242 Client(<span class="keywordtype">int</span> sock) {
260
- <a name="l00243"></a>00243 dataSmartPointer = <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> SharedData());
261
- <a name="l00244"></a>00244 data = dataSmartPointer.get();
262
- <a name="l00245"></a>00245 data-&gt;server = sock;
263
- <a name="l00246"></a>00246 }
264
- <a name="l00247"></a>00247
265
- <a name="l00248"></a>00248 <span class="keyword">virtual</span> <span class="keywordtype">void</span> clear() {
266
- <a name="l00249"></a>00249 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
267
- <a name="l00250"></a>00250 mutex::scoped_lock l(data-&gt;lock);
268
- <a name="l00251"></a>00251 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"clear"</span>, NULL);
269
- <a name="l00252"></a>00252 }
270
- <a name="l00253"></a>00253
271
- <a name="l00254"></a>00254 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMaxIdleTime(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> seconds) {
272
- <a name="l00255"></a>00255 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
273
- <a name="l00256"></a>00256 mutex::scoped_lock l(data-&gt;lock);
274
- <a name="l00257"></a>00257 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"setMaxIdleTime"</span>, <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(seconds).c_str(), NULL);
275
- <a name="l00258"></a>00258 }
276
- <a name="l00259"></a>00259
277
- <a name="l00260"></a>00260 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMax(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> max) {
278
- <a name="l00261"></a>00261 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
279
- <a name="l00262"></a>00262 mutex::scoped_lock l(data-&gt;lock);
280
- <a name="l00263"></a>00263 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"setMax"</span>, <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(max).c_str(), NULL);
281
- <a name="l00264"></a>00264 }
282
- <a name="l00265"></a>00265
283
- <a name="l00266"></a>00266 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getActive()<span class="keyword"> const </span>{
284
- <a name="l00267"></a>00267 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
285
- <a name="l00268"></a>00268 mutex::scoped_lock l(data-&gt;lock);
286
- <a name="l00269"></a>00269 vector&lt;string&gt; args;
287
- <a name="l00270"></a>00270
288
- <a name="l00271"></a>00271 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"getActive"</span>, NULL);
289
- <a name="l00272"></a>00272 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(args);
290
- <a name="l00273"></a>00273 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g73b17b509ee44938a56bf16cbf82fb48" title="Converts the given string to an integer.">atoi</a>(args[0].c_str());
291
- <a name="l00274"></a>00274 }
292
- <a name="l00275"></a>00275
293
- <a name="l00276"></a>00276 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getCount()<span class="keyword"> const </span>{
294
- <a name="l00277"></a>00277 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
295
- <a name="l00278"></a>00278 mutex::scoped_lock l(data-&gt;lock);
296
- <a name="l00279"></a>00279 vector&lt;string&gt; args;
297
- <a name="l00280"></a>00280
298
- <a name="l00281"></a>00281 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"getCount"</span>, NULL);
299
- <a name="l00282"></a>00282 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(args);
300
- <a name="l00283"></a>00283 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g73b17b509ee44938a56bf16cbf82fb48" title="Converts the given string to an integer.">atoi</a>(args[0].c_str());
301
- <a name="l00284"></a>00284 }
302
- <a name="l00285"></a>00285
303
- <a name="l00286"></a>00286 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMaxPerApp(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> max) {
304
- <a name="l00287"></a>00287 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
305
- <a name="l00288"></a>00288 mutex::scoped_lock l(data-&gt;lock);
306
- <a name="l00289"></a>00289 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"setMaxPerApp"</span>, <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(max).c_str(), NULL);
307
- <a name="l00290"></a>00290 }
308
- <a name="l00291"></a>00291
309
- <a name="l00292"></a>00292 <span class="keyword">virtual</span> pid_t getSpawnServerPid()<span class="keyword"> const </span>{
310
- <a name="l00293"></a>00293 <a class="code" href="classboost_1_1this__thread_1_1disable__syscall__interruption.html" title="Create this struct on the stack to temporarily disable system call interruption,...">this_thread::disable_syscall_interruption</a> dsi;
311
- <a name="l00294"></a>00294 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
312
- <a name="l00295"></a>00295 mutex::scoped_lock l(data-&gt;lock);
313
- <a name="l00296"></a>00296 vector&lt;string&gt; args;
314
- <a name="l00297"></a>00297
315
- <a name="l00298"></a>00298 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"getSpawnServerPid"</span>, NULL);
316
- <a name="l00299"></a>00299 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(args);
317
- <a name="l00300"></a>00300 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g73b17b509ee44938a56bf16cbf82fb48" title="Converts the given string to an integer.">atoi</a>(args[0].c_str());
318
- <a name="l00301"></a>00301 }
319
- <a name="l00302"></a>00302
320
- <a name="l00303"></a>00303 <span class="keyword">virtual</span> <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a> <span class="keyword">get</span>(
321
- <a name="l00304"></a>00304 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot,
322
- <a name="l00305"></a>00305 <span class="keywordtype">bool</span> lowerPrivilege = <span class="keyword">true</span>,
323
- <a name="l00306"></a>00306 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;lowestUser = <span class="stringliteral">"nobody"</span>,
324
- <a name="l00307"></a>00307 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;environment = <span class="stringliteral">"production"</span>,
325
- <a name="l00308"></a>00308 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;spawnMethod = <span class="stringliteral">"smart"</span>,
326
- <a name="l00309"></a>00309 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appType = <span class="stringliteral">"rails"</span>
327
- <a name="l00310"></a>00310 ) {
328
- <a name="l00311"></a>00311 <a class="code" href="classboost_1_1this__thread_1_1disable__syscall__interruption.html" title="Create this struct on the stack to temporarily disable system call interruption,...">this_thread::disable_syscall_interruption</a> dsi;
329
- <a name="l00312"></a>00312 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
330
- <a name="l00313"></a>00313 mutex::scoped_lock l(data-&gt;lock);
331
- <a name="l00314"></a>00314 vector&lt;string&gt; args;
332
- <a name="l00315"></a>00315 <span class="keywordtype">int</span> stream;
333
- <a name="l00316"></a>00316 <span class="keywordtype">bool</span> result;
334
- <a name="l00317"></a>00317
335
- <a name="l00318"></a>00318 <span class="keywordflow">try</span> {
336
- <a name="l00319"></a>00319 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"get"</span>, appRoot.c_str(),
337
- <a name="l00320"></a>00320 (lowerPrivilege) ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>,
338
- <a name="l00321"></a>00321 lowestUser.c_str(),
339
- <a name="l00322"></a>00322 environment.c_str(),
340
- <a name="l00323"></a>00323 spawnMethod.c_str(),
341
- <a name="l00324"></a>00324 appType.c_str(),
342
- <a name="l00325"></a>00325 NULL);
343
- <a name="l00326"></a>00326 } <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;) {
344
- <a name="l00327"></a>00327 <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 exited unexpectedly."</span>);
345
- <a name="l00328"></a>00328 }
346
- <a name="l00329"></a>00329 <span class="keywordflow">try</span> {
347
- <a name="l00330"></a>00330 result = channel.<a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(args);
348
- <a name="l00331"></a>00331 } <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) {
349
- <a name="l00332"></a>00332 <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 read a message from "</span>
350
- <a name="l00333"></a>00333 <span class="stringliteral">"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>());
351
- <a name="l00334"></a>00334 }
352
- <a name="l00335"></a>00335 <span class="keywordflow">if</span> (!result) {
353
- <a name="l00336"></a>00336 <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>
354
- <a name="l00337"></a>00337 <span class="stringliteral">"closed the connection."</span>);
355
- <a name="l00338"></a>00338 }
356
- <a name="l00339"></a>00339 <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"ok"</span>) {
357
- <a name="l00340"></a>00340 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>();
358
- <a name="l00341"></a>00341 <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,
359
- <a name="l00342"></a>00342 <a class="code" href="group__Support.html#g73b17b509ee44938a56bf16cbf82fb48" title="Converts the given string to an integer.">atoi</a>(args[1]), <a class="code" href="group__Support.html#g73b17b509ee44938a56bf16cbf82fb48" title="Converts the given string to an integer.">atoi</a>(args[2]), stream));
360
- <a name="l00343"></a>00343 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"SpawnException"</span>) {
361
- <a name="l00344"></a>00344 <span class="keywordflow">if</span> (args[2] == <span class="stringliteral">"true"</span>) {
362
- <a name="l00345"></a>00345 <span class="keywordtype">string</span> errorPage;
363
- <a name="l00346"></a>00346
364
- <a name="l00347"></a>00347 <span class="keywordflow">if</span> (!channel.<a class="code" href="classPassenger_1_1MessageChannel.html#4ce6a0e751b5e3563bee583c231569bc" title="Read a scalar message from the underlying file descriptor.">readScalar</a>(errorPage)) {
365
- <a name="l00348"></a>00348 <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>
366
- <a name="l00349"></a>00349 <span class="stringliteral">"unexpectedly closed the connection."</span>);
367
- <a name="l00350"></a>00350 }
368
- <a name="l00351"></a>00351 <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);
369
- <a name="l00352"></a>00352 } <span class="keywordflow">else</span> {
370
- <a name="l00353"></a>00353 <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]);
371
- <a name="l00354"></a>00354 }
372
- <a name="l00355"></a>00355 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"BusyException"</span>) {
373
- <a name="l00356"></a>00356 <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]);
374
- <a name="l00357"></a>00357 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"IOException"</span>) {
375
- <a name="l00358"></a>00358 <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]);
376
- <a name="l00359"></a>00359 } <span class="keywordflow">else</span> {
377
- <a name="l00360"></a>00360 <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>
378
- <a name="l00361"></a>00361 <span class="stringliteral">"an unknown message: "</span> + <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(args));
379
- <a name="l00362"></a>00362 }
380
- <a name="l00363"></a>00363 }
381
- <a name="l00364"></a>00364 };
382
- <a name="l00365"></a>00365
383
- <a name="l00366"></a>00366
384
- <a name="l00367"></a>00367 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> SERVER_SOCKET_FD = 3;
385
- <a name="l00368"></a>00368
386
- <a name="l00369"></a>00369 <span class="keywordtype">string</span> m_serverExecutable;
387
- <a name="l00370"></a>00370 <span class="keywordtype">string</span> m_spawnServerCommand;
388
- <a name="l00371"></a>00371 <span class="keywordtype">string</span> m_logFile;
389
- <a name="l00372"></a>00372 <span class="keywordtype">string</span> m_rubyCommand;
390
- <a name="l00373"></a>00373 <span class="keywordtype">string</span> m_user;
391
- <a name="l00374"></a>00374 <span class="keywordtype">string</span> statusReportFIFO;
392
- <a name="l00375"></a>00375 <span class="comment"></span>
393
- <a name="l00376"></a>00376 <span class="comment"> /**</span>
394
- <a name="l00377"></a>00377 <span class="comment"> * The PID of the ApplicationPool server process. If no server process</span>
395
- <a name="l00378"></a>00378 <span class="comment"> * is running, then &lt;tt&gt;serverPid == 0&lt;/tt&gt;.</span>
396
- <a name="l00379"></a>00379 <span class="comment"> *</span>
397
- <a name="l00380"></a>00380 <span class="comment"> * @invariant</span>
398
- <a name="l00381"></a>00381 <span class="comment"> * if serverPid == 0:</span>
399
- <a name="l00382"></a>00382 <span class="comment"> * serverSocket == -1</span>
400
- <a name="l00383"></a>00383 <span class="comment"> */</span>
401
- <a name="l00384"></a>00384 pid_t serverPid;
402
- <a name="l00385"></a>00385 <span class="comment"></span>
403
- <a name="l00386"></a>00386 <span class="comment"> /**</span>
404
- <a name="l00387"></a>00387 <span class="comment"> * The connection to the ApplicationPool server process. If no server</span>
405
- <a name="l00388"></a>00388 <span class="comment"> * process is running, then &lt;tt&gt;serverSocket == -1&lt;/tt&gt;.</span>
406
- <a name="l00389"></a>00389 <span class="comment"> *</span>
407
- <a name="l00390"></a>00390 <span class="comment"> * @invariant</span>
408
- <a name="l00391"></a>00391 <span class="comment"> * if serverPid == 0:</span>
409
- <a name="l00392"></a>00392 <span class="comment"> * serverSocket == -1</span>
410
- <a name="l00393"></a>00393 <span class="comment"> */</span>
411
- <a name="l00394"></a>00394 <span class="keywordtype">int</span> serverSocket;
412
- <a name="l00395"></a>00395 <span class="comment"></span>
413
- <a name="l00396"></a>00396 <span class="comment"> /**</span>
414
- <a name="l00397"></a>00397 <span class="comment"> * Shutdown the currently running ApplicationPool server process.</span>
415
- <a name="l00398"></a>00398 <span class="comment"> *</span>
416
- <a name="l00399"></a>00399 <span class="comment"> * @pre System call interruption is disabled.</span>
417
- <a name="l00400"></a>00400 <span class="comment"> * @pre serverSocket != -1 &amp;&amp; serverPid != 0</span>
418
- <a name="l00401"></a>00401 <span class="comment"> * @post serverSocket == -1 &amp;&amp; serverPid == 0</span>
419
- <a name="l00402"></a>00402 <span class="comment"> */</span>
420
- <a name="l00403"></a>00403 <span class="keywordtype">void</span> shutdownServer() {
421
- <a name="l00404"></a>00404 <a class="code" href="classboost_1_1this__thread_1_1disable__syscall__interruption.html" title="Create this struct on the stack to temporarily disable system call interruption,...">this_thread::disable_syscall_interruption</a> dsi;
422
- <a name="l00405"></a>00405 <span class="keywordtype">int</span> ret;
423
- <a name="l00406"></a>00406 time_t begin;
424
- <a name="l00407"></a>00407 <span class="keywordtype">bool</span> done = <span class="keyword">false</span>;
425
- <a name="l00408"></a>00408
426
- <a name="l00409"></a>00409 InterruptableCalls::close(serverSocket);
427
- <a name="l00410"></a>00410 <span class="keywordflow">if</span> (!statusReportFIFO.empty()) {
428
- <a name="l00411"></a>00411 <span class="keywordflow">do</span> {
429
- <a name="l00412"></a>00412 ret = unlink(statusReportFIFO.c_str());
430
- <a name="l00413"></a>00413 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
431
- <a name="l00414"></a>00414 }
432
- <a name="l00415"></a>00415
433
- <a name="l00416"></a>00416 P_TRACE(2, <span class="stringliteral">"Waiting for existing ApplicationPoolServerExecutable (PID "</span> &lt;&lt;
434
- <a name="l00417"></a>00417 serverPid &lt;&lt; <span class="stringliteral">") to exit..."</span>);
435
- <a name="l00418"></a>00418 begin = InterruptableCalls::time(NULL);
436
- <a name="l00419"></a>00419 <span class="keywordflow">while</span> (!done &amp;&amp; InterruptableCalls::time(NULL) &lt; begin + 5) {
437
- <a name="l00420"></a>00420 <span class="comment">/*</span>
438
- <a name="l00421"></a>00421 <span class="comment"> * Some Apache modules fork(), but don't close file descriptors.</span>
439
- <a name="l00422"></a>00422 <span class="comment"> * mod_wsgi is one such example. Because of that, closing serverSocket</span>
440
- <a name="l00423"></a>00423 <span class="comment"> * won't always cause the ApplicationPool server to exit. So we send it a</span>
441
- <a name="l00424"></a>00424 <span class="comment"> * signal.</span>
442
- <a name="l00425"></a>00425 <span class="comment"> */</span>
443
- <a name="l00426"></a>00426 InterruptableCalls::kill(serverPid, SIGINT);
444
- <a name="l00427"></a>00427
445
- <a name="l00428"></a>00428 ret = InterruptableCalls::waitpid(serverPid, NULL, WNOHANG);
446
- <a name="l00429"></a>00429 done = ret &gt; 0 || ret == -1;
447
- <a name="l00430"></a>00430 <span class="keywordflow">if</span> (!done) {
448
- <a name="l00431"></a>00431 InterruptableCalls::usleep(100000);
449
- <a name="l00432"></a>00432 }
450
- <a name="l00433"></a>00433 }
451
- <a name="l00434"></a>00434 <span class="keywordflow">if</span> (done) {
452
- <a name="l00435"></a>00435 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited."</span>);
453
- <a name="l00436"></a>00436 } <span class="keywordflow">else</span> {
454
- <a name="l00437"></a>00437 P_DEBUG(<span class="stringliteral">"ApplicationPoolServerExecutable not exited in time. Killing it..."</span>);
455
- <a name="l00438"></a>00438 InterruptableCalls::kill(serverPid, SIGTERM);
456
- <a name="l00439"></a>00439 InterruptableCalls::waitpid(serverPid, NULL, 0);
457
- <a name="l00440"></a>00440 }
458
- <a name="l00441"></a>00441
459
- <a name="l00442"></a>00442 serverSocket = -1;
460
- <a name="l00443"></a>00443 serverPid = 0;
461
- <a name="l00444"></a>00444 }
462
- <a name="l00445"></a>00445 <span class="comment"></span>
463
- <a name="l00446"></a>00446 <span class="comment"> /**</span>
464
- <a name="l00447"></a>00447 <span class="comment"> * Start an ApplicationPool server process. If there's already one running,</span>
465
- <a name="l00448"></a>00448 <span class="comment"> * then the currently running one will be shutdown.</span>
466
- <a name="l00449"></a>00449 <span class="comment"> *</span>
467
- <a name="l00450"></a>00450 <span class="comment"> * @pre System call interruption is disabled.</span>
468
- <a name="l00451"></a>00451 <span class="comment"> * @post serverSocket != -1 &amp;&amp; serverPid != 0</span>
469
- <a name="l00452"></a>00452 <span class="comment"> * @throw SystemException Something went wrong.</span>
470
- <a name="l00453"></a>00453 <span class="comment"> */</span>
471
- <a name="l00454"></a>00454 <span class="keywordtype">void</span> restartServer() {
472
- <a name="l00455"></a>00455 <span class="keywordtype">int</span> fds[2];
473
- <a name="l00456"></a>00456 pid_t pid;
474
- <a name="l00457"></a>00457
475
- <a name="l00458"></a>00458 <span class="keywordflow">if</span> (serverPid != 0) {
476
- <a name="l00459"></a>00459 shutdownServer();
477
- <a name="l00460"></a>00460 }
478
- <a name="l00461"></a>00461
479
- <a name="l00462"></a>00462 <span class="keywordflow">if</span> (InterruptableCalls::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
480
- <a name="l00463"></a>00463 <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);
481
- <a name="l00464"></a>00464 }
482
- <a name="l00465"></a>00465
483
- <a name="l00466"></a>00466 createStatusReportFIFO();
484
- <a name="l00467"></a>00467
485
- <a name="l00468"></a>00468 pid = InterruptableCalls::fork();
486
- <a name="l00469"></a>00469 <span class="keywordflow">if</span> (pid == 0) { <span class="comment">// Child process.</span>
487
- <a name="l00470"></a>00470 dup2(fds[0], SERVER_SOCKET_FD);
488
- <a name="l00471"></a>00471
489
- <a name="l00472"></a>00472 <span class="comment">// Close all unnecessary file descriptors</span>
490
- <a name="l00473"></a>00473 <span class="keywordflow">for</span> (<span class="keywordtype">long</span> i = sysconf(_SC_OPEN_MAX) - 1; i &gt; SERVER_SOCKET_FD; i--) {
491
- <a name="l00474"></a>00474 close(i);
492
- <a name="l00475"></a>00475 }
493
- <a name="l00476"></a>00476
494
- <a name="l00477"></a>00477 execlp(
495
- <a name="l00478"></a>00478 #<span class="keywordflow">if</span> 0
496
- <a name="l00479"></a>00479 <span class="stringliteral">"valgrind"</span>,
497
- <a name="l00480"></a>00480 <span class="stringliteral">"valgrind"</span>,
498
- <a name="l00481"></a>00481 #<span class="keywordflow">else</span>
499
- <a name="l00482"></a>00482 m_serverExecutable.c_str(),
500
- <a name="l00483"></a>00483 <span class="preprocessor"> #endif</span>
501
- <a name="l00484"></a>00484 <span class="preprocessor"></span> m_serverExecutable.c_str(),
502
- <a name="l00485"></a>00485 <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(Passenger::getLogLevel()).c_str(),
503
- <a name="l00486"></a>00486 m_spawnServerCommand.c_str(),
504
- <a name="l00487"></a>00487 m_logFile.c_str(),
505
- <a name="l00488"></a>00488 m_rubyCommand.c_str(),
506
- <a name="l00489"></a>00489 m_user.c_str(),
507
- <a name="l00490"></a>00490 statusReportFIFO.c_str(),
508
- <a name="l00491"></a>00491 NULL);
509
- <a name="l00492"></a>00492 <span class="keywordtype">int</span> e = errno;
510
- <a name="l00493"></a>00493 fprintf(stderr, <span class="stringliteral">"*** Passenger ERROR: Cannot execute %s: %s (%d)\n"</span>,
511
- <a name="l00494"></a>00494 m_serverExecutable.c_str(), strerror(e), e);
512
- <a name="l00495"></a>00495 fflush(stderr);
513
- <a name="l00496"></a>00496 _exit(1);
514
- <a name="l00497"></a>00497 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (pid == -1) { <span class="comment">// Error.</span>
515
- <a name="l00498"></a>00498 InterruptableCalls::close(fds[0]);
516
- <a name="l00499"></a>00499 InterruptableCalls::close(fds[1]);
517
- <a name="l00500"></a>00500 <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);
518
- <a name="l00501"></a>00501 } <span class="keywordflow">else</span> { <span class="comment">// Parent process.</span>
519
- <a name="l00502"></a>00502 InterruptableCalls::close(fds[0]);
520
- <a name="l00503"></a>00503 serverSocket = fds[1];
521
- <a name="l00504"></a>00504 serverPid = pid;
522
- <a name="l00505"></a>00505 }
523
- <a name="l00506"></a>00506 }
524
- <a name="l00507"></a>00507
525
- <a name="l00508"></a>00508 <span class="keywordtype">void</span> createStatusReportFIFO() {
526
- <a name="l00509"></a>00509 <span class="keywordtype">char</span> filename[PATH_MAX];
527
- <a name="l00510"></a>00510 <span class="keywordtype">int</span> ret;
528
- <a name="l00511"></a>00511
529
- <a name="l00512"></a>00512 snprintf(filename, <span class="keyword">sizeof</span>(filename), <span class="stringliteral">"/tmp/passenger_status.%d.fifo"</span>,
530
- <a name="l00513"></a>00513 getpid());
531
- <a name="l00514"></a>00514 filename[PATH_MAX - 1] = <span class="charliteral">'\0'</span>;
532
- <a name="l00515"></a>00515 <span class="keywordflow">do</span> {
533
- <a name="l00516"></a>00516 ret = mkfifo(filename, S_IRUSR | S_IWUSR);
534
- <a name="l00517"></a>00517 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
535
- <a name="l00518"></a>00518 <span class="keywordflow">if</span> (ret == -1 &amp;&amp; errno != EEXIST) {
536
- <a name="l00519"></a>00519 <span class="keywordtype">int</span> e = errno;
537
- <a name="l00520"></a>00520 P_WARN(<span class="stringliteral">"*** WARNING: Could not create FIFO '"</span> &lt;&lt; filename &lt;&lt;
538
- <a name="l00521"></a>00521 <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;
539
- <a name="l00522"></a>00522 <span class="stringliteral">"Disabling Passenger ApplicationPool status reporting."</span>);
540
- <a name="l00523"></a>00523 statusReportFIFO = <span class="stringliteral">""</span>;
541
- <a name="l00524"></a>00524 } <span class="keywordflow">else</span> {
542
- <a name="l00525"></a>00525 statusReportFIFO = filename;
543
- <a name="l00526"></a>00526 }
544
- <a name="l00527"></a>00527 }
545
- <a name="l00528"></a>00528
546
- <a name="l00529"></a>00529 <span class="keyword">public</span>:<span class="comment"></span>
547
- <a name="l00530"></a>00530 <span class="comment"> /**</span>
548
- <a name="l00531"></a>00531 <span class="comment"> * Create a new ApplicationPoolServer object.</span>
549
- <a name="l00532"></a>00532 <span class="comment"> *</span>
550
- <a name="l00533"></a>00533 <span class="comment"> * @param serverExecutable The filename of the ApplicationPool server</span>
551
- <a name="l00534"></a>00534 <span class="comment"> * executable to use.</span>
552
- <a name="l00535"></a>00535 <span class="comment"> * @param spawnServerCommand The filename of the spawn server to use.</span>
553
- <a name="l00536"></a>00536 <span class="comment"> * @param logFile Specify a log file that the spawn server should use.</span>
554
- <a name="l00537"></a>00537 <span class="comment"> * Messages on its standard output and standard error channels</span>
555
- <a name="l00538"></a>00538 <span class="comment"> * will be written to this log file. If an empty string is</span>
556
- <a name="l00539"></a>00539 <span class="comment"> * specified, no log file will be used, and the spawn server</span>
557
- <a name="l00540"></a>00540 <span class="comment"> * will use the same standard output/error channels as the</span>
558
- <a name="l00541"></a>00541 <span class="comment"> * current process.</span>
559
- <a name="l00542"></a>00542 <span class="comment"> * @param rubyCommand The Ruby interpreter's command.</span>
560
- <a name="l00543"></a>00543 <span class="comment"> * @param user The user that the spawn manager should run as. This</span>
561
- <a name="l00544"></a>00544 <span class="comment"> * parameter only has effect if the current process is</span>
562
- <a name="l00545"></a>00545 <span class="comment"> * running as root. If the empty string is given, or if</span>
563
- <a name="l00546"></a>00546 <span class="comment"> * the &lt;tt&gt;user&lt;/tt&gt; is not a valid username, then</span>
564
- <a name="l00547"></a>00547 <span class="comment"> * the spawn manager will be run as the current user.</span>
565
- <a name="l00548"></a>00548 <span class="comment"> * @throws SystemException An error occured while trying to setup the spawn server</span>
566
- <a name="l00549"></a>00549 <span class="comment"> * or the server socket.</span>
567
- <a name="l00550"></a>00550 <span class="comment"> * @throws IOException The specified log file could not be opened.</span>
568
- <a name="l00551"></a>00551 <span class="comment"> */</span>
569
- <a name="l00552"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html#2203db62a022579d569ceddff8ef6ca9">00552</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,
570
- <a name="l00553"></a>00553 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;spawnServerCommand,
571
- <a name="l00554"></a>00554 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;logFile = <span class="stringliteral">""</span>,
572
- <a name="l00555"></a>00555 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;rubyCommand = <span class="stringliteral">"ruby"</span>,
573
- <a name="l00556"></a>00556 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;user = <span class="stringliteral">""</span>)
574
- <a name="l00557"></a>00557 : m_serverExecutable(serverExecutable),
575
- <a name="l00558"></a>00558 m_spawnServerCommand(spawnServerCommand),
576
- <a name="l00559"></a>00559 m_logFile(logFile),
577
- <a name="l00560"></a>00560 m_rubyCommand(rubyCommand),
578
- <a name="l00561"></a>00561 m_user(user) {
579
- <a name="l00562"></a>00562 serverSocket = -1;
580
- <a name="l00563"></a>00563 serverPid = 0;
581
- <a name="l00564"></a>00564 <a class="code" href="classboost_1_1this__thread_1_1disable__syscall__interruption.html" title="Create this struct on the stack to temporarily disable system call interruption,...">this_thread::disable_syscall_interruption</a> dsi;
582
- <a name="l00565"></a>00565 restartServer();
583
- <a name="l00566"></a>00566 }
584
- <a name="l00567"></a>00567
585
- <a name="l00568"></a>00568 ~<a class="code" href="classPassenger_1_1ApplicationPoolServer.html" title="Multi-process usage support for ApplicationPool.">ApplicationPoolServer</a>() {
586
- <a name="l00569"></a>00569 <span class="keywordflow">if</span> (serverSocket != -1) {
587
- <a name="l00570"></a>00570 <a class="code" href="classboost_1_1this__thread_1_1disable__syscall__interruption.html" title="Create this struct on the stack to temporarily disable system call interruption,...">this_thread::disable_syscall_interruption</a> dsi;
588
- <a name="l00571"></a>00571 shutdownServer();
589
- <a name="l00572"></a>00572 }
590
- <a name="l00573"></a>00573 }
591
- <a name="l00574"></a>00574 <span class="comment"></span>
592
- <a name="l00575"></a>00575 <span class="comment"> /**</span>
593
- <a name="l00576"></a>00576 <span class="comment"> * Connects to the server and returns a usable ApplicationPool object.</span>
594
- <a name="l00577"></a>00577 <span class="comment"> * All cache/pool data of this ApplicationPool is actually stored on</span>
595
- <a name="l00578"></a>00578 <span class="comment"> * the server and shared with other clients, but that is totally</span>
596
- <a name="l00579"></a>00579 <span class="comment"> * transparent to the user of the ApplicationPool object.</span>
597
- <a name="l00580"></a>00580 <span class="comment"> *</span>
598
- <a name="l00581"></a>00581 <span class="comment"> * @note</span>
599
- <a name="l00582"></a>00582 <span class="comment"> * All methods of the returned ApplicationPool object may throw</span>
600
- <a name="l00583"></a>00583 <span class="comment"> * SystemException, IOException or boost::thread_interrupted.</span>
601
- <a name="l00584"></a>00584 <span class="comment"> *</span>
602
- <a name="l00585"></a>00585 <span class="comment"> * @warning</span>
603
- <a name="l00586"></a>00586 <span class="comment"> * One may only use the returned ApplicationPool object for handling</span>
604
- <a name="l00587"></a>00587 <span class="comment"> * one session at a time. For example, don't do stuff like this:</span>
605
- <a name="l00588"></a>00588 <span class="comment"> * @code</span>
606
- <a name="l00589"></a>00589 <span class="comment"> * ApplicationPoolPtr pool = server.connect();</span>
607
- <a name="l00590"></a>00590 <span class="comment"> * Application::SessionPtr session1 = pool-&gt;get(...);</span>
608
- <a name="l00591"></a>00591 <span class="comment"> * Application::SessionPtr session2 = pool-&gt;get(...);</span>
609
- <a name="l00592"></a>00592 <span class="comment"> * @endcode</span>
610
- <a name="l00593"></a>00593 <span class="comment"> * Otherwise, a deadlock can occur under certain circumstances.</span>
611
- <a name="l00594"></a>00594 <span class="comment"> * @warning</span>
612
- <a name="l00595"></a>00595 <span class="comment"> * Instead, one should call connect() multiple times:</span>
613
- <a name="l00596"></a>00596 <span class="comment"> * @code</span>
614
- <a name="l00597"></a>00597 <span class="comment"> * ApplicationPoolPtr pool1 = server.connect();</span>
615
- <a name="l00598"></a>00598 <span class="comment"> * Application::SessionPtr session1 = pool1-&gt;get(...);</span>
616
- <a name="l00599"></a>00599 <span class="comment"> * </span>
617
- <a name="l00600"></a>00600 <span class="comment"> * ApplicationPoolPtr pool2 = server.connect();</span>
618
- <a name="l00601"></a>00601 <span class="comment"> * Application::SessionPtr session2 = pool2-&gt;get(...);</span>
619
- <a name="l00602"></a>00602 <span class="comment"> * @endcode</span>
620
- <a name="l00603"></a>00603 <span class="comment"> *</span>
621
- <a name="l00604"></a>00604 <span class="comment"> * @throws SystemException Something went wrong.</span>
622
- <a name="l00605"></a>00605 <span class="comment"> * @throws IOException Something went wrong.</span>
623
- <a name="l00606"></a>00606 <span class="comment"> */</span>
624
- <a name="l00607"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html#18f77057cc28e7924a8f4d1397aa0468">00607</a> ApplicationPoolPtr <a class="code" href="classPassenger_1_1ApplicationPoolServer.html#18f77057cc28e7924a8f4d1397aa0468" title="Connects to the server and returns a usable ApplicationPool object.">connect</a>() {
625
- <a name="l00608"></a>00608 <span class="keywordflow">try</span> {
626
- <a name="l00609"></a>00609 <a class="code" href="classboost_1_1this__thread_1_1disable__syscall__interruption.html" title="Create this struct on the stack to temporarily disable system call interruption,...">this_thread::disable_syscall_interruption</a> dsi;
627
- <a name="l00610"></a>00610 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(serverSocket);
628
- <a name="l00611"></a>00611 <span class="keywordtype">int</span> clientConnection;
629
- <a name="l00612"></a>00612
630
- <a name="l00613"></a>00613 <span class="comment">// Write some random data to wake up the server.</span>
631
- <a name="l00614"></a>00614 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);
632
- <a name="l00615"></a>00615
633
- <a name="l00616"></a>00616 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>();
634
- <a name="l00617"></a>00617 <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));
635
- <a name="l00618"></a>00618 } <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) {
636
- <a name="l00619"></a>00619 <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>());
637
- <a name="l00620"></a>00620 } <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) {
638
- <a name="l00621"></a>00621 <span class="keywordtype">string</span> message(<span class="stringliteral">"Could not connect to the ApplicationPool server: "</span>);
639
- <a name="l00622"></a>00622 message.append(e.<a class="code" href="classPassenger_1_1IOException.html#1b65d0fdb9bc5136f5b7df759c14768a">what</a>());
640
- <a name="l00623"></a>00623 <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);
641
- <a name="l00624"></a>00624 }
642
- <a name="l00625"></a>00625 }
643
- <a name="l00626"></a>00626 <span class="comment"></span>
644
- <a name="l00627"></a>00627 <span class="comment"> /**</span>
645
- <a name="l00628"></a>00628 <span class="comment"> * Detach the server, thereby telling it that we don't want to connect</span>
646
- <a name="l00629"></a>00629 <span class="comment"> * to it anymore. This frees up some resources in the current process,</span>
647
- <a name="l00630"></a>00630 <span class="comment"> * such as file descriptors.</span>
648
- <a name="l00631"></a>00631 <span class="comment"> *</span>
649
- <a name="l00632"></a>00632 <span class="comment"> * This method is particularily useful to Apache worker processes that</span>
650
- <a name="l00633"></a>00633 <span class="comment"> * have just established a connection with the ApplicationPool server.</span>
651
- <a name="l00634"></a>00634 <span class="comment"> * Any sessions that are opened prior to calling detach(), will keep</span>
652
- <a name="l00635"></a>00635 <span class="comment"> * working even after a detach().</span>
653
- <a name="l00636"></a>00636 <span class="comment"> *</span>
654
- <a name="l00637"></a>00637 <span class="comment"> * This method may only be called once. The ApplicationPoolServer object</span>
655
- <a name="l00638"></a>00638 <span class="comment"> * will become unusable once detach() has been called, so call connect()</span>
656
- <a name="l00639"></a>00639 <span class="comment"> * before calling detach().</span>
657
- <a name="l00640"></a>00640 <span class="comment"> */</span>
658
- <a name="l00641"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html#b13957e32ae8ca36ba85f2e6ffefd5ce">00641</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>() {
659
- <a name="l00642"></a>00642 <span class="keywordtype">int</span> ret;
660
- <a name="l00643"></a>00643 <span class="keywordflow">do</span> {
661
- <a name="l00644"></a>00644 ret = close(serverSocket);
662
- <a name="l00645"></a>00645 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
663
- <a name="l00646"></a>00646 serverSocket = -1;
664
- <a name="l00647"></a>00647 }
665
- <a name="l00648"></a>00648 };
666
- <a name="l00649"></a>00649
667
- <a name="l00650"></a>00650 <span class="keyword">typedef</span> shared_ptr&lt;ApplicationPoolServer&gt; ApplicationPoolServerPtr;
668
- <a name="l00651"></a>00651
669
- <a name="l00652"></a>00652 } <span class="comment">// namespace Passenger</span>
670
- <a name="l00653"></a>00653
671
- <a name="l00654"></a>00654 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_APPLICATION_POOL_SERVER_H_ */</span>
672
- </pre></div></div>
673
- <hr size="1"><address style="text-align: right;"><small>Generated on Tue Jun 24 14:03:42 2008 for Passenger by&nbsp;
674
- <a href="http://www.doxygen.org/index.html">
675
- <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
676
- </body>
677
- </html>