passenger 2.2.9 → 2.2.10

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 (435) hide show
  1. data/NEWS +10 -0
  2. data/doc/Architectural overview.html +202 -65
  3. data/doc/Security of user switching support.html +200 -63
  4. data/doc/Users guide Apache.html +266 -129
  5. data/doc/Users guide Nginx.html +234 -97
  6. data/doc/cxxapi/AbstractSpawnManager_8h-source.html +138 -0
  7. data/doc/cxxapi/Account_8h-source.html +202 -0
  8. data/doc/cxxapi/AccountsDatabase_8h-source.html +158 -0
  9. data/doc/cxxapi/AgentsStarter_8h-source.html +79 -0
  10. data/doc/cxxapi/BCrypt_8h-source.html +101 -0
  11. data/doc/cxxapi/BacktracesServer_8h-source.html +87 -0
  12. data/doc/cxxapi/Base64_8h-source.html +85 -0
  13. data/doc/cxxapi/Blowfish_8h-source.html +131 -0
  14. data/doc/cxxapi/Bucket_8h-source.html +1 -1
  15. data/doc/cxxapi/CachedFileStat_8h-source.html +49 -157
  16. data/doc/cxxapi/Configuration_8h-source.html +1 -1
  17. data/doc/cxxapi/Constants_8h-source.html +71 -0
  18. data/doc/cxxapi/ContentHandler_8h-source.html +92 -0
  19. data/doc/cxxapi/DirectoryMapper_8h-source.html +1 -1
  20. data/doc/cxxapi/Exceptions_8h-source.html +332 -236
  21. data/doc/cxxapi/FileChangeChecker_8h-source.html +237 -0
  22. data/doc/cxxapi/FileDescriptor_8h-source.html +206 -0
  23. data/doc/cxxapi/Hooks_8h-source.html +1 -1
  24. data/doc/cxxapi/HttpStatusExtractor_8h-source.html +378 -0
  25. data/doc/cxxapi/LoggingServer_8h-source.html +165 -0
  26. data/doc/cxxapi/Logging_8h-source.html +580 -112
  27. data/doc/cxxapi/MessageChannel_8h-source.html +789 -599
  28. data/doc/cxxapi/MessageClient_8h-source.html +297 -0
  29. data/doc/cxxapi/MessageServer_8h-source.html +607 -0
  30. data/doc/cxxapi/PoolOptions_8h-source.html +471 -278
  31. data/doc/cxxapi/Process_8h-source.html +272 -0
  32. data/doc/cxxapi/RandomGenerator_8h-source.html +156 -0
  33. data/doc/cxxapi/ResourceLocator_8h-source.html +104 -0
  34. data/doc/cxxapi/ScgiRequestParser_8h-source.html +399 -0
  35. data/doc/cxxapi/ServerInstanceDir_8h-source.html +356 -0
  36. data/doc/cxxapi/Session_8h-source.html +483 -0
  37. data/doc/cxxapi/SpawnManager_8h-source.html +590 -546
  38. data/doc/cxxapi/StaticContentHandler_8h-source.html +65 -0
  39. data/doc/cxxapi/StaticString_8h-source.html +214 -0
  40. data/doc/cxxapi/StringListCreator_8h-source.html +111 -0
  41. data/doc/cxxapi/SystemTime_8h-source.html +191 -78
  42. data/doc/cxxapi/Timer_8h-source.html +157 -0
  43. data/doc/cxxapi/Utils_8h-source.html +621 -434
  44. data/doc/cxxapi/Version_8h-source.html +59 -0
  45. data/doc/cxxapi/annotated.html +1 -1
  46. data/doc/cxxapi/apache2_2Configuration_8h-source.html +79 -0
  47. data/doc/cxxapi/classAgentWatcher-members.html +50 -0
  48. data/doc/cxxapi/classAgentWatcher.html +445 -0
  49. data/doc/cxxapi/classClient-members.html +4 -3
  50. data/doc/cxxapi/classClient.html +50 -46
  51. data/doc/cxxapi/classHooks-members.html +1 -1
  52. data/doc/cxxapi/classHooks.html +1 -1
  53. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager-members.html +37 -0
  54. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager.html +191 -0
  55. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager__inherit__graph.map +1 -0
  56. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager__inherit__graph.md5 +1 -0
  57. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager__inherit__graph.png +0 -0
  58. data/doc/cxxapi/{classPassenger_1_1DummySpawnManager-members.html → classPassenger_1_1ArgumentException-members.html} +3 -2
  59. data/doc/cxxapi/classPassenger_1_1ArgumentException.html +52 -0
  60. data/doc/cxxapi/classPassenger_1_1BacktracesServer-members.html +36 -0
  61. data/doc/cxxapi/classPassenger_1_1BacktracesServer.html +107 -0
  62. data/doc/cxxapi/classPassenger_1_1BacktracesServer__inherit__graph.map +1 -0
  63. data/doc/cxxapi/classPassenger_1_1BacktracesServer__inherit__graph.md5 +1 -0
  64. data/doc/cxxapi/classPassenger_1_1BacktracesServer__inherit__graph.png +0 -0
  65. data/doc/cxxapi/classPassenger_1_1BufferedUpload-members.html +3 -3
  66. data/doc/cxxapi/classPassenger_1_1BufferedUpload.html +18 -34
  67. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +2 -1
  68. data/doc/cxxapi/classPassenger_1_1BusyException.html +3 -2
  69. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +2 -1
  70. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +3 -2
  71. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +1 -1
  72. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +1 -1
  73. data/doc/cxxapi/{classPassenger_1_1FileChecker-members.html → classPassenger_1_1EOFException-members.html} +3 -4
  74. data/doc/cxxapi/classPassenger_1_1EOFException.html +57 -0
  75. data/doc/cxxapi/classPassenger_1_1EOFException__inherit__graph.map +1 -0
  76. data/doc/cxxapi/classPassenger_1_1EOFException__inherit__graph.md5 +1 -0
  77. data/doc/cxxapi/classPassenger_1_1EOFException__inherit__graph.png +0 -0
  78. data/doc/cxxapi/classPassenger_1_1EventFd-members.html +33 -0
  79. data/doc/cxxapi/classPassenger_1_1EventFd.html +49 -0
  80. data/doc/cxxapi/classPassenger_1_1FileChangeChecker-members.html +37 -0
  81. data/doc/cxxapi/classPassenger_1_1FileChangeChecker.html +166 -0
  82. data/doc/cxxapi/classPassenger_1_1FileDescriptor-members.html +37 -0
  83. data/doc/cxxapi/classPassenger_1_1FileDescriptor.html +159 -0
  84. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +2 -1
  85. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +3 -2
  86. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +2 -1
  87. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +3 -2
  88. data/doc/cxxapi/{classPassenger_1_1ApplicationPoolServer-members.html → classPassenger_1_1HttpStatusExtractor-members.html} +6 -5
  89. data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor.html +128 -0
  90. data/doc/cxxapi/classPassenger_1_1IOException-members.html +2 -1
  91. data/doc/cxxapi/classPassenger_1_1IOException.html +4 -3
  92. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.map +2 -1
  93. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.md5 +1 -1
  94. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  95. data/doc/cxxapi/classPassenger_1_1MemZeroGuard-members.html +36 -0
  96. data/doc/cxxapi/classPassenger_1_1MemZeroGuard.html +147 -0
  97. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +12 -5
  98. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +267 -34
  99. data/doc/cxxapi/classPassenger_1_1MessageServer-members.html +46 -0
  100. data/doc/cxxapi/classPassenger_1_1MessageServer.html +438 -0
  101. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext-members.html +33 -0
  102. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext.html +56 -0
  103. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.map +1 -0
  104. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.md5 +1 -0
  105. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.png +0 -0
  106. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext-members.html +38 -0
  107. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext.html +175 -0
  108. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.map +1 -0
  109. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.md5 +1 -0
  110. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.png +0 -0
  111. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler-members.html +36 -0
  112. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler.html +176 -0
  113. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler__inherit__graph.map +1 -0
  114. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler__inherit__graph.md5 +1 -0
  115. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler__inherit__graph.png +0 -0
  116. data/doc/cxxapi/classPassenger_1_1Process-members.html +40 -0
  117. data/doc/cxxapi/classPassenger_1_1Process.html +266 -0
  118. data/doc/cxxapi/classPassenger_1_1RandomGenerator-members.html +33 -0
  119. data/doc/cxxapi/classPassenger_1_1RandomGenerator.html +51 -0
  120. data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +2 -1
  121. data/doc/cxxapi/classPassenger_1_1RuntimeException.html +3 -2
  122. data/doc/cxxapi/classPassenger_1_1ScgiRequestParser-members.html +47 -0
  123. data/doc/cxxapi/classPassenger_1_1ScgiRequestParser.html +302 -0
  124. data/doc/cxxapi/classPassenger_1_1SecurityException-members.html +33 -0
  125. data/doc/cxxapi/classPassenger_1_1SecurityException.html +52 -0
  126. data/doc/cxxapi/classPassenger_1_1Session-members.html +50 -0
  127. data/doc/cxxapi/classPassenger_1_1Session.html +577 -0
  128. data/doc/cxxapi/classPassenger_1_1Session__inherit__graph.map +1 -0
  129. data/doc/cxxapi/classPassenger_1_1Session__inherit__graph.md5 +1 -0
  130. data/doc/cxxapi/classPassenger_1_1Session__inherit__graph.png +0 -0
  131. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +2 -1
  132. data/doc/cxxapi/classPassenger_1_1SpawnException.html +5 -4
  133. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +8 -5
  134. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +127 -45
  135. data/doc/cxxapi/classPassenger_1_1SpawnManager__inherit__graph.map +1 -0
  136. data/doc/cxxapi/classPassenger_1_1SpawnManager__inherit__graph.md5 +1 -0
  137. data/doc/cxxapi/classPassenger_1_1SpawnManager__inherit__graph.png +0 -0
  138. data/doc/cxxapi/classPassenger_1_1StandardSession-members.html +51 -0
  139. data/doc/cxxapi/classPassenger_1_1StandardSession.html +415 -0
  140. data/doc/cxxapi/classPassenger_1_1StandardSession__inherit__graph.map +1 -0
  141. data/doc/cxxapi/classPassenger_1_1StandardSession__inherit__graph.md5 +1 -0
  142. data/doc/cxxapi/classPassenger_1_1StandardSession__inherit__graph.png +0 -0
  143. data/doc/cxxapi/classPassenger_1_1StaticString-members.html +33 -0
  144. data/doc/cxxapi/classPassenger_1_1StaticString.html +54 -0
  145. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +2 -1
  146. data/doc/cxxapi/classPassenger_1_1SystemException.html +4 -3
  147. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.map +1 -0
  148. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.md5 +1 -1
  149. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  150. data/doc/cxxapi/classPassenger_1_1SystemTime-members.html +9 -1
  151. data/doc/cxxapi/classPassenger_1_1SystemTime.html +92 -8
  152. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException-members.html +37 -0
  153. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException.html +57 -0
  154. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException__inherit__graph.map +1 -0
  155. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException__inherit__graph.md5 +1 -0
  156. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException__inherit__graph.png +0 -0
  157. data/doc/cxxapi/classPassenger_1_1TimeoutException-members.html +33 -0
  158. data/doc/cxxapi/classPassenger_1_1TimeoutException.html +50 -0
  159. data/doc/cxxapi/{classPassenger_1_1Application-members.html → classPassenger_1_1Timer-members.html} +8 -7
  160. data/doc/cxxapi/classPassenger_1_1Timer.html +163 -0
  161. data/doc/cxxapi/classServer-members.html +33 -0
  162. data/doc/cxxapi/classServer.html +46 -0
  163. data/doc/cxxapi/classServerInstanceDirToucher-members.html +33 -0
  164. data/doc/cxxapi/classServerInstanceDirToucher.html +43 -0
  165. data/doc/cxxapi/classes.html +1 -1
  166. data/doc/cxxapi/definitions_8h-source.html +1 -1
  167. data/doc/cxxapi/files.html +1 -1
  168. data/doc/cxxapi/functions.html +1 -1
  169. data/doc/cxxapi/{functions_type.html → functions_enum.html} +7 -5
  170. data/doc/cxxapi/functions_eval.html +55 -0
  171. data/doc/cxxapi/functions_func.html +1 -1
  172. data/doc/cxxapi/functions_vars.html +106 -9
  173. data/doc/cxxapi/graph_legend.html +1 -1
  174. data/doc/cxxapi/group__Configuration.html +1 -1
  175. data/doc/cxxapi/group__Core.html +1 -1
  176. data/doc/cxxapi/group__Exceptions.html +17 -1
  177. data/doc/cxxapi/group__Hooks.html +1 -1
  178. data/doc/cxxapi/group__Support.html +1 -1
  179. data/doc/cxxapi/hierarchy.html +34 -12
  180. data/doc/cxxapi/inherit__graph__0.map +1 -1
  181. data/doc/cxxapi/inherit__graph__0.md5 +1 -1
  182. data/doc/cxxapi/inherit__graph__0.png +0 -0
  183. data/doc/cxxapi/inherit__graph__1.map +1 -1
  184. data/doc/cxxapi/inherit__graph__1.md5 +1 -1
  185. data/doc/cxxapi/inherit__graph__1.png +0 -0
  186. data/doc/cxxapi/inherit__graph__10.map +1 -1
  187. data/doc/cxxapi/inherit__graph__10.md5 +1 -1
  188. data/doc/cxxapi/inherit__graph__10.png +0 -0
  189. data/doc/cxxapi/inherit__graph__11.map +1 -1
  190. data/doc/cxxapi/inherit__graph__11.md5 +1 -1
  191. data/doc/cxxapi/inherit__graph__11.png +0 -0
  192. data/doc/cxxapi/inherit__graph__12.map +1 -1
  193. data/doc/cxxapi/inherit__graph__12.md5 +1 -1
  194. data/doc/cxxapi/inherit__graph__12.png +0 -0
  195. data/doc/cxxapi/inherit__graph__13.map +1 -1
  196. data/doc/cxxapi/inherit__graph__13.md5 +1 -1
  197. data/doc/cxxapi/inherit__graph__13.png +0 -0
  198. data/doc/cxxapi/inherit__graph__14.map +3 -2
  199. data/doc/cxxapi/inherit__graph__14.md5 +1 -1
  200. data/doc/cxxapi/inherit__graph__14.png +0 -0
  201. data/doc/cxxapi/inherit__graph__15.map +1 -1
  202. data/doc/cxxapi/inherit__graph__15.md5 +1 -1
  203. data/doc/cxxapi/inherit__graph__15.png +0 -0
  204. data/doc/cxxapi/inherit__graph__16.map +1 -1
  205. data/doc/cxxapi/inherit__graph__16.md5 +1 -1
  206. data/doc/cxxapi/inherit__graph__16.png +0 -0
  207. data/doc/cxxapi/inherit__graph__17.map +1 -1
  208. data/doc/cxxapi/inherit__graph__17.md5 +1 -1
  209. data/doc/cxxapi/inherit__graph__17.png +0 -0
  210. data/doc/cxxapi/inherit__graph__18.map +2 -1
  211. data/doc/cxxapi/inherit__graph__18.md5 +1 -1
  212. data/doc/cxxapi/inherit__graph__18.png +0 -0
  213. data/doc/cxxapi/inherit__graph__19.map +1 -1
  214. data/doc/cxxapi/inherit__graph__19.md5 +1 -1
  215. data/doc/cxxapi/inherit__graph__19.png +0 -0
  216. data/doc/cxxapi/inherit__graph__2.map +1 -1
  217. data/doc/cxxapi/inherit__graph__2.md5 +1 -1
  218. data/doc/cxxapi/inherit__graph__2.png +0 -0
  219. data/doc/cxxapi/inherit__graph__20.map +1 -2
  220. data/doc/cxxapi/inherit__graph__20.md5 +1 -1
  221. data/doc/cxxapi/inherit__graph__20.png +0 -0
  222. data/doc/cxxapi/inherit__graph__21.map +1 -1
  223. data/doc/cxxapi/inherit__graph__21.md5 +1 -1
  224. data/doc/cxxapi/inherit__graph__21.png +0 -0
  225. data/doc/cxxapi/inherit__graph__22.map +1 -0
  226. data/doc/cxxapi/inherit__graph__22.md5 +1 -0
  227. data/doc/cxxapi/inherit__graph__22.png +0 -0
  228. data/doc/cxxapi/inherit__graph__23.map +1 -0
  229. data/doc/cxxapi/inherit__graph__23.md5 +1 -0
  230. data/doc/cxxapi/inherit__graph__23.png +0 -0
  231. data/doc/cxxapi/inherit__graph__24.map +1 -0
  232. data/doc/cxxapi/inherit__graph__24.md5 +1 -0
  233. data/doc/cxxapi/inherit__graph__24.png +0 -0
  234. data/doc/cxxapi/inherit__graph__25.map +1 -0
  235. data/doc/cxxapi/inherit__graph__25.md5 +1 -0
  236. data/doc/cxxapi/inherit__graph__25.png +0 -0
  237. data/doc/cxxapi/inherit__graph__26.map +1 -0
  238. data/doc/cxxapi/inherit__graph__26.md5 +1 -0
  239. data/doc/cxxapi/inherit__graph__26.png +0 -0
  240. data/doc/cxxapi/inherit__graph__27.map +2 -0
  241. data/doc/cxxapi/inherit__graph__27.md5 +1 -0
  242. data/doc/cxxapi/inherit__graph__27.png +0 -0
  243. data/doc/cxxapi/inherit__graph__28.map +1 -0
  244. data/doc/cxxapi/inherit__graph__28.md5 +1 -0
  245. data/doc/cxxapi/inherit__graph__28.png +0 -0
  246. data/doc/cxxapi/inherit__graph__29.map +1 -0
  247. data/doc/cxxapi/inherit__graph__29.md5 +1 -0
  248. data/doc/cxxapi/inherit__graph__29.png +0 -0
  249. data/doc/cxxapi/inherit__graph__3.map +2 -1
  250. data/doc/cxxapi/inherit__graph__3.md5 +1 -1
  251. data/doc/cxxapi/inherit__graph__3.png +0 -0
  252. data/doc/cxxapi/inherit__graph__30.map +1 -0
  253. data/doc/cxxapi/inherit__graph__30.md5 +1 -0
  254. data/doc/cxxapi/inherit__graph__30.png +0 -0
  255. data/doc/cxxapi/inherit__graph__31.map +3 -0
  256. data/doc/cxxapi/inherit__graph__31.md5 +1 -0
  257. data/doc/cxxapi/inherit__graph__31.png +0 -0
  258. data/doc/cxxapi/inherit__graph__32.map +1 -0
  259. data/doc/cxxapi/inherit__graph__32.md5 +1 -0
  260. data/doc/cxxapi/inherit__graph__32.png +0 -0
  261. data/doc/cxxapi/inherit__graph__33.map +1 -0
  262. data/doc/cxxapi/inherit__graph__33.md5 +1 -0
  263. data/doc/cxxapi/inherit__graph__33.png +0 -0
  264. data/doc/cxxapi/inherit__graph__34.map +1 -0
  265. data/doc/cxxapi/inherit__graph__34.md5 +1 -0
  266. data/doc/cxxapi/inherit__graph__34.png +0 -0
  267. data/doc/cxxapi/inherit__graph__35.map +1 -0
  268. data/doc/cxxapi/inherit__graph__35.md5 +1 -0
  269. data/doc/cxxapi/inherit__graph__35.png +0 -0
  270. data/doc/cxxapi/inherit__graph__36.map +1 -0
  271. data/doc/cxxapi/inherit__graph__36.md5 +1 -0
  272. data/doc/cxxapi/inherit__graph__36.png +0 -0
  273. data/doc/cxxapi/inherit__graph__4.map +1 -1
  274. data/doc/cxxapi/inherit__graph__4.md5 +1 -1
  275. data/doc/cxxapi/inherit__graph__4.png +0 -0
  276. data/doc/cxxapi/inherit__graph__5.map +1 -1
  277. data/doc/cxxapi/inherit__graph__5.md5 +1 -1
  278. data/doc/cxxapi/inherit__graph__5.png +0 -0
  279. data/doc/cxxapi/inherit__graph__6.map +1 -2
  280. data/doc/cxxapi/inherit__graph__6.md5 +1 -1
  281. data/doc/cxxapi/inherit__graph__6.png +0 -0
  282. data/doc/cxxapi/inherit__graph__7.map +1 -1
  283. data/doc/cxxapi/inherit__graph__7.md5 +1 -1
  284. data/doc/cxxapi/inherit__graph__7.png +0 -0
  285. data/doc/cxxapi/inherit__graph__8.map +1 -1
  286. data/doc/cxxapi/inherit__graph__8.md5 +1 -1
  287. data/doc/cxxapi/inherit__graph__8.png +0 -0
  288. data/doc/cxxapi/inherit__graph__9.map +1 -1
  289. data/doc/cxxapi/inherit__graph__9.md5 +1 -1
  290. data/doc/cxxapi/inherit__graph__9.png +0 -0
  291. data/doc/cxxapi/inherits.html +81 -41
  292. data/doc/cxxapi/main.html +1 -1
  293. data/doc/cxxapi/md5_8h-source.html +121 -0
  294. data/doc/cxxapi/modules.html +1 -1
  295. data/doc/cxxapi/namespacePassenger.html +651 -0
  296. data/doc/cxxapi/namespacemembers.html +155 -0
  297. data/doc/cxxapi/namespacemembers_enum.html +46 -0
  298. data/doc/cxxapi/namespacemembers_eval.html +52 -0
  299. data/doc/cxxapi/namespacemembers_func.html +139 -0
  300. data/doc/cxxapi/namespacemembers_type.html +50 -0
  301. data/doc/cxxapi/namespaces.html +34 -0
  302. data/doc/cxxapi/nginx_2Configuration_8h-source.html +114 -0
  303. data/doc/cxxapi/ngx__http__passenger__module_8h-source.html +91 -0
  304. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +2 -1
  305. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +3 -2
  306. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +2 -1
  307. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +3 -2
  308. data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard-members.html +33 -0
  309. data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard.html +49 -0
  310. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +19 -7
  311. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +323 -53
  312. data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash-members.html +33 -0
  313. data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash.html +49 -0
  314. data/ext/common/MessageChannel.h +48 -4
  315. data/ext/common/Version.h +1 -1
  316. data/ext/nginx/HttpStatusExtractor.h +1 -0
  317. data/ext/nginx/ScgiRequestParser.h +1 -0
  318. data/ext/phusion_passenger/native_support.c +5 -1
  319. data/lib/phusion_passenger/constants.rb +1 -1
  320. data/lib/phusion_passenger/message_channel.rb +45 -3
  321. data/lib/phusion_passenger/rack/application_spawner.rb +4 -0
  322. data/lib/phusion_passenger/railz/application_spawner.rb +19 -1
  323. data/lib/phusion_passenger/utils.rb +3 -3
  324. data/lib/phusion_passenger/utils/rewindable_input.rb +5 -0
  325. data/test/MessageChannelTest.cpp +9 -1
  326. data/test/stub/message_channel.rb +1 -1
  327. data/test/stub/message_channel_2.rb +1 -1
  328. data/test/stub/message_channel_3.rb +2 -2
  329. metadata +173 -113
  330. data/doc/cxxapi/ApplicationPoolServer_8h-source.html +0 -833
  331. data/doc/cxxapi/ApplicationPool_8h-source.html +0 -226
  332. data/doc/cxxapi/Application_8h-source.html +0 -553
  333. data/doc/cxxapi/DummySpawnManager_8h-source.html +0 -130
  334. data/doc/cxxapi/FileChecker_8h-source.html +0 -134
  335. data/doc/cxxapi/StandardApplicationPool_8h-source.html +0 -842
  336. data/doc/cxxapi/classPassenger_1_1Application.html +0 -231
  337. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +0 -41
  338. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +0 -323
  339. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +0 -227
  340. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.map +0 -1
  341. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.md5 +0 -1
  342. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
  343. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +0 -44
  344. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +0 -403
  345. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +0 -53
  346. data/doc/cxxapi/classPassenger_1_1FileChecker.html +0 -124
  347. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +0 -44
  348. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +0 -342
  349. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.map +0 -1
  350. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.md5 +0 -1
  351. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
  352. data/doc/rdoc/classes/ConditionVariable.html +0 -194
  353. data/doc/rdoc/classes/Exception.html +0 -120
  354. data/doc/rdoc/classes/GC.html +0 -113
  355. data/doc/rdoc/classes/IO.html +0 -169
  356. data/doc/rdoc/classes/PhusionPassenger.html +0 -239
  357. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +0 -153
  358. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +0 -517
  359. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +0 -719
  360. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +0 -97
  361. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +0 -96
  362. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +0 -97
  363. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +0 -96
  364. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +0 -598
  365. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +0 -140
  366. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +0 -317
  367. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +0 -138
  368. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +0 -154
  369. data/doc/rdoc/classes/PhusionPassenger/Application.html +0 -283
  370. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +0 -172
  371. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +0 -145
  372. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +0 -175
  373. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +0 -141
  374. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +0 -92
  375. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +0 -489
  376. data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +0 -350
  377. data/doc/rdoc/classes/PhusionPassenger/Rack.html +0 -91
  378. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +0 -188
  379. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +0 -199
  380. data/doc/rdoc/classes/PhusionPassenger/Railz.html +0 -95
  381. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +0 -438
  382. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +0 -98
  383. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +0 -200
  384. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +0 -436
  385. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +0 -98
  386. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +0 -155
  387. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +0 -402
  388. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +0 -125
  389. data/doc/rdoc/classes/PhusionPassenger/Utils.html +0 -805
  390. data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +0 -169
  391. data/doc/rdoc/classes/PhusionPassenger/Utils/RewindableInput.html +0 -247
  392. data/doc/rdoc/classes/PhusionPassenger/Utils/RewindableInput/Tempfile.html +0 -120
  393. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +0 -140
  394. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +0 -89
  395. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +0 -188
  396. data/doc/rdoc/classes/PlatformInfo.html +0 -866
  397. data/doc/rdoc/classes/RakeExtensions.html +0 -197
  398. data/doc/rdoc/classes/Signal.html +0 -139
  399. data/doc/rdoc/created.rid +0 -1
  400. data/doc/rdoc/files/DEVELOPERS_TXT.html +0 -255
  401. data/doc/rdoc/files/README.html +0 -157
  402. data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +0 -92
  403. data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +0 -129
  404. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +0 -129
  405. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +0 -126
  406. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +0 -128
  407. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +0 -130
  408. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +0 -122
  409. data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +0 -127
  410. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +0 -126
  411. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +0 -122
  412. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +0 -134
  413. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +0 -122
  414. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +0 -122
  415. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +0 -126
  416. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +0 -120
  417. data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +0 -122
  418. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +0 -127
  419. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +0 -133
  420. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +0 -125
  421. data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +0 -140
  422. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +0 -126
  423. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +0 -145
  424. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +0 -125
  425. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +0 -122
  426. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +0 -159
  427. data/doc/rdoc/files/lib/phusion_passenger/utils/rewindable_input_rb.html +0 -100
  428. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +0 -174
  429. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +0 -129
  430. data/doc/rdoc/files/misc/rake/extensions_rb.html +0 -130
  431. data/doc/rdoc/fr_class_index.html +0 -93
  432. data/doc/rdoc/fr_file_index.html +0 -77
  433. data/doc/rdoc/fr_method_index.html +0 -212
  434. data/doc/rdoc/index.html +0 -26
  435. data/doc/rdoc/rdoc-style.css +0 -187
@@ -1,833 +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="tabs.css" rel="stylesheet" type="text/css">
5
- <link href="doxygen.css" rel="stylesheet" type="text/css">
6
- </head><body>
7
- <!-- Generated by Doxygen 1.5.8 -->
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="annotated.html"><span>Classes</span></a></li>
14
- <li class="current"><a href="files.html"><span>Files</span></a></li>
15
- </ul>
16
- </div>
17
- <div class="tabs">
18
- <ul>
19
- <li><a href="files.html"><span>File&nbsp;List</span></a></li>
20
- </ul>
21
- </div>
22
- <h1>ApplicationPoolServer.h</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
23
- <a name="l00002"></a>00002 <span class="comment"> * Phusion Passenger - http://www.modrails.com/</span>
24
- <a name="l00003"></a>00003 <span class="comment"> * Copyright (C) 2008 Phusion</span>
25
- <a name="l00004"></a>00004 <span class="comment"> *</span>
26
- <a name="l00005"></a>00005 <span class="comment"> * Phusion Passenger is a trademark of Hongli Lai &amp; Ninh Bui.</span>
27
- <a name="l00006"></a>00006 <span class="comment"> *</span>
28
- <a name="l00007"></a>00007 <span class="comment"> * This program is free software; you can redistribute it and/or modify</span>
29
- <a name="l00008"></a>00008 <span class="comment"> * it under the terms of the GNU General Public License as published by</span>
30
- <a name="l00009"></a>00009 <span class="comment"> * the Free Software Foundation; version 2 of the License.</span>
31
- <a name="l00010"></a>00010 <span class="comment"> *</span>
32
- <a name="l00011"></a>00011 <span class="comment"> * This program is distributed in the hope that it will be useful,</span>
33
- <a name="l00012"></a>00012 <span class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
34
- <a name="l00013"></a>00013 <span class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
35
- <a name="l00014"></a>00014 <span class="comment"> * GNU General Public License for more details.</span>
36
- <a name="l00015"></a>00015 <span class="comment"> *</span>
37
- <a name="l00016"></a>00016 <span class="comment"> * You should have received a copy of the GNU General Public License along</span>
38
- <a name="l00017"></a>00017 <span class="comment"> * with this program; if not, write to the Free Software Foundation, Inc.,</span>
39
- <a name="l00018"></a>00018 <span class="comment"> * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span>
40
- <a name="l00019"></a>00019 <span class="comment"> */</span>
41
- <a name="l00020"></a>00020 <span class="preprocessor">#ifndef _PASSENGER_APPLICATION_POOL_SERVER_H_</span>
42
- <a name="l00021"></a>00021 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_APPLICATION_POOL_SERVER_H_</span>
43
- <a name="l00022"></a>00022 <span class="preprocessor"></span>
44
- <a name="l00023"></a>00023 <span class="preprocessor">#include &lt;boost/shared_ptr.hpp&gt;</span>
45
- <a name="l00024"></a>00024 <span class="preprocessor">#include &lt;boost/thread/mutex.hpp&gt;</span>
46
- <a name="l00025"></a>00025 <span class="preprocessor">#include &lt;oxt/system_calls.hpp&gt;</span>
47
- <a name="l00026"></a>00026 <span class="preprocessor">#include &lt;oxt/backtrace.hpp&gt;</span>
48
- <a name="l00027"></a>00027
49
- <a name="l00028"></a>00028 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
50
- <a name="l00029"></a>00029 <span class="preprocessor">#include &lt;sys/stat.h&gt;</span>
51
- <a name="l00030"></a>00030 <span class="preprocessor">#include &lt;sys/wait.h&gt;</span>
52
- <a name="l00031"></a>00031 <span class="preprocessor">#include &lt;sys/socket.h&gt;</span>
53
- <a name="l00032"></a>00032 <span class="preprocessor">#include &lt;cstdio&gt;</span>
54
- <a name="l00033"></a>00033 <span class="preprocessor">#include &lt;cstdlib&gt;</span>
55
- <a name="l00034"></a>00034 <span class="preprocessor">#include &lt;limits.h&gt;</span>
56
- <a name="l00035"></a>00035 <span class="preprocessor">#include &lt;errno.h&gt;</span>
57
- <a name="l00036"></a>00036 <span class="preprocessor">#include &lt;unistd.h&gt;</span>
58
- <a name="l00037"></a>00037 <span class="preprocessor">#include &lt;signal.h&gt;</span>
59
- <a name="l00038"></a>00038 <span class="preprocessor">#include &lt;fcntl.h&gt;</span>
60
- <a name="l00039"></a>00039
61
- <a name="l00040"></a>00040 <span class="preprocessor">#include "MessageChannel.h"</span>
62
- <a name="l00041"></a>00041 <span class="preprocessor">#include "ApplicationPool.h"</span>
63
- <a name="l00042"></a>00042 <span class="preprocessor">#include "Application.h"</span>
64
- <a name="l00043"></a>00043 <span class="preprocessor">#include "Exceptions.h"</span>
65
- <a name="l00044"></a>00044 <span class="preprocessor">#include "Logging.h"</span>
66
- <a name="l00045"></a>00045
67
- <a name="l00046"></a>00046 <span class="keyword">namespace </span>Passenger {
68
- <a name="l00047"></a>00047
69
- <a name="l00048"></a>00048 <span class="keyword">using namespace </span>std;
70
- <a name="l00049"></a>00049 <span class="keyword">using namespace </span>boost;
71
- <a name="l00050"></a>00050 <span class="keyword">using namespace </span>oxt;
72
- <a name="l00051"></a>00051
73
- <a name="l00052"></a>00052 <span class="comment"></span>
74
- <a name="l00053"></a>00053 <span class="comment">/**</span>
75
- <a name="l00054"></a>00054 <span class="comment"> * Multi-process usage support for ApplicationPool.</span>
76
- <a name="l00055"></a>00055 <span class="comment"> *</span>
77
- <a name="l00056"></a>00056 <span class="comment"> * ApplicationPoolServer implements a client/server architecture for ApplicationPool.</span>
78
- <a name="l00057"></a>00057 <span class="comment"> * This allows one to use ApplicationPool in a multi-process environment (unlike</span>
79
- <a name="l00058"></a>00058 <span class="comment"> * StandardApplicationPool). The cache/pool data is stored in the server. Different</span>
80
- <a name="l00059"></a>00059 <span class="comment"> * processes can then access the pool through the server.</span>
81
- <a name="l00060"></a>00060 <span class="comment"> *</span>
82
- <a name="l00061"></a>00061 <span class="comment"> * ApplicationPoolServer itself does not inherit ApplicationPool. Instead, it returns</span>
83
- <a name="l00062"></a>00062 <span class="comment"> * an ApplicationPool object via the connect() call. For example:</span>
84
- <a name="l00063"></a>00063 <span class="comment"> * @code</span>
85
- <a name="l00064"></a>00064 <span class="comment"> * // Create an ApplicationPoolServer.</span>
86
- <a name="l00065"></a>00065 <span class="comment"> * ApplicationPoolServer server(...);</span>
87
- <a name="l00066"></a>00066 <span class="comment"> * </span>
88
- <a name="l00067"></a>00067 <span class="comment"> * // Now fork a child process, like Apache's prefork MPM eventually will.</span>
89
- <a name="l00068"></a>00068 <span class="comment"> * pid_t pid = fork();</span>
90
- <a name="l00069"></a>00069 <span class="comment"> * if (pid == 0) {</span>
91
- <a name="l00070"></a>00070 <span class="comment"> * // Child process</span>
92
- <a name="l00071"></a>00071 <span class="comment"> * </span>
93
- <a name="l00072"></a>00072 <span class="comment"> * // Connect to the server. After connection, we have an ApplicationPool</span>
94
- <a name="l00073"></a>00073 <span class="comment"> * // object!</span>
95
- <a name="l00074"></a>00074 <span class="comment"> * ApplicationPoolPtr pool(server.connect());</span>
96
- <a name="l00075"></a>00075 <span class="comment"> *</span>
97
- <a name="l00076"></a>00076 <span class="comment"> * // We don't need to connect to the server anymore, so we detach from it.</span>
98
- <a name="l00077"></a>00077 <span class="comment"> * // This frees up some resources, such as file descriptors.</span>
99
- <a name="l00078"></a>00078 <span class="comment"> * server.detach();</span>
100
- <a name="l00079"></a>00079 <span class="comment"> *</span>
101
- <a name="l00080"></a>00080 <span class="comment"> * ApplicationPool::SessionPtr session(pool-&gt;get("/home/webapps/foo"));</span>
102
- <a name="l00081"></a>00081 <span class="comment"> * do_something_with(session);</span>
103
- <a name="l00082"></a>00082 <span class="comment"> *</span>
104
- <a name="l00083"></a>00083 <span class="comment"> * _exit(0);</span>
105
- <a name="l00084"></a>00084 <span class="comment"> * } else {</span>
106
- <a name="l00085"></a>00085 <span class="comment"> * // Parent process</span>
107
- <a name="l00086"></a>00086 <span class="comment"> * waitpid(pid, NULL, 0);</span>
108
- <a name="l00087"></a>00087 <span class="comment"> * }</span>
109
- <a name="l00088"></a>00088 <span class="comment"> * @endcode</span>
110
- <a name="l00089"></a>00089 <span class="comment"> *</span>
111
- <a name="l00090"></a>00090 <span class="comment"> * &lt;h2&gt;Implementation notes&lt;/h2&gt;</span>
112
- <a name="l00091"></a>00091 <span class="comment"> *</span>
113
- <a name="l00092"></a>00092 <span class="comment"> * &lt;h3&gt;Separate server executable&lt;/h3&gt;</span>
114
- <a name="l00093"></a>00093 <span class="comment"> * The actual server is implemented in ApplicationPoolServerExecutable.cpp, this class is</span>
115
- <a name="l00094"></a>00094 <span class="comment"> * just a convenience class for starting/stopping the server executable and connecting</span>
116
- <a name="l00095"></a>00095 <span class="comment"> * to it.</span>
117
- <a name="l00096"></a>00096 <span class="comment"> *</span>
118
- <a name="l00097"></a>00097 <span class="comment"> * In the past, the server logic itself was implemented in this class. This implies that</span>
119
- <a name="l00098"></a>00098 <span class="comment"> * the ApplicationPool server ran inside the Apache process. This presented us with several</span>
120
- <a name="l00099"></a>00099 <span class="comment"> * problems:</span>
121
- <a name="l00100"></a>00100 <span class="comment"> * - Because of the usage of threads in the ApplicationPool server, the Apache VM size would</span>
122
- <a name="l00101"></a>00101 <span class="comment"> * go way up. This gave people the (wrong) impression that Passenger uses a lot of memory,</span>
123
- <a name="l00102"></a>00102 <span class="comment"> * or that it leaks memory.</span>
124
- <a name="l00103"></a>00103 <span class="comment"> * - Although it's not entirely confirmed, we suspect that it caused heap fragmentation as</span>
125
- <a name="l00104"></a>00104 <span class="comment"> * well. Apache allocates lots and lots of small objects on the heap, and ApplicationPool</span>
126
- <a name="l00105"></a>00105 <span class="comment"> * server isn't exactly helping. This too gave people the (wrong) impression that</span>
127
- <a name="l00106"></a>00106 <span class="comment"> * Passenger leaks memory.</span>
128
- <a name="l00107"></a>00107 <span class="comment"> * - It would unnecessarily bloat the VM size of Apache worker processes.</span>
129
- <a name="l00108"></a>00108 <span class="comment"> * - We had to resort to all kinds of tricks to make sure that fork()ing a process doesn't</span>
130
- <a name="l00109"></a>00109 <span class="comment"> * result in file descriptor leaks.</span>
131
- <a name="l00110"></a>00110 <span class="comment"> * - Despite everything, there was still a small chance that file descriptor leaks would</span>
132
- <a name="l00111"></a>00111 <span class="comment"> * occur, and this could not be fixed. The reason for this is that the Apache control</span>
133
- <a name="l00112"></a>00112 <span class="comment"> * process may call fork() right after the ApplicationPool server has established a new</span>
134
- <a name="l00113"></a>00113 <span class="comment"> * connection with a client.</span>
135
- <a name="l00114"></a>00114 <span class="comment"> *</span>
136
- <a name="l00115"></a>00115 <span class="comment"> * Because of these problems, it was decided to split the ApplicationPool server to a</span>
137
- <a name="l00116"></a>00116 <span class="comment"> * separate executable. This comes with no performance hit.</span>
138
- <a name="l00117"></a>00117 <span class="comment"> *</span>
139
- <a name="l00118"></a>00118 <span class="comment"> * &lt;h3&gt;Anonymous server socket&lt;/h3&gt;</span>
140
- <a name="l00119"></a>00119 <span class="comment"> * Notice that ApplicationPoolServer does do not use TCP sockets at all, or even named Unix</span>
141
- <a name="l00120"></a>00120 <span class="comment"> * sockets, despite being a server that can handle multiple clients! So ApplicationPoolServer</span>
142
- <a name="l00121"></a>00121 <span class="comment"> * will expose no open ports or temporary Unix socket files. Only child processes are able</span>
143
- <a name="l00122"></a>00122 <span class="comment"> * to use the ApplicationPoolServer.</span>
144
- <a name="l00123"></a>00123 <span class="comment"> *</span>
145
- <a name="l00124"></a>00124 <span class="comment"> * This is implemented through anonymous Unix sockets (&lt;tt&gt;socketpair()&lt;/tt&gt;) and file descriptor</span>
146
- <a name="l00125"></a>00125 <span class="comment"> * passing. It allows one to emulate &lt;tt&gt;accept()&lt;/tt&gt;. ApplicationPoolServer is connected to</span>
147
- <a name="l00126"></a>00126 <span class="comment"> * the server executable through a Unix socket pair. connect() sends a connect request to the</span>
148
- <a name="l00127"></a>00127 <span class="comment"> * server through that socket. The server will then create a new socket pair, and pass one of</span>
149
- <a name="l00128"></a>00128 <span class="comment"> * them back. This new socket pair represents the newly established connection.</span>
150
- <a name="l00129"></a>00129 <span class="comment"> *</span>
151
- <a name="l00130"></a>00130 <span class="comment"> * @ingroup Support</span>
152
- <a name="l00131"></a>00131 <span class="comment"> */</span>
153
- <a name="l00132"></a><a class="code" href="classPassenger_1_1ApplicationPoolServer.html">00132</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1ApplicationPoolServer.html" title="Multi-process usage support for ApplicationPool.">ApplicationPoolServer</a> {
154
- <a name="l00133"></a>00133 <span class="keyword">private</span>:<span class="comment"></span>
155
- <a name="l00134"></a>00134 <span class="comment"> /**</span>
156
- <a name="l00135"></a>00135 <span class="comment"> * Contains data shared between RemoteSession and Client.</span>
157
- <a name="l00136"></a>00136 <span class="comment"> * Since RemoteSession and Client have different life times, i.e. one may be</span>
158
- <a name="l00137"></a>00137 <span class="comment"> * destroyed before the other, they both use a smart pointer that points to</span>
159
- <a name="l00138"></a>00138 <span class="comment"> * a SharedData. This way, the SharedData object is only destroyed when</span>
160
- <a name="l00139"></a>00139 <span class="comment"> * both the RemoteSession and the Client object has been destroyed.</span>
161
- <a name="l00140"></a>00140 <span class="comment"> */</span>
162
- <a name="l00141"></a>00141 <span class="keyword">struct </span>SharedData {<span class="comment"></span>
163
- <a name="l00142"></a>00142 <span class="comment"> /**</span>
164
- <a name="l00143"></a>00143 <span class="comment"> * The socket connection to the ApplicationPool server, as was</span>
165
- <a name="l00144"></a>00144 <span class="comment"> * established by ApplicationPoolServer::connect().</span>
166
- <a name="l00145"></a>00145 <span class="comment"> *</span>
167
- <a name="l00146"></a>00146 <span class="comment"> * The value may be -1, which indicates that the connection has</span>
168
- <a name="l00147"></a>00147 <span class="comment"> * been closed.</span>
169
- <a name="l00148"></a>00148 <span class="comment"> */</span>
170
- <a name="l00149"></a>00149 <span class="keywordtype">int</span> server;
171
- <a name="l00150"></a>00150
172
- <a name="l00151"></a>00151 <span class="keyword">mutable</span> boost::mutex lock;
173
- <a name="l00152"></a>00152
174
- <a name="l00153"></a>00153 ~SharedData() {
175
- <a name="l00154"></a>00154 TRACE_POINT();
176
- <a name="l00155"></a>00155 <span class="keywordflow">if</span> (server != -1) {
177
- <a name="l00156"></a>00156 disconnect();
178
- <a name="l00157"></a>00157 }
179
- <a name="l00158"></a>00158 }
180
- <a name="l00159"></a>00159 <span class="comment"></span>
181
- <a name="l00160"></a>00160 <span class="comment"> /**</span>
182
- <a name="l00161"></a>00161 <span class="comment"> * Disconnect from the ApplicationPool server.</span>
183
- <a name="l00162"></a>00162 <span class="comment"> */</span>
184
- <a name="l00163"></a>00163 <span class="keywordtype">void</span> disconnect() {
185
- <a name="l00164"></a>00164 TRACE_POINT();
186
- <a name="l00165"></a>00165 <span class="keywordtype">int</span> ret;
187
- <a name="l00166"></a>00166 <span class="keywordflow">do</span> {
188
- <a name="l00167"></a>00167 ret = close(server);
189
- <a name="l00168"></a>00168 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
190
- <a name="l00169"></a>00169 server = -1;
191
- <a name="l00170"></a>00170 }
192
- <a name="l00171"></a>00171 };
193
- <a name="l00172"></a>00172
194
- <a name="l00173"></a>00173 <span class="keyword">typedef</span> shared_ptr&lt;SharedData&gt; SharedDataPtr;
195
- <a name="l00174"></a>00174 <span class="comment"></span>
196
- <a name="l00175"></a>00175 <span class="comment"> /**</span>
197
- <a name="l00176"></a>00176 <span class="comment"> * An Application::Session which works together with ApplicationPoolServer.</span>
198
- <a name="l00177"></a>00177 <span class="comment"> */</span>
199
- <a name="l00178"></a>00178 <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 {
200
- <a name="l00179"></a>00179 <span class="keyword">private</span>:
201
- <a name="l00180"></a>00180 SharedDataPtr data;
202
- <a name="l00181"></a>00181 <span class="keywordtype">int</span> id;
203
- <a name="l00182"></a>00182 <span class="keywordtype">int</span> fd;
204
- <a name="l00183"></a>00183 pid_t pid;
205
- <a name="l00184"></a>00184 <span class="keyword">public</span>:
206
- <a name="l00185"></a>00185 RemoteSession(SharedDataPtr data, pid_t pid, <span class="keywordtype">int</span> <span class="keywordtype">id</span>, <span class="keywordtype">int</span> fd) {
207
- <a name="l00186"></a>00186 this-&gt;data = data;
208
- <a name="l00187"></a>00187 this-&gt;pid = pid;
209
- <a name="l00188"></a>00188 this-&gt;<span class="keywordtype">id</span> = id;
210
- <a name="l00189"></a>00189 this-&gt;fd = fd;
211
- <a name="l00190"></a>00190 }
212
- <a name="l00191"></a>00191
213
- <a name="l00192"></a>00192 <span class="keyword">virtual</span> ~RemoteSession() {
214
- <a name="l00193"></a>00193 closeStream();
215
- <a name="l00194"></a>00194 boost::mutex::scoped_lock(data-&gt;lock);
216
- <a name="l00195"></a>00195 <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);
217
- <a name="l00196"></a>00196 }
218
- <a name="l00197"></a>00197
219
- <a name="l00198"></a>00198 <span class="keyword">virtual</span> <span class="keywordtype">int</span> getStream()<span class="keyword"> const </span>{
220
- <a name="l00199"></a>00199 <span class="keywordflow">return</span> fd;
221
- <a name="l00200"></a>00200 }
222
- <a name="l00201"></a>00201
223
- <a name="l00202"></a>00202 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setReaderTimeout(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> msec) {
224
- <a name="l00203"></a>00203 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a>(fd).setReadTimeout(msec);
225
- <a name="l00204"></a>00204 }
226
- <a name="l00205"></a>00205
227
- <a name="l00206"></a>00206 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setWriterTimeout(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> msec) {
228
- <a name="l00207"></a>00207 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a>(fd).setWriteTimeout(msec);
229
- <a name="l00208"></a>00208 }
230
- <a name="l00209"></a>00209
231
- <a name="l00210"></a>00210 <span class="keyword">virtual</span> <span class="keywordtype">void</span> shutdownReader() {
232
- <a name="l00211"></a>00211 <span class="keywordflow">if</span> (fd != -1) {
233
- <a name="l00212"></a>00212 <span class="keywordtype">int</span> ret = syscalls::shutdown(fd, SHUT_RD);
234
- <a name="l00213"></a>00213 <span class="keywordflow">if</span> (ret == -1) {
235
- <a name="l00214"></a>00214 <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>,
236
- <a name="l00215"></a>00215 errno);
237
- <a name="l00216"></a>00216 }
238
- <a name="l00217"></a>00217 }
239
- <a name="l00218"></a>00218 }
240
- <a name="l00219"></a>00219
241
- <a name="l00220"></a>00220 <span class="keyword">virtual</span> <span class="keywordtype">void</span> shutdownWriter() {
242
- <a name="l00221"></a>00221 <span class="keywordflow">if</span> (fd != -1) {
243
- <a name="l00222"></a>00222 <span class="keywordtype">int</span> ret = syscalls::shutdown(fd, SHUT_WR);
244
- <a name="l00223"></a>00223 <span class="keywordflow">if</span> (ret == -1) {
245
- <a name="l00224"></a>00224 <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>,
246
- <a name="l00225"></a>00225 errno);
247
- <a name="l00226"></a>00226 }
248
- <a name="l00227"></a>00227 }
249
- <a name="l00228"></a>00228 }
250
- <a name="l00229"></a>00229
251
- <a name="l00230"></a>00230 <span class="keyword">virtual</span> <span class="keywordtype">void</span> closeStream() {
252
- <a name="l00231"></a>00231 <span class="keywordflow">if</span> (fd != -1) {
253
- <a name="l00232"></a>00232 <span class="keywordtype">int</span> ret = syscalls::close(fd);
254
- <a name="l00233"></a>00233 <span class="keywordflow">if</span> (ret == -1) {
255
- <a name="l00234"></a>00234 <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>,
256
- <a name="l00235"></a>00235 errno);
257
- <a name="l00236"></a>00236 }
258
- <a name="l00237"></a>00237 fd = -1;
259
- <a name="l00238"></a>00238 }
260
- <a name="l00239"></a>00239 }
261
- <a name="l00240"></a>00240
262
- <a name="l00241"></a>00241 <span class="keyword">virtual</span> <span class="keywordtype">void</span> discardStream() {
263
- <a name="l00242"></a>00242 fd = -1;
264
- <a name="l00243"></a>00243 }
265
- <a name="l00244"></a>00244
266
- <a name="l00245"></a>00245 <span class="keyword">virtual</span> pid_t getPid()<span class="keyword"> const </span>{
267
- <a name="l00246"></a>00246 <span class="keywordflow">return</span> pid;
268
- <a name="l00247"></a>00247 }
269
- <a name="l00248"></a>00248 };
270
- <a name="l00249"></a>00249 <span class="comment"></span>
271
- <a name="l00250"></a>00250 <span class="comment"> /**</span>
272
- <a name="l00251"></a>00251 <span class="comment"> * An ApplicationPool implementation that works together with ApplicationPoolServer.</span>
273
- <a name="l00252"></a>00252 <span class="comment"> * It doesn't do much by itself, its job is mostly to forward queries/commands to</span>
274
- <a name="l00253"></a>00253 <span class="comment"> * the server and returning the result. Most of the logic is in the server executable.</span>
275
- <a name="l00254"></a>00254 <span class="comment"> */</span>
276
- <a name="l00255"></a>00255 <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> {
277
- <a name="l00256"></a>00256 <span class="keyword">private</span>:
278
- <a name="l00257"></a>00257 <span class="comment">// The smart pointer only serves to keep the shared data alive.</span>
279
- <a name="l00258"></a>00258 <span class="comment">// We access the shared data via a normal pointer, for performance.</span>
280
- <a name="l00259"></a>00259 SharedDataPtr dataSmartPointer;
281
- <a name="l00260"></a>00260 SharedData *data;
282
- <a name="l00261"></a>00261
283
- <a name="l00262"></a>00262 <span class="keyword">public</span>:<span class="comment"></span>
284
- <a name="l00263"></a>00263 <span class="comment"> /**</span>
285
- <a name="l00264"></a>00264 <span class="comment"> * Create a new Client.</span>
286
- <a name="l00265"></a>00265 <span class="comment"> *</span>
287
- <a name="l00266"></a>00266 <span class="comment"> * @param sock The newly established socket connection with the ApplicationPoolServer.</span>
288
- <a name="l00267"></a>00267 <span class="comment"> */</span>
289
- <a name="l00268"></a>00268 Client(<span class="keywordtype">int</span> sock) {
290
- <a name="l00269"></a>00269 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());
291
- <a name="l00270"></a>00270 data = dataSmartPointer.get();
292
- <a name="l00271"></a>00271 data-&gt;server = sock;
293
- <a name="l00272"></a>00272 }
294
- <a name="l00273"></a>00273
295
- <a name="l00274"></a>00274 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> connected()<span class="keyword"> const </span>{
296
- <a name="l00275"></a>00275 boost::mutex::scoped_lock(data-&gt;lock);
297
- <a name="l00276"></a>00276 <span class="keywordflow">return</span> data-&gt;server != -1;
298
- <a name="l00277"></a>00277 }
299
- <a name="l00278"></a>00278
300
- <a name="l00279"></a>00279 <span class="keyword">virtual</span> <span class="keywordtype">void</span> clear() {
301
- <a name="l00280"></a>00280 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
302
- <a name="l00281"></a>00281 boost::mutex::scoped_lock l(data-&gt;lock);
303
- <a name="l00282"></a>00282 <span class="keywordflow">try</span> {
304
- <a name="l00283"></a>00283 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"clear"</span>, NULL);
305
- <a name="l00284"></a>00284 } <span class="keywordflow">catch</span> (...) {
306
- <a name="l00285"></a>00285 data-&gt;disconnect();
307
- <a name="l00286"></a>00286 <span class="keywordflow">throw</span>;
308
- <a name="l00287"></a>00287 }
309
- <a name="l00288"></a>00288 }
310
- <a name="l00289"></a>00289
311
- <a name="l00290"></a>00290 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMaxIdleTime(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> seconds) {
312
- <a name="l00291"></a>00291 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
313
- <a name="l00292"></a>00292 boost::mutex::scoped_lock l(data-&gt;lock);
314
- <a name="l00293"></a>00293 <span class="keywordflow">try</span> {
315
- <a name="l00294"></a>00294 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" 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);
316
- <a name="l00295"></a>00295 } <span class="keywordflow">catch</span> (...) {
317
- <a name="l00296"></a>00296 data-&gt;disconnect();
318
- <a name="l00297"></a>00297 <span class="keywordflow">throw</span>;
319
- <a name="l00298"></a>00298 }
320
- <a name="l00299"></a>00299 }
321
- <a name="l00300"></a>00300
322
- <a name="l00301"></a>00301 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMax(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> max) {
323
- <a name="l00302"></a>00302 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
324
- <a name="l00303"></a>00303 boost::mutex::scoped_lock l(data-&gt;lock);
325
- <a name="l00304"></a>00304 <span class="keywordflow">try</span> {
326
- <a name="l00305"></a>00305 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" 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);
327
- <a name="l00306"></a>00306 } <span class="keywordflow">catch</span> (...) {
328
- <a name="l00307"></a>00307 data-&gt;disconnect();
329
- <a name="l00308"></a>00308 <span class="keywordflow">throw</span>;
330
- <a name="l00309"></a>00309 }
331
- <a name="l00310"></a>00310 }
332
- <a name="l00311"></a>00311
333
- <a name="l00312"></a>00312 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getActive()<span class="keyword"> const </span>{
334
- <a name="l00313"></a>00313 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
335
- <a name="l00314"></a>00314 boost::mutex::scoped_lock l(data-&gt;lock);
336
- <a name="l00315"></a>00315 vector&lt;string&gt; args;
337
- <a name="l00316"></a>00316
338
- <a name="l00317"></a>00317 <span class="keywordflow">try</span> {
339
- <a name="l00318"></a>00318 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"getActive"</span>, NULL);
340
- <a name="l00319"></a>00319 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(args);
341
- <a name="l00320"></a>00320 <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());
342
- <a name="l00321"></a>00321 } <span class="keywordflow">catch</span> (...) {
343
- <a name="l00322"></a>00322 data-&gt;disconnect();
344
- <a name="l00323"></a>00323 <span class="keywordflow">throw</span>;
345
- <a name="l00324"></a>00324 }
346
- <a name="l00325"></a>00325 }
347
- <a name="l00326"></a>00326
348
- <a name="l00327"></a>00327 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getCount()<span class="keyword"> const </span>{
349
- <a name="l00328"></a>00328 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
350
- <a name="l00329"></a>00329 boost::mutex::scoped_lock l(data-&gt;lock);
351
- <a name="l00330"></a>00330 vector&lt;string&gt; args;
352
- <a name="l00331"></a>00331
353
- <a name="l00332"></a>00332 <span class="keywordflow">try</span> {
354
- <a name="l00333"></a>00333 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"getCount"</span>, NULL);
355
- <a name="l00334"></a>00334 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(args);
356
- <a name="l00335"></a>00335 <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());
357
- <a name="l00336"></a>00336 } <span class="keywordflow">catch</span> (...) {
358
- <a name="l00337"></a>00337 data-&gt;disconnect();
359
- <a name="l00338"></a>00338 <span class="keywordflow">throw</span>;
360
- <a name="l00339"></a>00339 }
361
- <a name="l00340"></a>00340 }
362
- <a name="l00341"></a>00341
363
- <a name="l00342"></a>00342 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMaxPerApp(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> max) {
364
- <a name="l00343"></a>00343 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
365
- <a name="l00344"></a>00344 boost::mutex::scoped_lock l(data-&gt;lock);
366
- <a name="l00345"></a>00345 <span class="keywordflow">try</span> {
367
- <a name="l00346"></a>00346 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" 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);
368
- <a name="l00347"></a>00347 } <span class="keywordflow">catch</span> (...) {
369
- <a name="l00348"></a>00348 data-&gt;disconnect();
370
- <a name="l00349"></a>00349 <span class="keywordflow">throw</span>;
371
- <a name="l00350"></a>00350 }
372
- <a name="l00351"></a>00351 }
373
- <a name="l00352"></a>00352
374
- <a name="l00353"></a>00353 <span class="keyword">virtual</span> pid_t getSpawnServerPid()<span class="keyword"> const </span>{
375
- <a name="l00354"></a>00354 this_thread::disable_syscall_interruption dsi;
376
- <a name="l00355"></a>00355 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
377
- <a name="l00356"></a>00356 boost::mutex::scoped_lock l(data-&gt;lock);
378
- <a name="l00357"></a>00357 vector&lt;string&gt; args;
379
- <a name="l00358"></a>00358
380
- <a name="l00359"></a>00359 <span class="keywordflow">try</span> {
381
- <a name="l00360"></a>00360 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="stringliteral">"getSpawnServerPid"</span>, NULL);
382
- <a name="l00361"></a>00361 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(args);
383
- <a name="l00362"></a>00362 <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());
384
- <a name="l00363"></a>00363 } <span class="keywordflow">catch</span> (...) {
385
- <a name="l00364"></a>00364 data-&gt;disconnect();
386
- <a name="l00365"></a>00365 <span class="keywordflow">throw</span>;
387
- <a name="l00366"></a>00366 }
388
- <a name="l00367"></a>00367 }
389
- <a name="l00368"></a>00368
390
- <a name="l00369"></a>00369 <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>(<span class="keyword">const</span> <a class="code" href="structPassenger_1_1PoolOptions.html" title="This struct encapsulates information for ApplicationPool::get() and for SpawnManager::spawn()...">PoolOptions</a> &amp;options) {
391
- <a name="l00370"></a>00370 this_thread::disable_syscall_interruption dsi;
392
- <a name="l00371"></a>00371 TRACE_POINT();
393
- <a name="l00372"></a>00372
394
- <a name="l00373"></a>00373 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> channel(data-&gt;server);
395
- <a name="l00374"></a>00374 boost::mutex::scoped_lock l(data-&gt;lock);
396
- <a name="l00375"></a>00375 vector&lt;string&gt; args;
397
- <a name="l00376"></a>00376 <span class="keywordtype">int</span> stream;
398
- <a name="l00377"></a>00377 <span class="keywordtype">bool</span> result;
399
- <a name="l00378"></a>00378
400
- <a name="l00379"></a>00379 <span class="keywordflow">try</span> {
401
- <a name="l00380"></a>00380 vector&lt;string&gt; args;
402
- <a name="l00381"></a>00381
403
- <a name="l00382"></a>00382 args.push_back(<span class="stringliteral">"get"</span>);
404
- <a name="l00383"></a>00383 options.toVector(args);
405
- <a name="l00384"></a>00384 channel.<a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(args);
406
- <a name="l00385"></a>00385 } <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) {
407
- <a name="l00386"></a>00386 UPDATE_TRACE_POINT();
408
- <a name="l00387"></a>00387 data-&gt;disconnect();
409
- <a name="l00388"></a>00388
410
- <a name="l00389"></a>00389 <span class="keywordtype">string</span> message(<span class="stringliteral">"Could not send data to the ApplicationPool server: "</span>);
411
- <a name="l00390"></a>00390 message.append(e.<a class="code" href="classPassenger_1_1SystemException.html#84fa2ab4f5b7b96704734fcdfdaa0269" title="Returns a brief version of the exception message.">brief</a>());
412
- <a name="l00391"></a>00391 <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>(message, e.<a class="code" href="classPassenger_1_1SystemException.html#ee7a6672bf79b72a4c3ee70c57d6a47c" title="The value of errno at the time the error occured.">code</a>());
413
- <a name="l00392"></a>00392 }
414
- <a name="l00393"></a>00393 <span class="keywordflow">try</span> {
415
- <a name="l00394"></a>00394 UPDATE_TRACE_POINT();
416
- <a name="l00395"></a>00395 result = channel.<a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(args);
417
- <a name="l00396"></a>00396 } <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) {
418
- <a name="l00397"></a>00397 UPDATE_TRACE_POINT();
419
- <a name="l00398"></a>00398 data-&gt;disconnect();
420
- <a name="l00399"></a>00399 <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>
421
- <a name="l00400"></a>00400 <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>());
422
- <a name="l00401"></a>00401 }
423
- <a name="l00402"></a>00402 <span class="keywordflow">if</span> (!result) {
424
- <a name="l00403"></a>00403 UPDATE_TRACE_POINT();
425
- <a name="l00404"></a>00404 data-&gt;disconnect();
426
- <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>
427
- <a name="l00406"></a>00406 <span class="stringliteral">"closed the connection while we're reading a response "</span>
428
- <a name="l00407"></a>00407 <span class="stringliteral">"for the 'get' command."</span>);
429
- <a name="l00408"></a>00408 }
430
- <a name="l00409"></a>00409 <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"ok"</span>) {
431
- <a name="l00410"></a>00410 UPDATE_TRACE_POINT();
432
- <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]);
433
- <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]);
434
- <a name="l00413"></a>00413
435
- <a name="l00414"></a>00414 <span class="keywordflow">try</span> {
436
- <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>();
437
- <a name="l00416"></a>00416 } <span class="keywordflow">catch</span> (...) {
438
- <a name="l00417"></a>00417 UPDATE_TRACE_POINT();
439
- <a name="l00418"></a>00418 data-&gt;disconnect();
440
- <a name="l00419"></a>00419 <span class="keywordflow">throw</span>;
441
- <a name="l00420"></a>00420 }
442
- <a name="l00421"></a>00421
443
- <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,
444
- <a name="l00423"></a>00423 pid, sessionID, stream));
445
- <a name="l00424"></a>00424 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"SpawnException"</span>) {
446
- <a name="l00425"></a>00425 UPDATE_TRACE_POINT();
447
- <a name="l00426"></a>00426 <span class="keywordflow">if</span> (args[2] == <span class="stringliteral">"true"</span>) {
448
- <a name="l00427"></a>00427 <span class="keywordtype">string</span> errorPage;
449
- <a name="l00428"></a>00428
450
- <a name="l00429"></a>00429 <span class="keywordflow">try</span> {
451
- <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);
452
- <a name="l00431"></a>00431 } <span class="keywordflow">catch</span> (...) {
453
- <a name="l00432"></a>00432 data-&gt;disconnect();
454
- <a name="l00433"></a>00433 <span class="keywordflow">throw</span>;
455
- <a name="l00434"></a>00434 }
456
- <a name="l00435"></a>00435 <span class="keywordflow">if</span> (!result) {
457
- <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>
458
- <a name="l00437"></a>00437 <span class="stringliteral">"unexpectedly closed the connection while "</span>
459
- <a name="l00438"></a>00438 <span class="stringliteral">"we're reading the error page data."</span>);
460
- <a name="l00439"></a>00439 }
461
- <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);
462
- <a name="l00441"></a>00441 } <span class="keywordflow">else</span> {
463
- <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]);
464
- <a name="l00443"></a>00443 }
465
- <a name="l00444"></a>00444 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"BusyException"</span>) {
466
- <a name="l00445"></a>00445 UPDATE_TRACE_POINT();
467
- <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]);
468
- <a name="l00447"></a>00447 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">"IOException"</span>) {
469
- <a name="l00448"></a>00448 UPDATE_TRACE_POINT();
470
- <a name="l00449"></a>00449 data-&gt;disconnect();
471
- <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]);
472
- <a name="l00451"></a>00451 } <span class="keywordflow">else</span> {
473
- <a name="l00452"></a>00452 UPDATE_TRACE_POINT();
474
- <a name="l00453"></a>00453 data-&gt;disconnect();
475
- <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>
476
- <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));
477
- <a name="l00456"></a>00456 }
478
- <a name="l00457"></a>00457 }
479
- <a name="l00458"></a>00458 };
480
- <a name="l00459"></a>00459
481
- <a name="l00460"></a>00460
482
- <a name="l00461"></a>00461 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> SERVER_SOCKET_FD = 3;
483
- <a name="l00462"></a>00462
484
- <a name="l00463"></a>00463 <span class="keywordtype">string</span> m_serverExecutable;
485
- <a name="l00464"></a>00464 <span class="keywordtype">string</span> m_spawnServerCommand;
486
- <a name="l00465"></a>00465 <span class="keywordtype">string</span> m_logFile;
487
- <a name="l00466"></a>00466 <span class="keywordtype">string</span> m_rubyCommand;
488
- <a name="l00467"></a>00467 <span class="keywordtype">string</span> m_user;
489
- <a name="l00468"></a>00468 <span class="keywordtype">string</span> statusReportFIFO;
490
- <a name="l00469"></a>00469 <span class="comment"></span>
491
- <a name="l00470"></a>00470 <span class="comment"> /**</span>
492
- <a name="l00471"></a>00471 <span class="comment"> * The PID of the ApplicationPool server process. If no server process</span>
493
- <a name="l00472"></a>00472 <span class="comment"> * is running, then &lt;tt&gt;serverPid == 0&lt;/tt&gt;.</span>
494
- <a name="l00473"></a>00473 <span class="comment"> *</span>
495
- <a name="l00474"></a>00474 <span class="comment"> * @invariant</span>
496
- <a name="l00475"></a>00475 <span class="comment"> * if serverPid == 0:</span>
497
- <a name="l00476"></a>00476 <span class="comment"> * serverSocket == -1</span>
498
- <a name="l00477"></a>00477 <span class="comment"> */</span>
499
- <a name="l00478"></a>00478 pid_t serverPid;
500
- <a name="l00479"></a>00479 <span class="comment"></span>
501
- <a name="l00480"></a>00480 <span class="comment"> /**</span>
502
- <a name="l00481"></a>00481 <span class="comment"> * The connection to the ApplicationPool server process. If no server</span>
503
- <a name="l00482"></a>00482 <span class="comment"> * process is running, then &lt;tt&gt;serverSocket == -1&lt;/tt&gt;.</span>
504
- <a name="l00483"></a>00483 <span class="comment"> *</span>
505
- <a name="l00484"></a>00484 <span class="comment"> * @invariant</span>
506
- <a name="l00485"></a>00485 <span class="comment"> * if serverPid == 0:</span>
507
- <a name="l00486"></a>00486 <span class="comment"> * serverSocket == -1</span>
508
- <a name="l00487"></a>00487 <span class="comment"> */</span>
509
- <a name="l00488"></a>00488 <span class="keywordtype">int</span> serverSocket;
510
- <a name="l00489"></a>00489 <span class="comment"></span>
511
- <a name="l00490"></a>00490 <span class="comment"> /**</span>
512
- <a name="l00491"></a>00491 <span class="comment"> * Shutdown the currently running ApplicationPool server process.</span>
513
- <a name="l00492"></a>00492 <span class="comment"> *</span>
514
- <a name="l00493"></a>00493 <span class="comment"> * @pre System call interruption is disabled.</span>
515
- <a name="l00494"></a>00494 <span class="comment"> * @pre serverSocket != -1 &amp;&amp; serverPid != 0</span>
516
- <a name="l00495"></a>00495 <span class="comment"> * @post serverSocket == -1 &amp;&amp; serverPid == 0</span>
517
- <a name="l00496"></a>00496 <span class="comment"> */</span>
518
- <a name="l00497"></a>00497 <span class="keywordtype">void</span> shutdownServer() {
519
- <a name="l00498"></a>00498 TRACE_POINT();
520
- <a name="l00499"></a>00499 this_thread::disable_syscall_interruption dsi;
521
- <a name="l00500"></a>00500 <span class="keywordtype">int</span> ret, status;
522
- <a name="l00501"></a>00501 time_t begin;
523
- <a name="l00502"></a>00502 <span class="keywordtype">bool</span> done = <span class="keyword">false</span>;
524
- <a name="l00503"></a>00503
525
- <a name="l00504"></a>00504 syscalls::close(serverSocket);
526
- <a name="l00505"></a>00505 <span class="keywordflow">if</span> (!statusReportFIFO.empty()) {
527
- <a name="l00506"></a>00506 <span class="keywordflow">do</span> {
528
- <a name="l00507"></a>00507 ret = unlink(statusReportFIFO.c_str());
529
- <a name="l00508"></a>00508 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
530
- <a name="l00509"></a>00509 }
531
- <a name="l00510"></a>00510
532
- <a name="l00511"></a>00511 P_TRACE(2, <span class="stringliteral">"Waiting for existing ApplicationPoolServerExecutable (PID "</span> &lt;&lt;
533
- <a name="l00512"></a>00512 serverPid &lt;&lt; <span class="stringliteral">") to exit..."</span>);
534
- <a name="l00513"></a>00513 begin = syscalls::time(NULL);
535
- <a name="l00514"></a>00514 <span class="keywordflow">while</span> (!done &amp;&amp; syscalls::time(NULL) &lt; begin + 5) {
536
- <a name="l00515"></a>00515 <span class="comment">/*</span>
537
- <a name="l00516"></a>00516 <span class="comment"> * Some Apache modules fork(), but don't close file descriptors.</span>
538
- <a name="l00517"></a>00517 <span class="comment"> * mod_wsgi is one such example. Because of that, closing serverSocket</span>
539
- <a name="l00518"></a>00518 <span class="comment"> * won't always cause the ApplicationPool server to exit. So we send it a</span>
540
- <a name="l00519"></a>00519 <span class="comment"> * signal. This must be the same as the oxt/system_calls.hpp interruption</span>
541
- <a name="l00520"></a>00520 <span class="comment"> * signal.</span>
542
- <a name="l00521"></a>00521 <span class="comment"> */</span>
543
- <a name="l00522"></a>00522 syscalls::kill(serverPid, SIGINT);
544
- <a name="l00523"></a>00523
545
- <a name="l00524"></a>00524 ret = syscalls::waitpid(serverPid, &amp;status, WNOHANG);
546
- <a name="l00525"></a>00525 done = ret &gt; 0 || ret == -1;
547
- <a name="l00526"></a>00526 <span class="keywordflow">if</span> (!done) {
548
- <a name="l00527"></a>00527 syscalls::usleep(100000);
549
- <a name="l00528"></a>00528 }
550
- <a name="l00529"></a>00529 }
551
- <a name="l00530"></a>00530 <span class="keywordflow">if</span> (done) {
552
- <a name="l00531"></a>00531 <span class="keywordflow">if</span> (ret &gt; 0) {
553
- <a name="l00532"></a>00532 <span class="keywordflow">if</span> (WIFEXITED(status)) {
554
- <a name="l00533"></a>00533 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited with exit status "</span> &lt;&lt;
555
- <a name="l00534"></a>00534 WEXITSTATUS(status) &lt;&lt; <span class="stringliteral">"."</span>);
556
- <a name="l00535"></a>00535 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (WIFSIGNALED(status)) {
557
- <a name="l00536"></a>00536 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited because of signal "</span> &lt;&lt;
558
- <a name="l00537"></a>00537 WTERMSIG(status) &lt;&lt; <span class="stringliteral">"."</span>);
559
- <a name="l00538"></a>00538 } <span class="keywordflow">else</span> {
560
- <a name="l00539"></a>00539 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited for an unknown reason."</span>);
561
- <a name="l00540"></a>00540 }
562
- <a name="l00541"></a>00541 } <span class="keywordflow">else</span> {
563
- <a name="l00542"></a>00542 P_TRACE(2, <span class="stringliteral">"ApplicationPoolServerExecutable exited."</span>);
564
- <a name="l00543"></a>00543 }
565
- <a name="l00544"></a>00544 } <span class="keywordflow">else</span> {
566
- <a name="l00545"></a>00545 P_DEBUG(<span class="stringliteral">"ApplicationPoolServerExecutable not exited in time. Killing it..."</span>);
567
- <a name="l00546"></a>00546 syscalls::kill(serverPid, SIGKILL);
568
- <a name="l00547"></a>00547 syscalls::waitpid(serverPid, NULL, 0);
569
- <a name="l00548"></a>00548 }
570
- <a name="l00549"></a>00549
571
- <a name="l00550"></a>00550 serverSocket = -1;
572
- <a name="l00551"></a>00551 serverPid = 0;
573
- <a name="l00552"></a>00552 }
574
- <a name="l00553"></a>00553 <span class="comment"></span>
575
- <a name="l00554"></a>00554 <span class="comment"> /**</span>
576
- <a name="l00555"></a>00555 <span class="comment"> * Start an ApplicationPool server process. If there's already one running,</span>
577
- <a name="l00556"></a>00556 <span class="comment"> * then the currently running one will be shutdown.</span>
578
- <a name="l00557"></a>00557 <span class="comment"> *</span>
579
- <a name="l00558"></a>00558 <span class="comment"> * @pre System call interruption is disabled.</span>
580
- <a name="l00559"></a>00559 <span class="comment"> * @post serverSocket != -1 &amp;&amp; serverPid != 0</span>
581
- <a name="l00560"></a>00560 <span class="comment"> * @throw SystemException Something went wrong.</span>
582
- <a name="l00561"></a>00561 <span class="comment"> */</span>
583
- <a name="l00562"></a>00562 <span class="keywordtype">void</span> restartServer() {
584
- <a name="l00563"></a>00563 TRACE_POINT();
585
- <a name="l00564"></a>00564 <span class="keywordtype">int</span> fds[2];
586
- <a name="l00565"></a>00565 pid_t pid;
587
- <a name="l00566"></a>00566
588
- <a name="l00567"></a>00567 <span class="keywordflow">if</span> (serverPid != 0) {
589
- <a name="l00568"></a>00568 shutdownServer();
590
- <a name="l00569"></a>00569 }
591
- <a name="l00570"></a>00570
592
- <a name="l00571"></a>00571 <span class="keywordflow">if</span> (syscalls::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
593
- <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);
594
- <a name="l00573"></a>00573 }
595
- <a name="l00574"></a>00574
596
- <a name="l00575"></a>00575 createStatusReportFIFO();
597
- <a name="l00576"></a>00576
598
- <a name="l00577"></a>00577 pid = syscalls::fork();
599
- <a name="l00578"></a>00578 <span class="keywordflow">if</span> (pid == 0) { <span class="comment">// Child process.</span>
600
- <a name="l00579"></a>00579 dup2(STDERR_FILENO, STDOUT_FILENO); <span class="comment">// Redirect stdout to the same channel as stderr.</span>
601
- <a name="l00580"></a>00580 dup2(fds[0], SERVER_SOCKET_FD);
602
- <a name="l00581"></a>00581
603
- <a name="l00582"></a>00582 <span class="comment">// Close all unnecessary file descriptors</span>
604
- <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--) {
605
- <a name="l00584"></a>00584 close(i);
606
- <a name="l00585"></a>00585 }
607
- <a name="l00586"></a>00586
608
- <a name="l00587"></a>00587 execlp(
609
- <a name="l00588"></a>00588 #<span class="keywordflow">if</span> 0
610
- <a name="l00589"></a>00589 <span class="stringliteral">"valgrind"</span>,
611
- <a name="l00590"></a>00590 <span class="stringliteral">"valgrind"</span>,
612
- <a name="l00591"></a>00591 #<span class="keywordflow">else</span>
613
- <a name="l00592"></a>00592 m_serverExecutable.c_str(),
614
- <a name="l00593"></a>00593 <span class="preprocessor"> #endif</span>
615
- <a name="l00594"></a>00594 <span class="preprocessor"></span> m_serverExecutable.c_str(),
616
- <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(),
617
- <a name="l00596"></a>00596 m_spawnServerCommand.c_str(),
618
- <a name="l00597"></a>00597 m_logFile.c_str(),
619
- <a name="l00598"></a>00598 m_rubyCommand.c_str(),
620
- <a name="l00599"></a>00599 m_user.c_str(),
621
- <a name="l00600"></a>00600 statusReportFIFO.c_str(),
622
- <a name="l00601"></a>00601 (<span class="keywordtype">char</span> *) 0);
623
- <a name="l00602"></a>00602 <span class="keywordtype">int</span> e = errno;
624
- <a name="l00603"></a>00603 fprintf(stderr, <span class="stringliteral">"*** Passenger ERROR (%s:%d):\n"</span>
625
- <a name="l00604"></a>00604 <span class="stringliteral">"Cannot execute %s: %s (%d)\n"</span>,
626
- <a name="l00605"></a>00605 __FILE__, __LINE__,
627
- <a name="l00606"></a>00606 m_serverExecutable.c_str(), strerror(e), e);
628
- <a name="l00607"></a>00607 fflush(stderr);
629
- <a name="l00608"></a>00608 _exit(1);
630
- <a name="l00609"></a>00609 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (pid == -1) { <span class="comment">// Error.</span>
631
- <a name="l00610"></a>00610 syscalls::close(fds[0]);
632
- <a name="l00611"></a>00611 syscalls::close(fds[1]);
633
- <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);
634
- <a name="l00613"></a>00613 } <span class="keywordflow">else</span> { <span class="comment">// Parent process.</span>
635
- <a name="l00614"></a>00614 syscalls::close(fds[0]);
636
- <a name="l00615"></a>00615 serverSocket = fds[1];
637
- <a name="l00616"></a>00616
638
- <a name="l00617"></a>00617 <span class="keywordtype">int</span> flags = fcntl(serverSocket, F_GETFD);
639
- <a name="l00618"></a>00618 <span class="keywordflow">if</span> (flags != -1) {
640
- <a name="l00619"></a>00619 fcntl(serverSocket, F_SETFD, flags | FD_CLOEXEC);
641
- <a name="l00620"></a>00620 }
642
- <a name="l00621"></a>00621
643
- <a name="l00622"></a>00622 serverPid = pid;
644
- <a name="l00623"></a>00623 }
645
- <a name="l00624"></a>00624 }
646
- <a name="l00625"></a>00625
647
- <a name="l00626"></a>00626 <span class="keywordtype">void</span> createStatusReportFIFO() {
648
- <a name="l00627"></a>00627 TRACE_POINT();
649
- <a name="l00628"></a>00628 <span class="keywordtype">char</span> filename[PATH_MAX];
650
- <a name="l00629"></a>00629 <span class="keywordtype">int</span> ret;
651
- <a name="l00630"></a>00630 mode_t permissions = S_IRUSR | S_IWUSR;
652
- <a name="l00631"></a>00631
653
- <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(),
654
- <a name="l00633"></a>00633 <span class="stringliteral">"nobody"</span>, geteuid(), getegid());
655
- <a name="l00634"></a>00634
656
- <a name="l00635"></a>00635 snprintf(filename, <span class="keyword">sizeof</span>(filename), <span class="stringliteral">"%s/info/status.fifo"</span>,
657
- <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());
658
- <a name="l00637"></a>00637 filename[PATH_MAX - 1] = <span class="charliteral">'\0'</span>;
659
- <a name="l00638"></a>00638 <span class="keywordflow">do</span> {
660
- <a name="l00639"></a>00639 ret = mkfifo(filename, permissions);
661
- <a name="l00640"></a>00640 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
662
- <a name="l00641"></a>00641 <span class="keywordflow">if</span> (ret == -1 &amp;&amp; errno != EEXIST) {
663
- <a name="l00642"></a>00642 <span class="keywordtype">int</span> e = errno;
664
- <a name="l00643"></a>00643 P_WARN(<span class="stringliteral">"*** WARNING: Could not create FIFO '"</span> &lt;&lt; filename &lt;&lt;
665
- <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;
666
- <a name="l00645"></a>00645 <span class="stringliteral">"Disabling Passenger ApplicationPool status reporting."</span>);
667
- <a name="l00646"></a>00646 statusReportFIFO = <span class="stringliteral">""</span>;
668
- <a name="l00647"></a>00647 } <span class="keywordflow">else</span> {
669
- <a name="l00648"></a>00648 statusReportFIFO = filename;
670
- <a name="l00649"></a>00649
671
- <a name="l00650"></a>00650 <span class="comment">// It seems that the permissions passed to mkfifo()</span>
672
- <a name="l00651"></a>00651 <span class="comment">// aren't respected, so here we chmod the file.</span>
673
- <a name="l00652"></a>00652 <span class="keywordflow">do</span> {
674
- <a name="l00653"></a>00653 ret = chmod(filename, permissions);
675
- <a name="l00654"></a>00654 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
676
- <a name="l00655"></a>00655
677
- <a name="l00656"></a>00656 <span class="comment">// Set the FIFO's owner according to whether we're running as root</span>
678
- <a name="l00657"></a>00657 <span class="comment">// and whether user switching is enabled.</span>
679
- <a name="l00658"></a>00658 <span class="keywordflow">if</span> (geteuid() == 0 &amp;&amp; !m_user.empty()) {
680
- <a name="l00659"></a>00659 uid_t uid;
681
- <a name="l00660"></a>00660 gid_t gid;
682
- <a name="l00661"></a>00661
683
- <a name="l00662"></a>00662 determineLowestUserAndGroup(m_user, uid, gid);
684
- <a name="l00663"></a>00663 <span class="keywordflow">do</span> {
685
- <a name="l00664"></a>00664 ret = chown(filename, uid, gid);
686
- <a name="l00665"></a>00665 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
687
- <a name="l00666"></a>00666 <span class="keywordflow">if</span> (errno == -1) {
688
- <a name="l00667"></a>00667 <span class="keywordtype">int</span> e = errno;
689
- <a name="l00668"></a>00668 P_WARN(<span class="stringliteral">"*** WARNING: Unable to set the FIFO file '"</span> &lt;&lt;
690
- <a name="l00669"></a>00669 filename &lt;&lt; <span class="stringliteral">"' its owner and group to that of user "</span> &lt;&lt;
691
- <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>);
692
- <a name="l00671"></a>00671 }
693
- <a name="l00672"></a>00672 }
694
- <a name="l00673"></a>00673 }
695
- <a name="l00674"></a>00674 }
696
- <a name="l00675"></a>00675
697
- <a name="l00676"></a>00676 <span class="keyword">public</span>:<span class="comment"></span>
698
- <a name="l00677"></a>00677 <span class="comment"> /**</span>
699
- <a name="l00678"></a>00678 <span class="comment"> * Create a new ApplicationPoolServer object.</span>
700
- <a name="l00679"></a>00679 <span class="comment"> *</span>
701
- <a name="l00680"></a>00680 <span class="comment"> * @param serverExecutable The filename of the ApplicationPool server</span>
702
- <a name="l00681"></a>00681 <span class="comment"> * executable to use.</span>
703
- <a name="l00682"></a>00682 <span class="comment"> * @param spawnServerCommand The filename of the spawn server to use.</span>
704
- <a name="l00683"></a>00683 <span class="comment"> * @param logFile Specify a log file that the spawn server should use.</span>
705
- <a name="l00684"></a>00684 <span class="comment"> * Messages on its standard output and standard error channels</span>
706
- <a name="l00685"></a>00685 <span class="comment"> * will be written to this log file. If an empty string is</span>
707
- <a name="l00686"></a>00686 <span class="comment"> * specified, no log file will be used, and the spawn server</span>
708
- <a name="l00687"></a>00687 <span class="comment"> * will use the same standard output/error channels as the</span>
709
- <a name="l00688"></a>00688 <span class="comment"> * current process.</span>
710
- <a name="l00689"></a>00689 <span class="comment"> * @param rubyCommand The Ruby interpreter's command.</span>
711
- <a name="l00690"></a>00690 <span class="comment"> * @param user The user that the spawn manager should run as. This</span>
712
- <a name="l00691"></a>00691 <span class="comment"> * parameter only has effect if the current process is</span>
713
- <a name="l00692"></a>00692 <span class="comment"> * running as root. If the empty string is given, or if</span>
714
- <a name="l00693"></a>00693 <span class="comment"> * the &lt;tt&gt;user&lt;/tt&gt; is not a valid username, then</span>
715
- <a name="l00694"></a>00694 <span class="comment"> * the spawn manager will be run as the current user.</span>
716
- <a name="l00695"></a>00695 <span class="comment"> * @throws SystemException An error occured while trying to setup the spawn server</span>
717
- <a name="l00696"></a>00696 <span class="comment"> * or the server socket.</span>
718
- <a name="l00697"></a>00697 <span class="comment"> * @throws IOException The specified log file could not be opened.</span>
719
- <a name="l00698"></a>00698 <span class="comment"> */</span>
720
- <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,
721
- <a name="l00700"></a>00700 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;spawnServerCommand,
722
- <a name="l00701"></a>00701 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;logFile = <span class="stringliteral">""</span>,
723
- <a name="l00702"></a>00702 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;rubyCommand = <span class="stringliteral">"ruby"</span>,
724
- <a name="l00703"></a>00703 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;user = <span class="stringliteral">""</span>)
725
- <a name="l00704"></a>00704 : m_serverExecutable(serverExecutable),
726
- <a name="l00705"></a>00705 m_spawnServerCommand(spawnServerCommand),
727
- <a name="l00706"></a>00706 m_logFile(logFile),
728
- <a name="l00707"></a>00707 m_rubyCommand(rubyCommand),
729
- <a name="l00708"></a>00708 m_user(user) {
730
- <a name="l00709"></a>00709 TRACE_POINT();
731
- <a name="l00710"></a>00710 serverSocket = -1;
732
- <a name="l00711"></a>00711 serverPid = 0;
733
- <a name="l00712"></a>00712 this_thread::disable_syscall_interruption dsi;
734
- <a name="l00713"></a>00713 restartServer();
735
- <a name="l00714"></a>00714 }
736
- <a name="l00715"></a>00715
737
- <a name="l00716"></a>00716 ~<a class="code" href="classPassenger_1_1ApplicationPoolServer.html" title="Multi-process usage support for ApplicationPool.">ApplicationPoolServer</a>() {
738
- <a name="l00717"></a>00717 TRACE_POINT();
739
- <a name="l00718"></a>00718 <span class="keywordflow">if</span> (serverSocket != -1) {
740
- <a name="l00719"></a>00719 UPDATE_TRACE_POINT();
741
- <a name="l00720"></a>00720 this_thread::disable_syscall_interruption dsi;
742
- <a name="l00721"></a>00721 shutdownServer();
743
- <a name="l00722"></a>00722 }
744
- <a name="l00723"></a>00723 }
745
- <a name="l00724"></a>00724 <span class="comment"></span>
746
- <a name="l00725"></a>00725 <span class="comment"> /**</span>
747
- <a name="l00726"></a>00726 <span class="comment"> * Connects to the server and returns a usable ApplicationPool object.</span>
748
- <a name="l00727"></a>00727 <span class="comment"> * All cache/pool data of this ApplicationPool is actually stored on</span>
749
- <a name="l00728"></a>00728 <span class="comment"> * the server and shared with other clients, but that is totally</span>
750
- <a name="l00729"></a>00729 <span class="comment"> * transparent to the user of the ApplicationPool object.</span>
751
- <a name="l00730"></a>00730 <span class="comment"> *</span>
752
- <a name="l00731"></a>00731 <span class="comment"> * @note</span>
753
- <a name="l00732"></a>00732 <span class="comment"> * All methods of the returned ApplicationPool object may throw</span>
754
- <a name="l00733"></a>00733 <span class="comment"> * SystemException, IOException or boost::thread_interrupted.</span>
755
- <a name="l00734"></a>00734 <span class="comment"> *</span>
756
- <a name="l00735"></a>00735 <span class="comment"> * @warning</span>
757
- <a name="l00736"></a>00736 <span class="comment"> * One may only use the returned ApplicationPool object for handling</span>
758
- <a name="l00737"></a>00737 <span class="comment"> * one session at a time. For example, don't do stuff like this:</span>
759
- <a name="l00738"></a>00738 <span class="comment"> * @code</span>
760
- <a name="l00739"></a>00739 <span class="comment"> * ApplicationPoolPtr pool = server.connect();</span>
761
- <a name="l00740"></a>00740 <span class="comment"> * Application::SessionPtr session1 = pool-&gt;get(...);</span>
762
- <a name="l00741"></a>00741 <span class="comment"> * Application::SessionPtr session2 = pool-&gt;get(...);</span>
763
- <a name="l00742"></a>00742 <span class="comment"> * @endcode</span>
764
- <a name="l00743"></a>00743 <span class="comment"> * Otherwise, a deadlock can occur under certain circumstances.</span>
765
- <a name="l00744"></a>00744 <span class="comment"> * @warning</span>
766
- <a name="l00745"></a>00745 <span class="comment"> * Instead, one should call connect() multiple times:</span>
767
- <a name="l00746"></a>00746 <span class="comment"> * @code</span>
768
- <a name="l00747"></a>00747 <span class="comment"> * ApplicationPoolPtr pool1 = server.connect();</span>
769
- <a name="l00748"></a>00748 <span class="comment"> * Application::SessionPtr session1 = pool1-&gt;get(...);</span>
770
- <a name="l00749"></a>00749 <span class="comment"> * </span>
771
- <a name="l00750"></a>00750 <span class="comment"> * ApplicationPoolPtr pool2 = server.connect();</span>
772
- <a name="l00751"></a>00751 <span class="comment"> * Application::SessionPtr session2 = pool2-&gt;get(...);</span>
773
- <a name="l00752"></a>00752 <span class="comment"> * @endcode</span>
774
- <a name="l00753"></a>00753 <span class="comment"> *</span>
775
- <a name="l00754"></a>00754 <span class="comment"> * @throws SystemException Something went wrong.</span>
776
- <a name="l00755"></a>00755 <span class="comment"> * @throws IOException Something went wrong.</span>
777
- <a name="l00756"></a>00756 <span class="comment"> */</span>
778
- <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>() {
779
- <a name="l00758"></a>00758 TRACE_POINT();
780
- <a name="l00759"></a>00759 <span class="keywordflow">try</span> {
781
- <a name="l00760"></a>00760 this_thread::disable_syscall_interruption dsi;
782
- <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);
783
- <a name="l00762"></a>00762 <span class="keywordtype">int</span> clientConnection;
784
- <a name="l00763"></a>00763
785
- <a name="l00764"></a>00764 <span class="comment">// Write some random data to wake up the server.</span>
786
- <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);
787
- <a name="l00766"></a>00766
788
- <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>();
789
- <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));
790
- <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) {
791
- <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>());
792
- <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) {
793
- <a name="l00772"></a>00772 <span class="keywordtype">string</span> message(<span class="stringliteral">"Could not connect to the ApplicationPool server: "</span>);
794
- <a name="l00773"></a>00773 message.append(e.<a class="code" href="classPassenger_1_1IOException.html#1b65d0fdb9bc5136f5b7df759c14768a">what</a>());
795
- <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);
796
- <a name="l00775"></a>00775 }
797
- <a name="l00776"></a>00776 }
798
- <a name="l00777"></a>00777 <span class="comment"></span>
799
- <a name="l00778"></a>00778 <span class="comment"> /**</span>
800
- <a name="l00779"></a>00779 <span class="comment"> * Detach the server, thereby telling it that we don't want to connect</span>
801
- <a name="l00780"></a>00780 <span class="comment"> * to it anymore. This frees up some resources in the current process,</span>
802
- <a name="l00781"></a>00781 <span class="comment"> * such as file descriptors.</span>
803
- <a name="l00782"></a>00782 <span class="comment"> *</span>
804
- <a name="l00783"></a>00783 <span class="comment"> * This method is particularily useful to Apache worker processes that</span>
805
- <a name="l00784"></a>00784 <span class="comment"> * have just established a connection with the ApplicationPool server.</span>
806
- <a name="l00785"></a>00785 <span class="comment"> * Any sessions that are opened prior to calling detach(), will keep</span>
807
- <a name="l00786"></a>00786 <span class="comment"> * working even after a detach().</span>
808
- <a name="l00787"></a>00787 <span class="comment"> *</span>
809
- <a name="l00788"></a>00788 <span class="comment"> * This method may only be called once. The ApplicationPoolServer object</span>
810
- <a name="l00789"></a>00789 <span class="comment"> * will become unusable once detach() has been called, so call connect()</span>
811
- <a name="l00790"></a>00790 <span class="comment"> * before calling detach().</span>
812
- <a name="l00791"></a>00791 <span class="comment"> */</span>
813
- <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>() {
814
- <a name="l00793"></a>00793 TRACE_POINT();
815
- <a name="l00794"></a>00794 <span class="keywordtype">int</span> ret;
816
- <a name="l00795"></a>00795 <span class="keywordflow">do</span> {
817
- <a name="l00796"></a>00796 ret = close(serverSocket);
818
- <a name="l00797"></a>00797 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
819
- <a name="l00798"></a>00798 serverSocket = -1;
820
- <a name="l00799"></a>00799 }
821
- <a name="l00800"></a>00800 };
822
- <a name="l00801"></a>00801
823
- <a name="l00802"></a>00802 <span class="keyword">typedef</span> shared_ptr&lt;ApplicationPoolServer&gt; ApplicationPoolServerPtr;
824
- <a name="l00803"></a>00803
825
- <a name="l00804"></a>00804 } <span class="comment">// namespace Passenger</span>
826
- <a name="l00805"></a>00805
827
- <a name="l00806"></a>00806 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_APPLICATION_POOL_SERVER_H_ */</span>
828
- </pre></div></div>
829
- <hr size="1"><address style="text-align: right;"><small>Generated on Wed Apr 8 22:35:10 2009 for Passenger by&nbsp;
830
- <a href="http://www.doxygen.org/index.html">
831
- <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.8 </small></address>
832
- </body>
833
- </html>