passenger 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (243) hide show
  1. data/Rakefile +2 -1
  2. data/doc/Security of user switching support.html +1 -1
  3. data/doc/Users guide.html +1 -1
  4. data/ext/apache2/ApplicationPoolServerExecutable.cpp +4 -2
  5. data/ext/apache2/Bucket.cpp +104 -0
  6. data/ext/apache2/Bucket.h +36 -0
  7. data/ext/apache2/Configuration.h +1 -1
  8. data/ext/apache2/Hooks.cpp +2 -5
  9. data/ext/apache2/Utils.h +1 -1
  10. data/ext/boost/non_type.hpp +27 -0
  11. metadata +7 -247
  12. data/doc/Architectural overview.html +0 -740
  13. data/doc/cxxapi/ApplicationPoolServer_8h-source.html +0 -677
  14. data/doc/cxxapi/ApplicationPool_8h-source.html +0 -212
  15. data/doc/cxxapi/Application_8h-source.html +0 -448
  16. data/doc/cxxapi/Configuration_8h-source.html +0 -180
  17. data/doc/cxxapi/DummySpawnManager_8h-source.html +0 -126
  18. data/doc/cxxapi/Exceptions_8h-source.html +0 -244
  19. data/doc/cxxapi/Hooks_8h-source.html +0 -63
  20. data/doc/cxxapi/Logging_8h-source.html +0 -136
  21. data/doc/cxxapi/MessageChannel_8h-source.html +0 -524
  22. data/doc/cxxapi/SpawnManager_8h-source.html +0 -593
  23. data/doc/cxxapi/StandardApplicationPool_8h-source.html +0 -713
  24. data/doc/cxxapi/System_8h-source.html +0 -251
  25. data/doc/cxxapi/Utils_8h-source.html +0 -283
  26. data/doc/cxxapi/annotated.html +0 -59
  27. data/doc/cxxapi/classClient-members.html +0 -35
  28. data/doc/cxxapi/classClient.html +0 -117
  29. data/doc/cxxapi/classDirectoryMapper-members.html +0 -38
  30. data/doc/cxxapi/classDirectoryMapper.html +0 -203
  31. data/doc/cxxapi/classHooks-members.html +0 -33
  32. data/doc/cxxapi/classHooks.html +0 -43
  33. data/doc/cxxapi/classPassenger_1_1Application-members.html +0 -38
  34. data/doc/cxxapi/classPassenger_1_1Application.html +0 -229
  35. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +0 -40
  36. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +0 -331
  37. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +0 -36
  38. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +0 -225
  39. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.map +0 -1
  40. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.md5 +0 -1
  41. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
  42. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +0 -43
  43. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +0 -329
  44. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +0 -33
  45. data/doc/cxxapi/classPassenger_1_1BusyException.html +0 -47
  46. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +0 -33
  47. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +0 -44
  48. data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +0 -33
  49. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +0 -51
  50. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +0 -33
  51. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +0 -51
  52. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.map +0 -1
  53. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.md5 +0 -1
  54. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  55. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +0 -38
  56. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +0 -61
  57. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.map +0 -1
  58. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.md5 +0 -1
  59. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  60. data/doc/cxxapi/classPassenger_1_1IOException-members.html +0 -33
  61. data/doc/cxxapi/classPassenger_1_1IOException.html +0 -54
  62. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.map +0 -1
  63. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.md5 +0 -1
  64. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  65. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +0 -47
  66. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +0 -591
  67. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +0 -35
  68. data/doc/cxxapi/classPassenger_1_1SpawnException.html +0 -77
  69. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +0 -37
  70. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +0 -255
  71. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +0 -42
  72. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +0 -372
  73. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.map +0 -1
  74. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.md5 +0 -1
  75. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
  76. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +0 -37
  77. data/doc/cxxapi/classPassenger_1_1SystemException.html +0 -154
  78. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.map +0 -1
  79. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.md5 +0 -1
  80. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  81. data/doc/cxxapi/classPassenger_1_1TempFile-members.html +0 -36
  82. data/doc/cxxapi/classPassenger_1_1TempFile.html +0 -128
  83. data/doc/cxxapi/classPassenger_1_1Thread-members.html +0 -35
  84. data/doc/cxxapi/classPassenger_1_1Thread.html +0 -100
  85. data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption-members.html +0 -33
  86. data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption.html +0 -46
  87. data/doc/cxxapi/classboost_1_1this__thread_1_1enable__syscall__interruption-members.html +0 -33
  88. data/doc/cxxapi/classboost_1_1this__thread_1_1enable__syscall__interruption.html +0 -44
  89. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption-members.html +0 -33
  90. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption.html +0 -44
  91. data/doc/cxxapi/definitions_8h-source.html +0 -28
  92. data/doc/cxxapi/doxygen.css +0 -433
  93. data/doc/cxxapi/doxygen.png +0 -0
  94. data/doc/cxxapi/files.html +0 -41
  95. data/doc/cxxapi/ftv2blank.png +0 -0
  96. data/doc/cxxapi/ftv2doc.png +0 -0
  97. data/doc/cxxapi/ftv2folderclosed.png +0 -0
  98. data/doc/cxxapi/ftv2folderopen.png +0 -0
  99. data/doc/cxxapi/ftv2lastnode.png +0 -0
  100. data/doc/cxxapi/ftv2link.png +0 -0
  101. data/doc/cxxapi/ftv2mlastnode.png +0 -0
  102. data/doc/cxxapi/ftv2mnode.png +0 -0
  103. data/doc/cxxapi/ftv2node.png +0 -0
  104. data/doc/cxxapi/ftv2plastnode.png +0 -0
  105. data/doc/cxxapi/ftv2pnode.png +0 -0
  106. data/doc/cxxapi/ftv2vertline.png +0 -0
  107. data/doc/cxxapi/functions.html +0 -212
  108. data/doc/cxxapi/functions_func.html +0 -207
  109. data/doc/cxxapi/functions_type.html +0 -46
  110. data/doc/cxxapi/functions_vars.html +0 -48
  111. data/doc/cxxapi/graph_legend.dot +0 -22
  112. data/doc/cxxapi/graph_legend.html +0 -87
  113. data/doc/cxxapi/graph_legend.png +0 -0
  114. data/doc/cxxapi/group__Configuration.html +0 -236
  115. data/doc/cxxapi/group__Configuration.png +0 -0
  116. data/doc/cxxapi/group__Core.html +0 -51
  117. data/doc/cxxapi/group__Core.png +0 -0
  118. data/doc/cxxapi/group__Exceptions.html +0 -43
  119. data/doc/cxxapi/group__Hooks.html +0 -46
  120. data/doc/cxxapi/group__Hooks.png +0 -0
  121. data/doc/cxxapi/group__Support.html +0 -406
  122. data/doc/cxxapi/hierarchy.html +0 -67
  123. data/doc/cxxapi/index.html +0 -11
  124. data/doc/cxxapi/inherit__graph__0.map +0 -1
  125. data/doc/cxxapi/inherit__graph__0.md5 +0 -1
  126. data/doc/cxxapi/inherit__graph__0.png +0 -0
  127. data/doc/cxxapi/inherit__graph__1.map +0 -1
  128. data/doc/cxxapi/inherit__graph__1.md5 +0 -1
  129. data/doc/cxxapi/inherit__graph__1.png +0 -0
  130. data/doc/cxxapi/inherit__graph__10.map +0 -1
  131. data/doc/cxxapi/inherit__graph__10.md5 +0 -1
  132. data/doc/cxxapi/inherit__graph__10.png +0 -0
  133. data/doc/cxxapi/inherit__graph__11.map +0 -1
  134. data/doc/cxxapi/inherit__graph__11.md5 +0 -1
  135. data/doc/cxxapi/inherit__graph__11.png +0 -0
  136. data/doc/cxxapi/inherit__graph__12.map +0 -1
  137. data/doc/cxxapi/inherit__graph__12.md5 +0 -1
  138. data/doc/cxxapi/inherit__graph__12.png +0 -0
  139. data/doc/cxxapi/inherit__graph__13.map +0 -1
  140. data/doc/cxxapi/inherit__graph__13.md5 +0 -1
  141. data/doc/cxxapi/inherit__graph__13.png +0 -0
  142. data/doc/cxxapi/inherit__graph__14.map +0 -2
  143. data/doc/cxxapi/inherit__graph__14.md5 +0 -1
  144. data/doc/cxxapi/inherit__graph__14.png +0 -0
  145. data/doc/cxxapi/inherit__graph__15.map +0 -1
  146. data/doc/cxxapi/inherit__graph__15.md5 +0 -1
  147. data/doc/cxxapi/inherit__graph__15.png +0 -0
  148. data/doc/cxxapi/inherit__graph__16.map +0 -1
  149. data/doc/cxxapi/inherit__graph__16.md5 +0 -1
  150. data/doc/cxxapi/inherit__graph__16.png +0 -0
  151. data/doc/cxxapi/inherit__graph__17.map +0 -1
  152. data/doc/cxxapi/inherit__graph__17.md5 +0 -1
  153. data/doc/cxxapi/inherit__graph__17.png +0 -0
  154. data/doc/cxxapi/inherit__graph__2.map +0 -1
  155. data/doc/cxxapi/inherit__graph__2.md5 +0 -1
  156. data/doc/cxxapi/inherit__graph__2.png +0 -0
  157. data/doc/cxxapi/inherit__graph__3.map +0 -1
  158. data/doc/cxxapi/inherit__graph__3.md5 +0 -1
  159. data/doc/cxxapi/inherit__graph__3.png +0 -0
  160. data/doc/cxxapi/inherit__graph__4.map +0 -1
  161. data/doc/cxxapi/inherit__graph__4.md5 +0 -1
  162. data/doc/cxxapi/inherit__graph__4.png +0 -0
  163. data/doc/cxxapi/inherit__graph__5.map +0 -1
  164. data/doc/cxxapi/inherit__graph__5.md5 +0 -1
  165. data/doc/cxxapi/inherit__graph__5.png +0 -0
  166. data/doc/cxxapi/inherit__graph__6.map +0 -1
  167. data/doc/cxxapi/inherit__graph__6.md5 +0 -1
  168. data/doc/cxxapi/inherit__graph__6.png +0 -0
  169. data/doc/cxxapi/inherit__graph__7.map +0 -1
  170. data/doc/cxxapi/inherit__graph__7.md5 +0 -1
  171. data/doc/cxxapi/inherit__graph__7.png +0 -0
  172. data/doc/cxxapi/inherit__graph__8.map +0 -1
  173. data/doc/cxxapi/inherit__graph__8.md5 +0 -1
  174. data/doc/cxxapi/inherit__graph__8.png +0 -0
  175. data/doc/cxxapi/inherit__graph__9.map +0 -2
  176. data/doc/cxxapi/inherit__graph__9.md5 +0 -1
  177. data/doc/cxxapi/inherit__graph__9.png +0 -0
  178. data/doc/cxxapi/inherits.html +0 -102
  179. data/doc/cxxapi/main.html +0 -27
  180. data/doc/cxxapi/modules.html +0 -34
  181. data/doc/cxxapi/namespacePassenger.html +0 -208
  182. data/doc/cxxapi/namespacePassenger_1_1InterruptableCalls.html +0 -43
  183. data/doc/cxxapi/namespacemembers.html +0 -70
  184. data/doc/cxxapi/namespacemembers_func.html +0 -66
  185. data/doc/cxxapi/namespacemembers_type.html +0 -46
  186. data/doc/cxxapi/namespaces.html +0 -35
  187. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +0 -33
  188. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +0 -49
  189. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +0 -33
  190. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +0 -49
  191. data/doc/cxxapi/tab_b.gif +0 -0
  192. data/doc/cxxapi/tab_l.gif +0 -0
  193. data/doc/cxxapi/tab_r.gif +0 -0
  194. data/doc/cxxapi/tabs.css +0 -102
  195. data/doc/cxxapi/tree.html +0 -166
  196. data/doc/rdoc/classes/ConditionVariable.html +0 -160
  197. data/doc/rdoc/classes/Exception.html +0 -120
  198. data/doc/rdoc/classes/GC.html +0 -113
  199. data/doc/rdoc/classes/IO.html +0 -150
  200. data/doc/rdoc/classes/Passenger.html +0 -136
  201. data/doc/rdoc/classes/Passenger/AbstractRequestHandler.html +0 -401
  202. data/doc/rdoc/classes/Passenger/AbstractServer.html +0 -649
  203. data/doc/rdoc/classes/Passenger/AbstractServer/ServerAlreadyStarted.html +0 -97
  204. data/doc/rdoc/classes/Passenger/AbstractServer/ServerError.html +0 -96
  205. data/doc/rdoc/classes/Passenger/AbstractServer/ServerNotStarted.html +0 -97
  206. data/doc/rdoc/classes/Passenger/AbstractServer/UnknownMessage.html +0 -96
  207. data/doc/rdoc/classes/Passenger/AppInitError.html +0 -137
  208. data/doc/rdoc/classes/Passenger/Application.html +0 -296
  209. data/doc/rdoc/classes/Passenger/ConsoleTextTemplate.html +0 -172
  210. data/doc/rdoc/classes/Passenger/FrameworkInitError.html +0 -143
  211. data/doc/rdoc/classes/Passenger/HTMLTemplate.html +0 -175
  212. data/doc/rdoc/classes/Passenger/InitializationError.html +0 -141
  213. data/doc/rdoc/classes/Passenger/MessageChannel.html +0 -488
  214. data/doc/rdoc/classes/Passenger/NativeSupport.html +0 -320
  215. data/doc/rdoc/classes/Passenger/SpawnManager.html +0 -375
  216. data/doc/rdoc/classes/Passenger/UnknownError.html +0 -125
  217. data/doc/rdoc/classes/Passenger/Utils.html +0 -580
  218. data/doc/rdoc/classes/Passenger/VersionNotFound.html +0 -140
  219. data/doc/rdoc/classes/PlatformInfo.html +0 -292
  220. data/doc/rdoc/classes/RakeExtensions.html +0 -197
  221. data/doc/rdoc/created.rid +0 -1
  222. data/doc/rdoc/files/DEVELOPERS_TXT.html +0 -230
  223. data/doc/rdoc/files/README.html +0 -150
  224. data/doc/rdoc/files/ext/passenger/native_support_c.html +0 -92
  225. data/doc/rdoc/files/lib/passenger/abstract_request_handler_rb.html +0 -125
  226. data/doc/rdoc/files/lib/passenger/abstract_server_rb.html +0 -127
  227. data/doc/rdoc/files/lib/passenger/application_rb.html +0 -123
  228. data/doc/rdoc/files/lib/passenger/console_text_template_rb.html +0 -122
  229. data/doc/rdoc/files/lib/passenger/constants_rb.html +0 -114
  230. data/doc/rdoc/files/lib/passenger/dependencies_rb.html +0 -130
  231. data/doc/rdoc/files/lib/passenger/exceptions_rb.html +0 -118
  232. data/doc/rdoc/files/lib/passenger/html_template_rb.html +0 -122
  233. data/doc/rdoc/files/lib/passenger/message_channel_rb.html +0 -118
  234. data/doc/rdoc/files/lib/passenger/platform_info_rb.html +0 -122
  235. data/doc/rdoc/files/lib/passenger/simple_benchmarking_rb.html +0 -118
  236. data/doc/rdoc/files/lib/passenger/spawn_manager_rb.html +0 -139
  237. data/doc/rdoc/files/lib/passenger/utils_rb.html +0 -130
  238. data/doc/rdoc/files/lib/rake/extensions_rb.html +0 -122
  239. data/doc/rdoc/fr_class_index.html +0 -71
  240. data/doc/rdoc/fr_file_index.html +0 -63
  241. data/doc/rdoc/fr_method_index.html +0 -120
  242. data/doc/rdoc/index.html +0 -26
  243. data/doc/rdoc/rdoc-style.css +0 -187
@@ -1,713 +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: StandardApplicationPool.h Source File</title>
4
- <link href="doxygen.css" rel="stylesheet" type="text/css">
5
- <link href="tabs.css" rel="stylesheet" type="text/css">
6
- </head><body>
7
- <!-- Generated by Doxygen 1.5.5 -->
8
- <div class="navigation" id="top">
9
- <div class="tabs">
10
- <ul>
11
- <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
12
- <li><a href="modules.html"><span>Modules</span></a></li>
13
- <li><a href="namespaces.html"><span>Namespaces</span></a></li>
14
- <li><a href="annotated.html"><span>Classes</span></a></li>
15
- <li class="current"><a href="files.html"><span>Files</span></a></li>
16
- </ul>
17
- </div>
18
- <h1>StandardApplicationPool.h</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
19
- <a name="l00002"></a>00002 <span class="comment"> * Phusion Passenger - http://www.modrails.com/</span>
20
- <a name="l00003"></a>00003 <span class="comment"> * Copyright (C) 2008 Phusion</span>
21
- <a name="l00004"></a>00004 <span class="comment"> *</span>
22
- <a name="l00005"></a>00005 <span class="comment"> * Phusion Passenger is a trademark of Hongli Lai &amp; Ninh Bui.</span>
23
- <a name="l00006"></a>00006 <span class="comment"> *</span>
24
- <a name="l00007"></a>00007 <span class="comment"> * This program is free software; you can redistribute it and/or modify</span>
25
- <a name="l00008"></a>00008 <span class="comment"> * it under the terms of the GNU General Public License as published by</span>
26
- <a name="l00009"></a>00009 <span class="comment"> * the Free Software Foundation; version 2 of the License.</span>
27
- <a name="l00010"></a>00010 <span class="comment"> *</span>
28
- <a name="l00011"></a>00011 <span class="comment"> * This program is distributed in the hope that it will be useful,</span>
29
- <a name="l00012"></a>00012 <span class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
30
- <a name="l00013"></a>00013 <span class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
31
- <a name="l00014"></a>00014 <span class="comment"> * GNU General Public License for more details.</span>
32
- <a name="l00015"></a>00015 <span class="comment"> *</span>
33
- <a name="l00016"></a>00016 <span class="comment"> * You should have received a copy of the GNU General Public License along</span>
34
- <a name="l00017"></a>00017 <span class="comment"> * with this program; if not, write to the Free Software Foundation, Inc.,</span>
35
- <a name="l00018"></a>00018 <span class="comment"> * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span>
36
- <a name="l00019"></a>00019 <span class="comment"> */</span>
37
- <a name="l00020"></a>00020 <span class="preprocessor">#ifndef _PASSENGER_STANDARD_APPLICATION_POOL_H_</span>
38
- <a name="l00021"></a>00021 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_STANDARD_APPLICATION_POOL_H_</span>
39
- <a name="l00022"></a>00022 <span class="preprocessor"></span>
40
- <a name="l00023"></a>00023 <span class="preprocessor">#include &lt;boost/shared_ptr.hpp&gt;</span>
41
- <a name="l00024"></a>00024 <span class="preprocessor">#include &lt;boost/weak_ptr.hpp&gt;</span>
42
- <a name="l00025"></a>00025 <span class="preprocessor">#include &lt;boost/thread.hpp&gt;</span>
43
- <a name="l00026"></a>00026 <span class="preprocessor">#include &lt;boost/bind.hpp&gt;</span>
44
- <a name="l00027"></a>00027 <span class="preprocessor">#include &lt;boost/date_time/microsec_time_clock.hpp&gt;</span>
45
- <a name="l00028"></a>00028 <span class="preprocessor">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt;</span>
46
- <a name="l00029"></a>00029
47
- <a name="l00030"></a>00030 <span class="preprocessor">#include &lt;string&gt;</span>
48
- <a name="l00031"></a>00031 <span class="preprocessor">#include &lt;sstream&gt;</span>
49
- <a name="l00032"></a>00032 <span class="preprocessor">#include &lt;map&gt;</span>
50
- <a name="l00033"></a>00033 <span class="preprocessor">#include &lt;list&gt;</span>
51
- <a name="l00034"></a>00034
52
- <a name="l00035"></a>00035 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
53
- <a name="l00036"></a>00036 <span class="preprocessor">#include &lt;sys/stat.h&gt;</span>
54
- <a name="l00037"></a>00037 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
55
- <a name="l00038"></a>00038 <span class="preprocessor">#include &lt;unistd.h&gt;</span>
56
- <a name="l00039"></a>00039 <span class="preprocessor">#include &lt;ctime&gt;</span>
57
- <a name="l00040"></a>00040 <span class="preprocessor">#include &lt;cerrno&gt;</span>
58
- <a name="l00041"></a>00041 <span class="preprocessor">#ifdef TESTING_APPLICATION_POOL</span>
59
- <a name="l00042"></a>00042 <span class="preprocessor"></span><span class="preprocessor"> #include &lt;cstdlib&gt;</span>
60
- <a name="l00043"></a>00043 <span class="preprocessor">#endif</span>
61
- <a name="l00044"></a>00044 <span class="preprocessor"></span>
62
- <a name="l00045"></a>00045 <span class="preprocessor">#include "ApplicationPool.h"</span>
63
- <a name="l00046"></a>00046 <span class="preprocessor">#include "Logging.h"</span>
64
- <a name="l00047"></a>00047 <span class="preprocessor">#include "System.h"</span>
65
- <a name="l00048"></a>00048 <span class="preprocessor">#ifdef PASSENGER_USE_DUMMY_SPAWN_MANAGER</span>
66
- <a name="l00049"></a>00049 <span class="preprocessor"></span><span class="preprocessor"> #include "DummySpawnManager.h"</span>
67
- <a name="l00050"></a>00050 <span class="preprocessor">#else</span>
68
- <a name="l00051"></a>00051 <span class="preprocessor"></span><span class="preprocessor"> #include "SpawnManager.h"</span>
69
- <a name="l00052"></a>00052 <span class="preprocessor">#endif</span>
70
- <a name="l00053"></a>00053 <span class="preprocessor"></span>
71
- <a name="l00054"></a>00054 <span class="keyword">namespace </span>Passenger {
72
- <a name="l00055"></a>00055
73
- <a name="l00056"></a>00056 <span class="keyword">using namespace </span>std;
74
- <a name="l00057"></a>00057 <span class="keyword">using namespace </span>boost;
75
- <a name="l00058"></a>00058
76
- <a name="l00059"></a>00059 <span class="keyword">class </span>ApplicationPoolServer;
77
- <a name="l00060"></a>00060
78
- <a name="l00061"></a>00061 <span class="comment">/****************************************************************</span>
79
- <a name="l00062"></a>00062 <span class="comment"> *</span>
80
- <a name="l00063"></a>00063 <span class="comment"> * See "doc/ApplicationPool algorithm.txt" for a more readable</span>
81
- <a name="l00064"></a>00064 <span class="comment"> * and detailed description of the algorithm implemented here.</span>
82
- <a name="l00065"></a>00065 <span class="comment"> *</span>
83
- <a name="l00066"></a>00066 <span class="comment"> ****************************************************************/</span>
84
- <a name="l00067"></a>00067 <span class="comment"></span>
85
- <a name="l00068"></a>00068 <span class="comment">/**</span>
86
- <a name="l00069"></a>00069 <span class="comment"> * A standard implementation of ApplicationPool for single-process environments.</span>
87
- <a name="l00070"></a>00070 <span class="comment"> *</span>
88
- <a name="l00071"></a>00071 <span class="comment"> * The environment may or may not be multithreaded - StandardApplicationPool is completely</span>
89
- <a name="l00072"></a>00072 <span class="comment"> * thread-safe. Apache with the threading MPM is an example of a multithreaded single-process</span>
90
- <a name="l00073"></a>00073 <span class="comment"> * environment.</span>
91
- <a name="l00074"></a>00074 <span class="comment"> *</span>
92
- <a name="l00075"></a>00075 <span class="comment"> * This class is unusable in multi-process environments such as Apache with the prefork MPM.</span>
93
- <a name="l00076"></a>00076 <span class="comment"> * The reasons are as follows:</span>
94
- <a name="l00077"></a>00077 <span class="comment"> * - StandardApplicationPool uses threads internally. Because threads disappear after a fork(),</span>
95
- <a name="l00078"></a>00078 <span class="comment"> * a StandardApplicationPool object will become unusable after a fork().</span>
96
- <a name="l00079"></a>00079 <span class="comment"> * - StandardApplicationPool stores its internal cache on the heap. Different processes</span>
97
- <a name="l00080"></a>00080 <span class="comment"> * cannot share their heaps, so they will not be able to access each others' pool cache.</span>
98
- <a name="l00081"></a>00081 <span class="comment"> * - StandardApplicationPool has a connection to the spawn server. If there are multiple</span>
99
- <a name="l00082"></a>00082 <span class="comment"> * processes, and they all use the spawn servers's connection at the same time without</span>
100
- <a name="l00083"></a>00083 <span class="comment"> * some sort of synchronization, then bad things will happen.</span>
101
- <a name="l00084"></a>00084 <span class="comment"> *</span>
102
- <a name="l00085"></a>00085 <span class="comment"> * (Of course, StandardApplicationPool &lt;em&gt;is&lt;/em&gt; usable if each process creates its own</span>
103
- <a name="l00086"></a>00086 <span class="comment"> * StandardApplicationPool object, but that would defeat the point of having a shared pool.)</span>
104
- <a name="l00087"></a>00087 <span class="comment"> *</span>
105
- <a name="l00088"></a>00088 <span class="comment"> * For multi-process environments, one should use ApplicationPoolServer instead.</span>
106
- <a name="l00089"></a>00089 <span class="comment"> *</span>
107
- <a name="l00090"></a>00090 <span class="comment"> * @ingroup Support</span>
108
- <a name="l00091"></a>00091 <span class="comment"> */</span>
109
- <a name="l00092"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html">00092</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1StandardApplicationPool.html" title="A standard implementation of ApplicationPool for single-process environments.">StandardApplicationPool</a>: <span class="keyword">public</span> <a class="code" href="classPassenger_1_1ApplicationPool.html" title="A persistent pool of Applications.">ApplicationPool</a> {
110
- <a name="l00093"></a>00093 <span class="keyword">private</span>:
111
- <a name="l00094"></a>00094 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> DEFAULT_MAX_IDLE_TIME = 120;
112
- <a name="l00095"></a>00095 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> DEFAULT_MAX_POOL_SIZE = 20;
113
- <a name="l00096"></a>00096 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> DEFAULT_MAX_INSTANCES_PER_APP = 0;
114
- <a name="l00097"></a>00097 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> CLEANER_THREAD_STACK_SIZE = 1024 * 128;
115
- <a name="l00098"></a>00098 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MAX_GET_ATTEMPTS = 10;
116
- <a name="l00099"></a>00099 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GET_TIMEOUT = 5000; <span class="comment">// In milliseconds.</span>
117
- <a name="l00100"></a>00100
118
- <a name="l00101"></a>00101 <span class="keyword">friend</span> <span class="keyword">class </span><a class="code" href="classPassenger_1_1ApplicationPoolServer.html" title="Multi-process usage support for ApplicationPool.">ApplicationPoolServer</a>;
119
- <a name="l00102"></a>00102 <span class="keyword">struct </span>AppContainer;
120
- <a name="l00103"></a>00103
121
- <a name="l00104"></a>00104 <span class="keyword">typedef</span> shared_ptr&lt;AppContainer&gt; AppContainerPtr;
122
- <a name="l00105"></a>00105 <span class="keyword">typedef</span> list&lt;AppContainerPtr&gt; AppContainerList;
123
- <a name="l00106"></a>00106 <span class="keyword">typedef</span> shared_ptr&lt;AppContainerList&gt; AppContainerListPtr;
124
- <a name="l00107"></a>00107 <span class="keyword">typedef</span> map&lt;string, AppContainerListPtr&gt; ApplicationMap;
125
- <a name="l00108"></a>00108
126
- <a name="l00109"></a>00109 <span class="keyword">struct </span>AppContainer {
127
- <a name="l00110"></a>00110 <a class="code" href="namespacePassenger.html#6a15fd5e8765802a0b8b077e15297e18" title="Convenient alias for Application smart pointer.">ApplicationPtr</a> app;
128
- <a name="l00111"></a>00111 time_t lastUsed;
129
- <a name="l00112"></a>00112 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> sessions;
130
- <a name="l00113"></a>00113 AppContainerList::iterator iterator;
131
- <a name="l00114"></a>00114 AppContainerList::iterator ia_iterator;
132
- <a name="l00115"></a>00115 };
133
- <a name="l00116"></a>00116
134
- <a name="l00117"></a>00117 <span class="keyword">struct </span>SharedData {
135
- <a name="l00118"></a>00118 mutex lock;
136
- <a name="l00119"></a>00119 condition activeOrMaxChanged;
137
- <a name="l00120"></a>00120
138
- <a name="l00121"></a>00121 ApplicationMap apps;
139
- <a name="l00122"></a>00122 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> max;
140
- <a name="l00123"></a>00123 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> count;
141
- <a name="l00124"></a>00124 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> active;
142
- <a name="l00125"></a>00125 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> maxPerApp;
143
- <a name="l00126"></a>00126 AppContainerList inactiveApps;
144
- <a name="l00127"></a>00127 map&lt;string, time_t&gt; restartFileTimes;
145
- <a name="l00128"></a>00128 map&lt;string, unsigned int&gt; appInstanceCount;
146
- <a name="l00129"></a>00129 };
147
- <a name="l00130"></a>00130
148
- <a name="l00131"></a>00131 <span class="keyword">typedef</span> shared_ptr&lt;SharedData&gt; SharedDataPtr;
149
- <a name="l00132"></a>00132
150
- <a name="l00133"></a>00133 <span class="keyword">struct </span>SessionCloseCallback {
151
- <a name="l00134"></a>00134 SharedDataPtr data;
152
- <a name="l00135"></a>00135 weak_ptr&lt;AppContainer&gt; container;
153
- <a name="l00136"></a>00136
154
- <a name="l00137"></a>00137 SessionCloseCallback(SharedDataPtr data,
155
- <a name="l00138"></a>00138 <span class="keyword">const</span> weak_ptr&lt;AppContainer&gt; &amp;container) {
156
- <a name="l00139"></a>00139 this-&gt;data = data;
157
- <a name="l00140"></a>00140 this-&gt;container = container;
158
- <a name="l00141"></a>00141 }
159
- <a name="l00142"></a>00142
160
- <a name="l00143"></a>00143 <span class="keywordtype">void</span> operator()() {
161
- <a name="l00144"></a>00144 mutex::scoped_lock l(data-&gt;lock);
162
- <a name="l00145"></a>00145 AppContainerPtr container(this-&gt;container.lock());
163
- <a name="l00146"></a>00146
164
- <a name="l00147"></a>00147 <span class="keywordflow">if</span> (container == NULL) {
165
- <a name="l00148"></a>00148 <span class="keywordflow">return</span>;
166
- <a name="l00149"></a>00149 }
167
- <a name="l00150"></a>00150
168
- <a name="l00151"></a>00151 ApplicationMap::iterator it;
169
- <a name="l00152"></a>00152 it = data-&gt;apps.find(container-&gt;app-&gt;getAppRoot());
170
- <a name="l00153"></a>00153 <span class="keywordflow">if</span> (it != data-&gt;apps.end()) {
171
- <a name="l00154"></a>00154 AppContainerListPtr list(it-&gt;second);
172
- <a name="l00155"></a>00155 container-&gt;lastUsed = time(NULL);
173
- <a name="l00156"></a>00156 container-&gt;sessions--;
174
- <a name="l00157"></a>00157 <span class="keywordflow">if</span> (container-&gt;sessions == 0) {
175
- <a name="l00158"></a>00158 list-&gt;erase(container-&gt;iterator);
176
- <a name="l00159"></a>00159 list-&gt;push_front(container);
177
- <a name="l00160"></a>00160 container-&gt;iterator = list-&gt;begin();
178
- <a name="l00161"></a>00161 data-&gt;inactiveApps.push_back(container);
179
- <a name="l00162"></a>00162 container-&gt;ia_iterator = data-&gt;inactiveApps.end();
180
- <a name="l00163"></a>00163 container-&gt;ia_iterator--;
181
- <a name="l00164"></a>00164 data-&gt;active--;
182
- <a name="l00165"></a>00165 data-&gt;activeOrMaxChanged.notify_all();
183
- <a name="l00166"></a>00166 }
184
- <a name="l00167"></a>00167 }
185
- <a name="l00168"></a>00168 }
186
- <a name="l00169"></a>00169 };
187
- <a name="l00170"></a>00170
188
- <a name="l00171"></a>00171 <span class="preprocessor"> #ifdef PASSENGER_USE_DUMMY_SPAWN_MANAGER</span>
189
- <a name="l00172"></a>00172 <span class="preprocessor"></span> <a class="code" href="classPassenger_1_1DummySpawnManager.html" title="A dummy SpawnManager replacement for testing/debugging purposes.">DummySpawnManager</a> spawnManager;
190
- <a name="l00173"></a>00173 <span class="preprocessor"> #else</span>
191
- <a name="l00174"></a>00174 <span class="preprocessor"></span> <a class="code" href="classPassenger_1_1SpawnManager.html" title="Spawning of Ruby on Rails/Rack application instances.">SpawnManager</a> spawnManager;
192
- <a name="l00175"></a>00175 <span class="preprocessor"> #endif</span>
193
- <a name="l00176"></a>00176 <span class="preprocessor"></span> SharedDataPtr data;
194
- <a name="l00177"></a>00177 thread *cleanerThread;
195
- <a name="l00178"></a>00178 <span class="keywordtype">bool</span> detached;
196
- <a name="l00179"></a>00179 <span class="keywordtype">bool</span> done;
197
- <a name="l00180"></a>00180 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> maxIdleTime;
198
- <a name="l00181"></a>00181 condition cleanerThreadSleeper;
199
- <a name="l00182"></a>00182
200
- <a name="l00183"></a>00183 <span class="comment">// Shortcuts for instance variables in SharedData. Saves typing in get().</span>
201
- <a name="l00184"></a>00184 mutex &amp;lock;
202
- <a name="l00185"></a>00185 condition &amp;activeOrMaxChanged;
203
- <a name="l00186"></a>00186 ApplicationMap &amp;apps;
204
- <a name="l00187"></a>00187 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &amp;max;
205
- <a name="l00188"></a>00188 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &amp;count;
206
- <a name="l00189"></a>00189 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &amp;active;
207
- <a name="l00190"></a>00190 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &amp;maxPerApp;
208
- <a name="l00191"></a>00191 AppContainerList &amp;inactiveApps;
209
- <a name="l00192"></a>00192 map&lt;string, time_t&gt; &amp;restartFileTimes;
210
- <a name="l00193"></a>00193 map&lt;string, unsigned int&gt; &amp;appInstanceCount;
211
- <a name="l00194"></a>00194 <span class="comment"></span>
212
- <a name="l00195"></a>00195 <span class="comment"> /**</span>
213
- <a name="l00196"></a>00196 <span class="comment"> * Verify that all the invariants are correct.</span>
214
- <a name="l00197"></a>00197 <span class="comment"> */</span>
215
- <a name="l00198"></a>00198 <span class="keywordtype">bool</span> <span class="keyword">inline</span> verifyState() {
216
- <a name="l00199"></a>00199 <span class="preprocessor"> #if PASSENGER_DEBUG</span>
217
- <a name="l00200"></a>00200 <span class="preprocessor"></span> <span class="comment">// Invariant for _apps_.</span>
218
- <a name="l00201"></a>00201 ApplicationMap::const_iterator it;
219
- <a name="l00202"></a>00202 <span class="keywordflow">for</span> (it = apps.begin(); it != apps.end(); it++) {
220
- <a name="l00203"></a>00203 AppContainerList *list = it-&gt;second.get();
221
- <a name="l00204"></a>00204 P_ASSERT(!list-&gt;empty(), <span class="keyword">false</span>, <span class="stringliteral">"List for '"</span> &lt;&lt; it-&gt;first &lt;&lt; <span class="stringliteral">"' is nonempty."</span>);
222
- <a name="l00205"></a>00205
223
- <a name="l00206"></a>00206 AppContainerList::const_iterator prev_lit;
224
- <a name="l00207"></a>00207 AppContainerList::const_iterator lit;
225
- <a name="l00208"></a>00208 prev_lit = list-&gt;begin();
226
- <a name="l00209"></a>00209 lit = prev_lit;
227
- <a name="l00210"></a>00210 lit++;
228
- <a name="l00211"></a>00211 <span class="keywordflow">for</span> (; lit != list-&gt;end(); lit++) {
229
- <a name="l00212"></a>00212 <span class="keywordflow">if</span> ((*prev_lit)-&gt;sessions &gt; 0) {
230
- <a name="l00213"></a>00213 P_ASSERT((*lit)-&gt;sessions &gt; 0, <span class="keyword">false</span>,
231
- <a name="l00214"></a>00214 <span class="stringliteral">"List for '"</span> &lt;&lt; it-&gt;first &lt;&lt;
232
- <a name="l00215"></a>00215 <span class="stringliteral">"' is sorted from nonactive to active"</span>);
233
- <a name="l00216"></a>00216 }
234
- <a name="l00217"></a>00217 }
235
- <a name="l00218"></a>00218 }
236
- <a name="l00219"></a>00219
237
- <a name="l00220"></a>00220 P_ASSERT(active &lt;= count, <span class="keyword">false</span>,
238
- <a name="l00221"></a>00221 <span class="stringliteral">"active ("</span> &lt;&lt; active &lt;&lt; <span class="stringliteral">") &lt; count ("</span> &lt;&lt; count &lt;&lt; <span class="stringliteral">")"</span>);
239
- <a name="l00222"></a>00222 P_ASSERT(inactiveApps.size() == count - active, <span class="keyword">false</span>,
240
- <a name="l00223"></a>00223 <span class="stringliteral">"inactive_apps.size() == count - active"</span>);
241
- <a name="l00224"></a>00224 <span class="preprocessor"> #endif</span>
242
- <a name="l00225"></a>00225 <span class="preprocessor"></span> <span class="keywordflow">return</span> <span class="keyword">true</span>;
243
- <a name="l00226"></a>00226 }
244
- <a name="l00227"></a>00227
245
- <a name="l00228"></a>00228 <span class="keyword">template</span>&lt;<span class="keyword">typename</span> LockActionType&gt;
246
- <a name="l00229"></a>00229 <span class="keywordtype">string</span> toString(LockActionType lockAction)<span class="keyword"> const </span>{
247
- <a name="l00230"></a>00230 unique_lock&lt;mutex&gt; l(lock, lockAction);
248
- <a name="l00231"></a>00231 stringstream result;
249
- <a name="l00232"></a>00232
250
- <a name="l00233"></a>00233 result &lt;&lt; <span class="stringliteral">"----------- General information -----------"</span> &lt;&lt; endl;
251
- <a name="l00234"></a>00234 result &lt;&lt; <span class="stringliteral">"max = "</span> &lt;&lt; max &lt;&lt; endl;
252
- <a name="l00235"></a>00235 result &lt;&lt; <span class="stringliteral">"count = "</span> &lt;&lt; count &lt;&lt; endl;
253
- <a name="l00236"></a>00236 result &lt;&lt; <span class="stringliteral">"active = "</span> &lt;&lt; active &lt;&lt; endl;
254
- <a name="l00237"></a>00237 result &lt;&lt; <span class="stringliteral">"inactive = "</span> &lt;&lt; inactiveApps.size() &lt;&lt; endl;
255
- <a name="l00238"></a>00238 result &lt;&lt; endl;
256
- <a name="l00239"></a>00239
257
- <a name="l00240"></a>00240 result &lt;&lt; <span class="stringliteral">"----------- Applications -----------"</span> &lt;&lt; endl;
258
- <a name="l00241"></a>00241 ApplicationMap::const_iterator it;
259
- <a name="l00242"></a>00242 <span class="keywordflow">for</span> (it = apps.begin(); it != apps.end(); it++) {
260
- <a name="l00243"></a>00243 AppContainerList *list = it-&gt;second.get();
261
- <a name="l00244"></a>00244 AppContainerList::const_iterator lit;
262
- <a name="l00245"></a>00245
263
- <a name="l00246"></a>00246 result &lt;&lt; it-&gt;first &lt;&lt; <span class="stringliteral">": "</span> &lt;&lt; endl;
264
- <a name="l00247"></a>00247 <span class="keywordflow">for</span> (lit = list-&gt;begin(); lit != list-&gt;end(); lit++) {
265
- <a name="l00248"></a>00248 AppContainer *container = lit-&gt;get();
266
- <a name="l00249"></a>00249 <span class="keywordtype">char</span> buf[128];
267
- <a name="l00250"></a>00250
268
- <a name="l00251"></a>00251 snprintf(buf, <span class="keyword">sizeof</span>(buf), <span class="stringliteral">"PID: %-8d Sessions: %d"</span>,
269
- <a name="l00252"></a>00252 container-&gt;app-&gt;getPid(), container-&gt;sessions);
270
- <a name="l00253"></a>00253 result &lt;&lt; <span class="stringliteral">" "</span> &lt;&lt; buf &lt;&lt; endl;
271
- <a name="l00254"></a>00254 }
272
- <a name="l00255"></a>00255 result &lt;&lt; endl;
273
- <a name="l00256"></a>00256 }
274
- <a name="l00257"></a>00257 <span class="keywordflow">return</span> result.str();
275
- <a name="l00258"></a>00258 }
276
- <a name="l00259"></a>00259
277
- <a name="l00260"></a>00260 <span class="keywordtype">bool</span> needsRestart(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot) {
278
- <a name="l00261"></a>00261 <span class="keywordtype">string</span> restartFile(appRoot);
279
- <a name="l00262"></a>00262 restartFile.append(<span class="stringliteral">"/tmp/restart.txt"</span>);
280
- <a name="l00263"></a>00263
281
- <a name="l00264"></a>00264 <span class="keyword">struct </span>stat buf;
282
- <a name="l00265"></a>00265 <span class="keywordtype">bool</span> result;
283
- <a name="l00266"></a>00266 <span class="keywordtype">int</span> ret;
284
- <a name="l00267"></a>00267
285
- <a name="l00268"></a>00268 <span class="keywordflow">do</span> {
286
- <a name="l00269"></a>00269 ret = stat(restartFile.c_str(), &amp;buf);
287
- <a name="l00270"></a>00270 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
288
- <a name="l00271"></a>00271 <span class="keywordflow">if</span> (ret == 0) {
289
- <a name="l00272"></a>00272 <span class="keywordflow">do</span> {
290
- <a name="l00273"></a>00273 ret = unlink(restartFile.c_str());
291
- <a name="l00274"></a>00274 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; (errno == EINTR || errno == EAGAIN));
292
- <a name="l00275"></a>00275 <span class="keywordflow">if</span> (ret == 0 || errno == ENOENT) {
293
- <a name="l00276"></a>00276 restartFileTimes.erase(appRoot);
294
- <a name="l00277"></a>00277 result = <span class="keyword">true</span>;
295
- <a name="l00278"></a>00278 } <span class="keywordflow">else</span> {
296
- <a name="l00279"></a>00279 map&lt;string, time_t&gt;::const_iterator it;
297
- <a name="l00280"></a>00280
298
- <a name="l00281"></a>00281 it = restartFileTimes.find(appRoot);
299
- <a name="l00282"></a>00282 <span class="keywordflow">if</span> (it == restartFileTimes.end()) {
300
- <a name="l00283"></a>00283 result = <span class="keyword">true</span>;
301
- <a name="l00284"></a>00284 } <span class="keywordflow">else</span> {
302
- <a name="l00285"></a>00285 result = buf.st_mtime != restartFileTimes[appRoot];
303
- <a name="l00286"></a>00286 }
304
- <a name="l00287"></a>00287 restartFileTimes[appRoot] = buf.st_mtime;
305
- <a name="l00288"></a>00288 }
306
- <a name="l00289"></a>00289 } <span class="keywordflow">else</span> {
307
- <a name="l00290"></a>00290 restartFileTimes.erase(appRoot);
308
- <a name="l00291"></a>00291 result = <span class="keyword">false</span>;
309
- <a name="l00292"></a>00292 }
310
- <a name="l00293"></a>00293 <span class="keywordflow">return</span> result;
311
- <a name="l00294"></a>00294 }
312
- <a name="l00295"></a>00295
313
- <a name="l00296"></a>00296 <span class="keywordtype">void</span> cleanerThreadMainLoop() {
314
- <a name="l00297"></a>00297 <a class="code" href="classboost_1_1this__thread_1_1disable__syscall__interruption.html" title="Create this struct on the stack to temporarily disable system call interruption,...">this_thread::disable_syscall_interruption</a> dsi;
315
- <a name="l00298"></a>00298 unique_lock&lt;mutex&gt; l(lock);
316
- <a name="l00299"></a>00299 <span class="keywordflow">try</span> {
317
- <a name="l00300"></a>00300 <span class="keywordflow">while</span> (!done &amp;&amp; !this_thread::interruption_requested()) {
318
- <a name="l00301"></a>00301 xtime xt;
319
- <a name="l00302"></a>00302 xtime_get(&amp;xt, TIME_UTC);
320
- <a name="l00303"></a>00303 xt.sec += maxIdleTime + 1;
321
- <a name="l00304"></a>00304 <span class="keywordflow">if</span> (cleanerThreadSleeper.timed_wait(l, xt)) {
322
- <a name="l00305"></a>00305 <span class="comment">// Condition was woken up.</span>
323
- <a name="l00306"></a>00306 <span class="keywordflow">if</span> (done) {
324
- <a name="l00307"></a>00307 <span class="comment">// StandardApplicationPool is being destroyed.</span>
325
- <a name="l00308"></a>00308 <span class="keywordflow">break</span>;
326
- <a name="l00309"></a>00309 } <span class="keywordflow">else</span> {
327
- <a name="l00310"></a>00310 <span class="comment">// maxIdleTime changed.</span>
328
- <a name="l00311"></a>00311 <span class="keywordflow">continue</span>;
329
- <a name="l00312"></a>00312 }
330
- <a name="l00313"></a>00313 }
331
- <a name="l00314"></a>00314
332
- <a name="l00315"></a>00315 time_t now = InterruptableCalls::time(NULL);
333
- <a name="l00316"></a>00316 AppContainerList::iterator it;
334
- <a name="l00317"></a>00317 <span class="keywordflow">for</span> (it = inactiveApps.begin(); it != inactiveApps.end(); it++) {
335
- <a name="l00318"></a>00318 AppContainer &amp;container(*it-&gt;get());
336
- <a name="l00319"></a>00319 <a class="code" href="namespacePassenger.html#6a15fd5e8765802a0b8b077e15297e18" title="Convenient alias for Application smart pointer.">ApplicationPtr</a> app(container.app);
337
- <a name="l00320"></a>00320 AppContainerListPtr appList(apps[app-&gt;getAppRoot()]);
338
- <a name="l00321"></a>00321
339
- <a name="l00322"></a>00322 <span class="keywordflow">if</span> (now - container.lastUsed &gt; (time_t) maxIdleTime) {
340
- <a name="l00323"></a>00323 P_DEBUG(<span class="stringliteral">"Cleaning idle app "</span> &lt;&lt; app-&gt;getAppRoot() &lt;&lt;
341
- <a name="l00324"></a>00324 <span class="stringliteral">" (PID "</span> &lt;&lt; app-&gt;getPid() &lt;&lt; <span class="stringliteral">")"</span>);
342
- <a name="l00325"></a>00325 appList-&gt;erase(container.iterator);
343
- <a name="l00326"></a>00326
344
- <a name="l00327"></a>00327 AppContainerList::iterator prev = it;
345
- <a name="l00328"></a>00328 prev--;
346
- <a name="l00329"></a>00329 inactiveApps.erase(it);
347
- <a name="l00330"></a>00330 it = prev;
348
- <a name="l00331"></a>00331
349
- <a name="l00332"></a>00332 appInstanceCount[app-&gt;getAppRoot()]--;
350
- <a name="l00333"></a>00333
351
- <a name="l00334"></a>00334 count--;
352
- <a name="l00335"></a>00335 }
353
- <a name="l00336"></a>00336 <span class="keywordflow">if</span> (appList-&gt;empty()) {
354
- <a name="l00337"></a>00337 apps.erase(app-&gt;getAppRoot());
355
- <a name="l00338"></a>00338 appInstanceCount.erase(app-&gt;getAppRoot());
356
- <a name="l00339"></a>00339 data-&gt;restartFileTimes.erase(app-&gt;getAppRoot());
357
- <a name="l00340"></a>00340 }
358
- <a name="l00341"></a>00341 }
359
- <a name="l00342"></a>00342 }
360
- <a name="l00343"></a>00343 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> exception &amp;e) {
361
- <a name="l00344"></a>00344 P_ERROR(<span class="stringliteral">"Uncaught exception: "</span> &lt;&lt; e.what());
362
- <a name="l00345"></a>00345 }
363
- <a name="l00346"></a>00346 }
364
- <a name="l00347"></a>00347 <span class="comment"></span>
365
- <a name="l00348"></a>00348 <span class="comment"> /**</span>
366
- <a name="l00349"></a>00349 <span class="comment"> * @throws boost::thread_interrupted</span>
367
- <a name="l00350"></a>00350 <span class="comment"> * @throws SpawnException</span>
368
- <a name="l00351"></a>00351 <span class="comment"> * @throws SystemException</span>
369
- <a name="l00352"></a>00352 <span class="comment"> */</span>
370
- <a name="l00353"></a>00353 pair&lt;AppContainerPtr, AppContainerList *&gt;
371
- <a name="l00354"></a>00354 spawnOrUseExisting(
372
- <a name="l00355"></a>00355 mutex::scoped_lock &amp;l,
373
- <a name="l00356"></a>00356 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot,
374
- <a name="l00357"></a>00357 <span class="keywordtype">bool</span> lowerPrivilege,
375
- <a name="l00358"></a>00358 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;lowestUser,
376
- <a name="l00359"></a>00359 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;environment,
377
- <a name="l00360"></a>00360 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;spawnMethod,
378
- <a name="l00361"></a>00361 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appType
379
- <a name="l00362"></a>00362 ) {
380
- <a name="l00363"></a>00363 this_thread::disable_interruption di;
381
- <a name="l00364"></a>00364 <a class="code" href="classboost_1_1this__thread_1_1disable__syscall__interruption.html" title="Create this struct on the stack to temporarily disable system call interruption,...">this_thread::disable_syscall_interruption</a> dsi;
382
- <a name="l00365"></a>00365 AppContainerPtr container;
383
- <a name="l00366"></a>00366 AppContainerList *list;
384
- <a name="l00367"></a>00367
385
- <a name="l00368"></a>00368 <span class="keywordflow">try</span> {
386
- <a name="l00369"></a>00369 ApplicationMap::iterator it(apps.find(appRoot));
387
- <a name="l00370"></a>00370
388
- <a name="l00371"></a>00371 <span class="keywordflow">if</span> (it != apps.end() &amp;&amp; needsRestart(appRoot)) {
389
- <a name="l00372"></a>00372 AppContainerList::iterator it2;
390
- <a name="l00373"></a>00373 list = it-&gt;second.get();
391
- <a name="l00374"></a>00374 <span class="keywordflow">for</span> (it2 = list-&gt;begin(); it2 != list-&gt;end(); it2++) {
392
- <a name="l00375"></a>00375 container = *it2;
393
- <a name="l00376"></a>00376 <span class="keywordflow">if</span> (container-&gt;sessions == 0) {
394
- <a name="l00377"></a>00377 inactiveApps.erase(container-&gt;ia_iterator);
395
- <a name="l00378"></a>00378 } <span class="keywordflow">else</span> {
396
- <a name="l00379"></a>00379 active--;
397
- <a name="l00380"></a>00380 }
398
- <a name="l00381"></a>00381 it2--;
399
- <a name="l00382"></a>00382 list-&gt;erase(container-&gt;iterator);
400
- <a name="l00383"></a>00383 count--;
401
- <a name="l00384"></a>00384 }
402
- <a name="l00385"></a>00385 apps.erase(appRoot);
403
- <a name="l00386"></a>00386 appInstanceCount.erase(appRoot);
404
- <a name="l00387"></a>00387 spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#2e85c43042b9556ca2fd74b8d28956ce" title="Remove the cached application instances at the given application root.">reload</a>(appRoot);
405
- <a name="l00388"></a>00388 it = apps.end();
406
- <a name="l00389"></a>00389 activeOrMaxChanged.notify_all();
407
- <a name="l00390"></a>00390 }
408
- <a name="l00391"></a>00391
409
- <a name="l00392"></a>00392 <span class="keywordflow">if</span> (it != apps.end()) {
410
- <a name="l00393"></a>00393 list = it-&gt;second.get();
411
- <a name="l00394"></a>00394
412
- <a name="l00395"></a>00395 <span class="keywordflow">if</span> (list-&gt;front()-&gt;sessions == 0) {
413
- <a name="l00396"></a>00396 container = list-&gt;front();
414
- <a name="l00397"></a>00397 list-&gt;pop_front();
415
- <a name="l00398"></a>00398 list-&gt;push_back(container);
416
- <a name="l00399"></a>00399 container-&gt;iterator = list-&gt;end();
417
- <a name="l00400"></a>00400 container-&gt;iterator--;
418
- <a name="l00401"></a>00401 inactiveApps.erase(container-&gt;ia_iterator);
419
- <a name="l00402"></a>00402 active++;
420
- <a name="l00403"></a>00403 activeOrMaxChanged.notify_all();
421
- <a name="l00404"></a>00404 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (count &gt;= max || (
422
- <a name="l00405"></a>00405 maxPerApp != 0 &amp;&amp; appInstanceCount[appRoot] &gt;= maxPerApp )
423
- <a name="l00406"></a>00406 ) {
424
- <a name="l00407"></a>00407 AppContainerList::iterator it(list-&gt;begin());
425
- <a name="l00408"></a>00408 AppContainerList::iterator smallest(list-&gt;begin());
426
- <a name="l00409"></a>00409 it++;
427
- <a name="l00410"></a>00410 <span class="keywordflow">for</span> (; it != list-&gt;end(); it++) {
428
- <a name="l00411"></a>00411 <span class="keywordflow">if</span> ((*it)-&gt;sessions &lt; (*smallest)-&gt;sessions) {
429
- <a name="l00412"></a>00412 smallest = it;
430
- <a name="l00413"></a>00413 }
431
- <a name="l00414"></a>00414 }
432
- <a name="l00415"></a>00415 container = *smallest;
433
- <a name="l00416"></a>00416 list-&gt;erase(smallest);
434
- <a name="l00417"></a>00417 list-&gt;push_back(container);
435
- <a name="l00418"></a>00418 container-&gt;iterator = list-&gt;end();
436
- <a name="l00419"></a>00419 container-&gt;iterator--;
437
- <a name="l00420"></a>00420 } <span class="keywordflow">else</span> {
438
- <a name="l00421"></a>00421 container = <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AppContainer());
439
- <a name="l00422"></a>00422 {
440
- <a name="l00423"></a>00423 this_thread::restore_interruption ri(di);
441
- <a name="l00424"></a>00424 <a class="code" href="classboost_1_1this__thread_1_1restore__syscall__interruption.html" title="Creating an object of this class on the stack will restore the system call interruption...">this_thread::restore_syscall_interruption</a> rsi(dsi);
442
- <a name="l00425"></a>00425 container-&gt;app = spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#1bafa97204ea49a88b66272be3377d53" title="Spawn a new instance of a Ruby on Rails or Rack application.">spawn</a>(appRoot,
443
- <a name="l00426"></a>00426 lowerPrivilege, lowestUser, environment,
444
- <a name="l00427"></a>00427 spawnMethod, appType);
445
- <a name="l00428"></a>00428 }
446
- <a name="l00429"></a>00429 container-&gt;sessions = 0;
447
- <a name="l00430"></a>00430 list-&gt;push_back(container);
448
- <a name="l00431"></a>00431 container-&gt;iterator = list-&gt;end();
449
- <a name="l00432"></a>00432 container-&gt;iterator--;
450
- <a name="l00433"></a>00433 appInstanceCount[appRoot]++;
451
- <a name="l00434"></a>00434 count++;
452
- <a name="l00435"></a>00435 active++;
453
- <a name="l00436"></a>00436 activeOrMaxChanged.notify_all();
454
- <a name="l00437"></a>00437 }
455
- <a name="l00438"></a>00438 } <span class="keywordflow">else</span> {
456
- <a name="l00439"></a>00439 <span class="keywordflow">while</span> (!(
457
- <a name="l00440"></a>00440 active &lt; max &amp;&amp;
458
- <a name="l00441"></a>00441 (maxPerApp == 0 || appInstanceCount[appRoot] &lt; maxPerApp)
459
- <a name="l00442"></a>00442 )) {
460
- <a name="l00443"></a>00443 activeOrMaxChanged.wait(l);
461
- <a name="l00444"></a>00444 }
462
- <a name="l00445"></a>00445 <span class="keywordflow">if</span> (count == max) {
463
- <a name="l00446"></a>00446 container = inactiveApps.front();
464
- <a name="l00447"></a>00447 inactiveApps.pop_front();
465
- <a name="l00448"></a>00448 list = apps[container-&gt;app-&gt;getAppRoot()].get();
466
- <a name="l00449"></a>00449 list-&gt;erase(container-&gt;iterator);
467
- <a name="l00450"></a>00450 <span class="keywordflow">if</span> (list-&gt;empty()) {
468
- <a name="l00451"></a>00451 apps.erase(container-&gt;app-&gt;getAppRoot());
469
- <a name="l00452"></a>00452 restartFileTimes.erase(container-&gt;app-&gt;getAppRoot());
470
- <a name="l00453"></a>00453 appInstanceCount.erase(container-&gt;app-&gt;getAppRoot());
471
- <a name="l00454"></a>00454 } <span class="keywordflow">else</span> {
472
- <a name="l00455"></a>00455 appInstanceCount[container-&gt;app-&gt;getAppRoot()]--;
473
- <a name="l00456"></a>00456 }
474
- <a name="l00457"></a>00457 count--;
475
- <a name="l00458"></a>00458 }
476
- <a name="l00459"></a>00459 container = <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AppContainer());
477
- <a name="l00460"></a>00460 {
478
- <a name="l00461"></a>00461 this_thread::restore_interruption ri(di);
479
- <a name="l00462"></a>00462 <a class="code" href="classboost_1_1this__thread_1_1restore__syscall__interruption.html" title="Creating an object of this class on the stack will restore the system call interruption...">this_thread::restore_syscall_interruption</a> rsi(dsi);
480
- <a name="l00463"></a>00463 container-&gt;app = spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#1bafa97204ea49a88b66272be3377d53" title="Spawn a new instance of a Ruby on Rails or Rack application.">spawn</a>(appRoot, lowerPrivilege, lowestUser,
481
- <a name="l00464"></a>00464 environment, spawnMethod, appType);
482
- <a name="l00465"></a>00465 }
483
- <a name="l00466"></a>00466 container-&gt;sessions = 0;
484
- <a name="l00467"></a>00467 it = apps.find(appRoot);
485
- <a name="l00468"></a>00468 <span class="keywordflow">if</span> (it == apps.end()) {
486
- <a name="l00469"></a>00469 list = <span class="keyword">new</span> AppContainerList();
487
- <a name="l00470"></a>00470 apps[appRoot] = <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(list);
488
- <a name="l00471"></a>00471 appInstanceCount[appRoot] = 1;
489
- <a name="l00472"></a>00472 } <span class="keywordflow">else</span> {
490
- <a name="l00473"></a>00473 list = it-&gt;second.get();
491
- <a name="l00474"></a>00474 appInstanceCount[appRoot]++;
492
- <a name="l00475"></a>00475 }
493
- <a name="l00476"></a>00476 list-&gt;push_back(container);
494
- <a name="l00477"></a>00477 container-&gt;iterator = list-&gt;end();
495
- <a name="l00478"></a>00478 container-&gt;iterator--;
496
- <a name="l00479"></a>00479 count++;
497
- <a name="l00480"></a>00480 active++;
498
- <a name="l00481"></a>00481 activeOrMaxChanged.notify_all();
499
- <a name="l00482"></a>00482 }
500
- <a name="l00483"></a>00483 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a class="code" href="classPassenger_1_1SpawnException.html" title="Thrown when SpawnManager or ApplicationPool fails to spawn an application instance...">SpawnException</a> &amp;e) {
501
- <a name="l00484"></a>00484 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot spawn application '"</span>);
502
- <a name="l00485"></a>00485 message.append(appRoot);
503
- <a name="l00486"></a>00486 message.append(<span class="stringliteral">"': "</span>);
504
- <a name="l00487"></a>00487 message.append(e.<a class="code" href="classPassenger_1_1SpawnException.html#d2da180f89a43423a4b37248249972ff">what</a>());
505
- <a name="l00488"></a>00488 <span class="keywordflow">if</span> (e.<a class="code" href="classPassenger_1_1SpawnException.html#e65dc272e183fd9e5637a4091cc6bbf4" title="Check whether an error page is available.">hasErrorPage</a>()) {
506
- <a name="l00489"></a>00489 <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>(message, e.<a class="code" href="classPassenger_1_1SpawnException.html#6f675a37edd7070875d0744e7dd010a1" title="Return the error page content.">getErrorPage</a>());
507
- <a name="l00490"></a>00490 } <span class="keywordflow">else</span> {
508
- <a name="l00491"></a>00491 <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>(message);
509
- <a name="l00492"></a>00492 }
510
- <a name="l00493"></a>00493 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> exception &amp;e) {
511
- <a name="l00494"></a>00494 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot spawn application '"</span>);
512
- <a name="l00495"></a>00495 message.append(appRoot);
513
- <a name="l00496"></a>00496 message.append(<span class="stringliteral">"': "</span>);
514
- <a name="l00497"></a>00497 message.append(e.what());
515
- <a name="l00498"></a>00498 <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>(message);
516
- <a name="l00499"></a>00499 }
517
- <a name="l00500"></a>00500
518
- <a name="l00501"></a>00501 <span class="keywordflow">return</span> make_pair(container, list);
519
- <a name="l00502"></a>00502 }
520
- <a name="l00503"></a>00503
521
- <a name="l00504"></a>00504 <span class="keyword">public</span>:<span class="comment"></span>
522
- <a name="l00505"></a>00505 <span class="comment"> /**</span>
523
- <a name="l00506"></a>00506 <span class="comment"> * Create a new StandardApplicationPool object.</span>
524
- <a name="l00507"></a>00507 <span class="comment"> *</span>
525
- <a name="l00508"></a>00508 <span class="comment"> * @param spawnServerCommand The filename of the spawn server to use.</span>
526
- <a name="l00509"></a>00509 <span class="comment"> * @param logFile Specify a log file that the spawn server should use.</span>
527
- <a name="l00510"></a>00510 <span class="comment"> * Messages on its standard output and standard error channels</span>
528
- <a name="l00511"></a>00511 <span class="comment"> * will be written to this log file. If an empty string is</span>
529
- <a name="l00512"></a>00512 <span class="comment"> * specified, no log file will be used, and the spawn server</span>
530
- <a name="l00513"></a>00513 <span class="comment"> * will use the same standard output/error channels as the</span>
531
- <a name="l00514"></a>00514 <span class="comment"> * current process.</span>
532
- <a name="l00515"></a>00515 <span class="comment"> * @param rubyCommand The Ruby interpreter's command.</span>
533
- <a name="l00516"></a>00516 <span class="comment"> * @param user The user that the spawn manager should run as. This</span>
534
- <a name="l00517"></a>00517 <span class="comment"> * parameter only has effect if the current process is</span>
535
- <a name="l00518"></a>00518 <span class="comment"> * running as root. If the empty string is given, or if</span>
536
- <a name="l00519"></a>00519 <span class="comment"> * the &lt;tt&gt;user&lt;/tt&gt; is not a valid username, then</span>
537
- <a name="l00520"></a>00520 <span class="comment"> * the spawn manager will be run as the current user.</span>
538
- <a name="l00521"></a>00521 <span class="comment"> * @param rubyCommand The Ruby interpreter's command.</span>
539
- <a name="l00522"></a>00522 <span class="comment"> * @throws SystemException An error occured while trying to setup the spawn server.</span>
540
- <a name="l00523"></a>00523 <span class="comment"> * @throws IOException The specified log file could not be opened.</span>
541
- <a name="l00524"></a>00524 <span class="comment"> */</span>
542
- <a name="l00525"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#f175704fc477f37ba1d387be09fa2e6b">00525</a> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#f175704fc477f37ba1d387be09fa2e6b" title="Create a new StandardApplicationPool object.">StandardApplicationPool</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;spawnServerCommand,
543
- <a name="l00526"></a>00526 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;logFile = <span class="stringliteral">""</span>,
544
- <a name="l00527"></a>00527 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;rubyCommand = <span class="stringliteral">"ruby"</span>,
545
- <a name="l00528"></a>00528 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;user = <span class="stringliteral">""</span>)
546
- <a name="l00529"></a>00529 :
547
- <a name="l00530"></a>00530 #ifndef PASSENGER_USE_DUMMY_SPAWN_MANAGER
548
- <a name="l00531"></a>00531 spawnManager(spawnServerCommand, logFile, rubyCommand, user),
549
- <a name="l00532"></a>00532 #endif
550
- <a name="l00533"></a>00533 data(new SharedData()),
551
- <a name="l00534"></a>00534 lock(data-&gt;lock),
552
- <a name="l00535"></a>00535 activeOrMaxChanged(data-&gt;activeOrMaxChanged),
553
- <a name="l00536"></a>00536 apps(data-&gt;apps),
554
- <a name="l00537"></a>00537 max(data-&gt;max),
555
- <a name="l00538"></a>00538 count(data-&gt;count),
556
- <a name="l00539"></a>00539 active(data-&gt;active),
557
- <a name="l00540"></a>00540 maxPerApp(data-&gt;maxPerApp),
558
- <a name="l00541"></a>00541 inactiveApps(data-&gt;inactiveApps),
559
- <a name="l00542"></a>00542 restartFileTimes(data-&gt;restartFileTimes),
560
- <a name="l00543"></a>00543 appInstanceCount(data-&gt;appInstanceCount)
561
- <a name="l00544"></a>00544 {
562
- <a name="l00545"></a>00545 detached = <span class="keyword">false</span>;
563
- <a name="l00546"></a>00546 done = <span class="keyword">false</span>;
564
- <a name="l00547"></a>00547 max = DEFAULT_MAX_POOL_SIZE;
565
- <a name="l00548"></a>00548 count = 0;
566
- <a name="l00549"></a>00549 active = 0;
567
- <a name="l00550"></a>00550 maxPerApp = DEFAULT_MAX_INSTANCES_PER_APP;
568
- <a name="l00551"></a>00551 maxIdleTime = DEFAULT_MAX_IDLE_TIME;
569
- <a name="l00552"></a>00552 cleanerThread = <span class="keyword">new</span> thread(
570
- <a name="l00553"></a>00553 bind(&amp;StandardApplicationPool::cleanerThreadMainLoop, <span class="keyword">this</span>),
571
- <a name="l00554"></a>00554 CLEANER_THREAD_STACK_SIZE
572
- <a name="l00555"></a>00555 );
573
- <a name="l00556"></a>00556 }
574
- <a name="l00557"></a>00557
575
- <a name="l00558"></a>00558 <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1StandardApplicationPool.html" title="A standard implementation of ApplicationPool for single-process environments.">StandardApplicationPool</a>() {
576
- <a name="l00559"></a>00559 <span class="keywordflow">if</span> (!detached) {
577
- <a name="l00560"></a>00560 this_thread::disable_interruption di;
578
- <a name="l00561"></a>00561 {
579
- <a name="l00562"></a>00562 mutex::scoped_lock l(lock);
580
- <a name="l00563"></a>00563 done = <span class="keyword">true</span>;
581
- <a name="l00564"></a>00564 cleanerThreadSleeper.notify_one();
582
- <a name="l00565"></a>00565 }
583
- <a name="l00566"></a>00566 cleanerThread-&gt;join();
584
- <a name="l00567"></a>00567 }
585
- <a name="l00568"></a>00568 <span class="keyword">delete</span> cleanerThread;
586
- <a name="l00569"></a>00569 }
587
- <a name="l00570"></a>00570
588
- <a name="l00571"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#0dcdd88c39d7f1a1d667e24c3cb9b243">00571</a> <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>(
589
- <a name="l00572"></a>00572 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot,
590
- <a name="l00573"></a>00573 <span class="keywordtype">bool</span> lowerPrivilege = <span class="keyword">true</span>,
591
- <a name="l00574"></a>00574 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;lowestUser = <span class="stringliteral">"nobody"</span>,
592
- <a name="l00575"></a>00575 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;environment = <span class="stringliteral">"production"</span>,
593
- <a name="l00576"></a>00576 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;spawnMethod = <span class="stringliteral">"smart"</span>,
594
- <a name="l00577"></a>00577 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appType = <span class="stringliteral">"rails"</span>
595
- <a name="l00578"></a>00578 ) {
596
- <a name="l00579"></a>00579 <span class="keyword">using namespace </span>boost::posix_time;
597
- <a name="l00580"></a>00580 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> attempt = 0;
598
- <a name="l00581"></a>00581 ptime timeLimit(get_system_time() + millisec(GET_TIMEOUT));
599
- <a name="l00582"></a>00582 unique_lock&lt;mutex&gt; l(lock);
600
- <a name="l00583"></a>00583
601
- <a name="l00584"></a>00584 <span class="keywordflow">while</span> (<span class="keyword">true</span>) {
602
- <a name="l00585"></a>00585 attempt++;
603
- <a name="l00586"></a>00586
604
- <a name="l00587"></a>00587 pair&lt;AppContainerPtr, AppContainerList *&gt; p(
605
- <a name="l00588"></a>00588 spawnOrUseExisting(l, appRoot, lowerPrivilege, lowestUser,
606
- <a name="l00589"></a>00589 environment, spawnMethod, appType)
607
- <a name="l00590"></a>00590 );
608
- <a name="l00591"></a>00591 AppContainerPtr &amp;container(p.first);
609
- <a name="l00592"></a>00592 AppContainerList &amp;list(*p.second);
610
- <a name="l00593"></a>00593
611
- <a name="l00594"></a>00594 container-&gt;lastUsed = time(NULL);
612
- <a name="l00595"></a>00595 container-&gt;sessions++;
613
- <a name="l00596"></a>00596
614
- <a name="l00597"></a>00597 P_ASSERT(verifyState(), <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a>(),
615
- <a name="l00598"></a>00598 <span class="stringliteral">"State is valid:\n"</span> &lt;&lt; <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(<span class="keyword">false</span>));
616
- <a name="l00599"></a>00599 <span class="keywordflow">try</span> {
617
- <a name="l00600"></a>00600 <span class="keywordflow">return</span> container-&gt;app-&gt;connect(SessionCloseCallback(data, container));
618
- <a name="l00601"></a>00601 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> exception &amp;e) {
619
- <a name="l00602"></a>00602 container-&gt;sessions--;
620
- <a name="l00603"></a>00603 <span class="keywordflow">if</span> (attempt == MAX_GET_ATTEMPTS) {
621
- <a name="l00604"></a>00604 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot connect to an existing "</span>
622
- <a name="l00605"></a>00605 <span class="stringliteral">"application instance for '"</span>);
623
- <a name="l00606"></a>00606 message.append(appRoot);
624
- <a name="l00607"></a>00607 message.append(<span class="stringliteral">"': "</span>);
625
- <a name="l00608"></a>00608 <span class="keywordflow">try</span> {
626
- <a name="l00609"></a>00609 <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;syse =
627
- <a name="l00610"></a>00610 <span class="keyword">dynamic_cast&lt;</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;<span class="keyword">&gt;</span>(e);
628
- <a name="l00611"></a>00611 message.append(syse.<a class="code" href="classPassenger_1_1SystemException.html#0ef41d755fea2c9b1db2252e7c418dc8" title="Returns the system&amp;#39;s error message.">sys</a>());
629
- <a name="l00612"></a>00612 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> bad_cast &amp;) {
630
- <a name="l00613"></a>00613 message.append(e.what());
631
- <a name="l00614"></a>00614 }
632
- <a name="l00615"></a>00615 <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);
633
- <a name="l00616"></a>00616 } <span class="keywordflow">else</span> {
634
- <a name="l00617"></a>00617 list.erase(container-&gt;iterator);
635
- <a name="l00618"></a>00618 <span class="keywordflow">if</span> (list.empty()) {
636
- <a name="l00619"></a>00619 apps.erase(appRoot);
637
- <a name="l00620"></a>00620 appInstanceCount.erase(appRoot);
638
- <a name="l00621"></a>00621 }
639
- <a name="l00622"></a>00622 count--;
640
- <a name="l00623"></a>00623 active--;
641
- <a name="l00624"></a>00624 activeOrMaxChanged.notify_all();
642
- <a name="l00625"></a>00625 P_ASSERT(verifyState(), <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a>(),
643
- <a name="l00626"></a>00626 <span class="stringliteral">"State is valid."</span>);
644
- <a name="l00627"></a>00627 }
645
- <a name="l00628"></a>00628 }
646
- <a name="l00629"></a>00629 }
647
- <a name="l00630"></a>00630 <span class="comment">// Never reached; shut up compiler warning</span>
648
- <a name="l00631"></a>00631 <span class="keywordflow">return</span> <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a>();
649
- <a name="l00632"></a>00632 }
650
- <a name="l00633"></a>00633
651
- <a name="l00634"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#bcf8faeb4f431ae07ea0e20270661d08">00634</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#bcf8faeb4f431ae07ea0e20270661d08" title="Clear all application instances that are currently in the pool.">clear</a>() {
652
- <a name="l00635"></a>00635 mutex::scoped_lock l(lock);
653
- <a name="l00636"></a>00636 apps.clear();
654
- <a name="l00637"></a>00637 inactiveApps.clear();
655
- <a name="l00638"></a>00638 restartFileTimes.clear();
656
- <a name="l00639"></a>00639 appInstanceCount.clear();
657
- <a name="l00640"></a>00640 count = 0;
658
- <a name="l00641"></a>00641 active = 0;
659
- <a name="l00642"></a>00642 }
660
- <a name="l00643"></a>00643
661
- <a name="l00644"></a>00644 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMaxIdleTime(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> seconds) {
662
- <a name="l00645"></a>00645 mutex::scoped_lock l(lock);
663
- <a name="l00646"></a>00646 maxIdleTime = seconds;
664
- <a name="l00647"></a>00647 cleanerThreadSleeper.notify_one();
665
- <a name="l00648"></a>00648 }
666
- <a name="l00649"></a>00649
667
- <a name="l00650"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#04ef8c92da189520ad2022f4f82e9553">00650</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#04ef8c92da189520ad2022f4f82e9553" title="Set a hard limit on the number of application instances that this ApplicationPool...">setMax</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> max) {
668
- <a name="l00651"></a>00651 mutex::scoped_lock l(lock);
669
- <a name="l00652"></a>00652 this-&gt;max = max;
670
- <a name="l00653"></a>00653 activeOrMaxChanged.notify_all();
671
- <a name="l00654"></a>00654 }
672
- <a name="l00655"></a>00655
673
- <a name="l00656"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#7773c4a3dfbd88eac72401d063831788">00656</a> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#7773c4a3dfbd88eac72401d063831788" title="Get the number of active applications in the pool.">getActive</a>()<span class="keyword"> const </span>{
674
- <a name="l00657"></a>00657 <span class="keywordflow">return</span> active;
675
- <a name="l00658"></a>00658 }
676
- <a name="l00659"></a>00659
677
- <a name="l00660"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#cdbfe2b9ffacdab4438c879c2411bf02">00660</a> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#cdbfe2b9ffacdab4438c879c2411bf02" title="Get the number of active applications in the pool.">getCount</a>()<span class="keyword"> const </span>{
678
- <a name="l00661"></a>00661 <span class="keywordflow">return</span> count;
679
- <a name="l00662"></a>00662 }
680
- <a name="l00663"></a>00663
681
- <a name="l00664"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#3bafcda8d880f70561ad8a9da16e26ef">00664</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#3bafcda8d880f70561ad8a9da16e26ef" title="Set a hard limit on the number of application instances that a single application...">setMaxPerApp</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> maxPerApp) {
682
- <a name="l00665"></a>00665 mutex::scoped_lock l(lock);
683
- <a name="l00666"></a>00666 this-&gt;maxPerApp = maxPerApp;
684
- <a name="l00667"></a>00667 activeOrMaxChanged.notify_all();
685
- <a name="l00668"></a>00668 }
686
- <a name="l00669"></a>00669
687
- <a name="l00670"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#6955152d237920988d20297d2fff5660">00670</a> <span class="keyword">virtual</span> pid_t <a class="code" href="classPassenger_1_1StandardApplicationPool.html#6955152d237920988d20297d2fff5660" title="Get the process ID of the spawn server that is used.">getSpawnServerPid</a>()<span class="keyword"> const </span>{
688
- <a name="l00671"></a>00671 <span class="keywordflow">return</span> spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#1f77e2e7e6cb464028c13a29f983ad8e" title="Get the Process ID of the spawn server.">getServerPid</a>();
689
- <a name="l00672"></a>00672 }
690
- <a name="l00673"></a>00673 <span class="comment"></span>
691
- <a name="l00674"></a>00674 <span class="comment"> /**</span>
692
- <a name="l00675"></a>00675 <span class="comment"> * Returns a textual description of the internal state of</span>
693
- <a name="l00676"></a>00676 <span class="comment"> * the application pool.</span>
694
- <a name="l00677"></a>00677 <span class="comment"> */</span>
695
- <a name="l00678"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#22b4149ca8256c3042fc342e681b0383">00678</a> <span class="keyword">virtual</span> <span class="keywordtype">string</span> <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(<span class="keywordtype">bool</span> lockMutex = <span class="keyword">true</span>)<span class="keyword"> const </span>{
696
- <a name="l00679"></a>00679 <span class="keywordflow">if</span> (lockMutex) {
697
- <a name="l00680"></a>00680 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(boost::adopt_lock);
698
- <a name="l00681"></a>00681 } <span class="keywordflow">else</span> {
699
- <a name="l00682"></a>00682 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#gf6fab368d70c18fdf16bf5a24f630407" title="Convert anything to a string.">toString</a>(boost::defer_lock);
700
- <a name="l00683"></a>00683 }
701
- <a name="l00684"></a>00684 }
702
- <a name="l00685"></a>00685 };
703
- <a name="l00686"></a>00686
704
- <a name="l00687"></a>00687 } <span class="comment">// namespace Passenger</span>
705
- <a name="l00688"></a>00688
706
- <a name="l00689"></a>00689 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_STANDARD_APPLICATION_POOL_H_ */</span>
707
- <a name="l00690"></a>00690
708
- </pre></div></div>
709
- <hr size="1"><address style="text-align: right;"><small>Generated on Tue Jun 24 14:03:42 2008 for Passenger by&nbsp;
710
- <a href="http://www.doxygen.org/index.html">
711
- <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
712
- </body>
713
- </html>