passenger 2.1.2 → 2.1.3

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

Potentially problematic release.


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

Files changed (244) hide show
  1. data/Rakefile +7 -5
  2. data/doc/Architectural overview.html +729 -1
  3. data/doc/Architectural overview.txt +0 -5
  4. data/doc/Security of user switching support.html +605 -1
  5. data/doc/Users guide.html +110 -106
  6. data/doc/Users guide.txt +49 -0
  7. data/doc/cxxapi/ApplicationPoolServer_8h-source.html +400 -372
  8. data/doc/cxxapi/ApplicationPool_8h-source.html +1 -1
  9. data/doc/cxxapi/Application_8h-source.html +1 -1
  10. data/doc/cxxapi/Bucket_8h-source.html +1 -1
  11. data/doc/cxxapi/CachedFileStat_8h-source.html +56 -65
  12. data/doc/cxxapi/Configuration_8h-source.html +40 -32
  13. data/doc/cxxapi/DirectoryMapper_8h-source.html +1 -1
  14. data/doc/cxxapi/DummySpawnManager_8h-source.html +1 -1
  15. data/doc/cxxapi/Exceptions_8h-source.html +1 -1
  16. data/doc/cxxapi/FileChecker_8h-source.html +29 -30
  17. data/doc/cxxapi/Hooks_8h-source.html +1 -1
  18. data/doc/cxxapi/Logging_8h-source.html +1 -1
  19. data/doc/cxxapi/MessageChannel_8h-source.html +1 -1
  20. data/doc/cxxapi/PoolOptions_8h-source.html +1 -1
  21. data/doc/cxxapi/SpawnManager_8h-source.html +225 -219
  22. data/doc/cxxapi/StandardApplicationPool_8h-source.html +451 -445
  23. data/doc/cxxapi/SystemTime_8h-source.html +1 -1
  24. data/doc/cxxapi/Utils_8h-source.html +201 -140
  25. data/doc/cxxapi/annotated.html +2 -2
  26. data/doc/cxxapi/classClient-members.html +1 -1
  27. data/doc/cxxapi/classClient.html +1 -1
  28. data/doc/cxxapi/classHooks-members.html +1 -1
  29. data/doc/cxxapi/classHooks.html +1 -1
  30. data/doc/cxxapi/classPassenger_1_1Application-members.html +1 -1
  31. data/doc/cxxapi/classPassenger_1_1Application.html +1 -1
  32. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +1 -1
  33. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +1 -1
  34. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -1
  35. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +1 -1
  36. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
  37. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +1 -1
  38. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +1 -1
  39. data/doc/cxxapi/{classPassenger_1_1TempFile-members.html → classPassenger_1_1BufferedUpload-members.html} +5 -5
  40. data/doc/cxxapi/{classPassenger_1_1TempFile.html → classPassenger_1_1BufferedUpload.html} +33 -43
  41. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +1 -1
  42. data/doc/cxxapi/classPassenger_1_1BusyException.html +1 -1
  43. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +1 -1
  44. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +1 -1
  45. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +1 -1
  46. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +1 -1
  47. data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -1
  48. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +1 -1
  49. data/doc/cxxapi/classPassenger_1_1FileChecker-members.html +1 -1
  50. data/doc/cxxapi/classPassenger_1_1FileChecker.html +2 -2
  51. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -1
  52. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +1 -1
  53. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  54. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +1 -1
  55. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +1 -1
  56. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  57. data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -1
  58. data/doc/cxxapi/classPassenger_1_1IOException.html +1 -1
  59. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  60. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +1 -1
  61. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +1 -1
  62. data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +1 -1
  63. data/doc/cxxapi/classPassenger_1_1RuntimeException.html +1 -1
  64. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -1
  65. data/doc/cxxapi/classPassenger_1_1SpawnException.html +1 -1
  66. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +1 -1
  67. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +1 -1
  68. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +1 -1
  69. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +1 -1
  70. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
  71. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +1 -1
  72. data/doc/cxxapi/classPassenger_1_1SystemException.html +1 -1
  73. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  74. data/doc/cxxapi/classPassenger_1_1SystemTime-members.html +1 -1
  75. data/doc/cxxapi/classPassenger_1_1SystemTime.html +1 -1
  76. data/doc/cxxapi/definitions_8h-source.html +1 -1
  77. data/doc/cxxapi/files.html +1 -1
  78. data/doc/cxxapi/functions.html +12 -11
  79. data/doc/cxxapi/functions_func.html +9 -7
  80. data/doc/cxxapi/functions_type.html +1 -1
  81. data/doc/cxxapi/functions_vars.html +2 -4
  82. data/doc/cxxapi/graph_legend.html +1 -1
  83. data/doc/cxxapi/graph_legend.png +0 -0
  84. data/doc/cxxapi/group__Configuration.html +3 -3
  85. data/doc/cxxapi/group__Configuration.png +0 -0
  86. data/doc/cxxapi/group__Core.html +1 -1
  87. data/doc/cxxapi/group__Core.png +0 -0
  88. data/doc/cxxapi/group__Exceptions.html +1 -1
  89. data/doc/cxxapi/group__Hooks.html +1 -1
  90. data/doc/cxxapi/group__Hooks.png +0 -0
  91. data/doc/cxxapi/group__Support.html +33 -16
  92. data/doc/cxxapi/hierarchy.html +2 -2
  93. data/doc/cxxapi/inherit__graph__0.png +0 -0
  94. data/doc/cxxapi/inherit__graph__1.png +0 -0
  95. data/doc/cxxapi/inherit__graph__10.map +1 -1
  96. data/doc/cxxapi/inherit__graph__10.md5 +1 -1
  97. data/doc/cxxapi/inherit__graph__10.png +0 -0
  98. data/doc/cxxapi/inherit__graph__11.map +1 -1
  99. data/doc/cxxapi/inherit__graph__11.md5 +1 -1
  100. data/doc/cxxapi/inherit__graph__11.png +0 -0
  101. data/doc/cxxapi/inherit__graph__12.map +1 -2
  102. data/doc/cxxapi/inherit__graph__12.md5 +1 -1
  103. data/doc/cxxapi/inherit__graph__12.png +0 -0
  104. data/doc/cxxapi/inherit__graph__13.map +2 -1
  105. data/doc/cxxapi/inherit__graph__13.md5 +1 -1
  106. data/doc/cxxapi/inherit__graph__13.png +0 -0
  107. data/doc/cxxapi/inherit__graph__14.map +1 -1
  108. data/doc/cxxapi/inherit__graph__14.md5 +1 -1
  109. data/doc/cxxapi/inherit__graph__14.png +0 -0
  110. data/doc/cxxapi/inherit__graph__15.map +1 -1
  111. data/doc/cxxapi/inherit__graph__15.md5 +1 -1
  112. data/doc/cxxapi/inherit__graph__15.png +0 -0
  113. data/doc/cxxapi/inherit__graph__16.map +1 -1
  114. data/doc/cxxapi/inherit__graph__16.md5 +1 -1
  115. data/doc/cxxapi/inherit__graph__16.png +0 -0
  116. data/doc/cxxapi/inherit__graph__17.map +1 -1
  117. data/doc/cxxapi/inherit__graph__17.md5 +1 -1
  118. data/doc/cxxapi/inherit__graph__17.png +0 -0
  119. data/doc/cxxapi/inherit__graph__18.map +1 -1
  120. data/doc/cxxapi/inherit__graph__18.md5 +1 -1
  121. data/doc/cxxapi/inherit__graph__18.png +0 -0
  122. data/doc/cxxapi/inherit__graph__19.map +1 -2
  123. data/doc/cxxapi/inherit__graph__19.md5 +1 -1
  124. data/doc/cxxapi/inherit__graph__19.png +0 -0
  125. data/doc/cxxapi/inherit__graph__2.png +0 -0
  126. data/doc/cxxapi/inherit__graph__20.map +2 -1
  127. data/doc/cxxapi/inherit__graph__20.md5 +1 -1
  128. data/doc/cxxapi/inherit__graph__20.png +0 -0
  129. data/doc/cxxapi/inherit__graph__21.map +1 -1
  130. data/doc/cxxapi/inherit__graph__21.md5 +1 -1
  131. data/doc/cxxapi/inherit__graph__21.png +0 -0
  132. data/doc/cxxapi/inherit__graph__3.png +0 -0
  133. data/doc/cxxapi/inherit__graph__4.png +0 -0
  134. data/doc/cxxapi/inherit__graph__5.png +0 -0
  135. data/doc/cxxapi/inherit__graph__6.png +0 -0
  136. data/doc/cxxapi/inherit__graph__7.map +1 -1
  137. data/doc/cxxapi/inherit__graph__7.md5 +1 -1
  138. data/doc/cxxapi/inherit__graph__7.png +0 -0
  139. data/doc/cxxapi/inherit__graph__8.map +1 -1
  140. data/doc/cxxapi/inherit__graph__8.md5 +1 -1
  141. data/doc/cxxapi/inherit__graph__8.png +0 -0
  142. data/doc/cxxapi/inherit__graph__9.map +1 -1
  143. data/doc/cxxapi/inherit__graph__9.md5 +1 -1
  144. data/doc/cxxapi/inherit__graph__9.png +0 -0
  145. data/doc/cxxapi/inherits.html +18 -18
  146. data/doc/cxxapi/main.html +1 -1
  147. data/doc/cxxapi/modules.html +1 -1
  148. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -1
  149. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +1 -1
  150. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -1
  151. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +1 -1
  152. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +1 -1
  153. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +1 -1
  154. data/doc/cxxapi/tree.html +4 -4
  155. data/doc/rdoc/classes/ConditionVariable.html +58 -58
  156. data/doc/rdoc/classes/Exception.html +11 -11
  157. data/doc/rdoc/classes/GC.html +4 -4
  158. data/doc/rdoc/classes/IO.html +14 -14
  159. data/doc/rdoc/classes/PhusionPassenger.html +11 -11
  160. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +1 -1
  161. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +40 -39
  162. data/doc/rdoc/classes/PhusionPassenger/Application.html +14 -14
  163. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +12 -12
  164. data/doc/rdoc/classes/PhusionPassenger/Railz.html +1 -1
  165. data/doc/rdoc/classes/PhusionPassenger/Utils.html +15 -8
  166. data/doc/rdoc/classes/PlatformInfo.html +257 -253
  167. data/doc/rdoc/classes/RakeExtensions.html +2 -2
  168. data/doc/rdoc/classes/Signal.html +26 -26
  169. data/doc/rdoc/created.rid +1 -1
  170. data/doc/rdoc/files/DEVELOPERS_TXT.html +1 -1
  171. data/doc/rdoc/files/README.html +1 -1
  172. data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +1 -1
  173. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +1 -1
  174. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +1 -1
  175. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +1 -1
  176. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +1 -1
  177. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +1 -1
  178. data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +1 -1
  179. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +1 -1
  180. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +1 -1
  181. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +1 -1
  182. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +1 -1
  183. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +1 -1
  184. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +1 -1
  185. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +1 -1
  186. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +1 -1
  187. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +1 -1
  188. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +1 -1
  189. data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +1 -1
  190. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +1 -1
  191. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +1 -1
  192. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +1 -1
  193. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +1 -1
  194. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +1 -1
  195. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +9 -9
  196. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +1 -1
  197. data/doc/rdoc/files/{lib → misc}/rake/extensions_rb.html +2 -2
  198. data/doc/rdoc/fr_file_index.html +1 -1
  199. data/doc/rdoc/fr_method_index.html +22 -22
  200. data/ext/apache2/ApplicationPoolServer.h +43 -15
  201. data/ext/apache2/ApplicationPoolServerExecutable.cpp +27 -52
  202. data/ext/apache2/CachedFileStat.h +7 -16
  203. data/ext/apache2/Configuration.h +9 -1
  204. data/ext/apache2/FileChecker.h +4 -5
  205. data/ext/apache2/Hooks.cpp +20 -22
  206. data/ext/apache2/SpawnManager.h +6 -0
  207. data/ext/apache2/StandardApplicationPool.h +6 -0
  208. data/ext/apache2/Utils.cpp +174 -16
  209. data/ext/apache2/Utils.h +99 -38
  210. data/ext/boost/cstdint.hpp +2 -1
  211. data/ext/oxt/system_calls.cpp +20 -2
  212. data/ext/oxt/system_calls.hpp +2 -0
  213. data/lib/phusion_passenger/abstract_request_handler.rb +5 -1
  214. data/lib/phusion_passenger/admin_tools.rb +1 -1
  215. data/lib/phusion_passenger/admin_tools/control_process.rb +2 -1
  216. data/lib/phusion_passenger/dependencies.rb +7 -4
  217. data/lib/phusion_passenger/platform_info.rb +8 -2
  218. data/lib/phusion_passenger/rack/application_spawner.rb +1 -1
  219. data/lib/phusion_passenger/templates/version_not_found.html.erb +9 -0
  220. data/lib/phusion_passenger/utils.rb +13 -6
  221. data/lib/phusion_passenger/wsgi/application_spawner.rb +1 -1
  222. data/{lib → misc}/rake/cplusplus.rb +0 -0
  223. data/{lib → misc}/rake/extensions.rb +0 -0
  224. data/{lib → misc}/rake/gempackagetask.rb +0 -0
  225. data/{lib → misc}/rake/packagetask.rb +0 -0
  226. data/{lib → misc}/rake/rdoctask.rb +0 -0
  227. data/misc/render_error_pages.rb +6 -5
  228. data/test/CxxTestMain.cpp +109 -7
  229. data/test/UtilsTest.cpp +61 -51
  230. data/test/config.yml.example +6 -2
  231. data/test/integration_tests.rb +4 -0
  232. data/test/ruby/abstract_request_handler_spec.rb +9 -3
  233. data/test/ruby/rack/application_spawner_spec.rb +3 -2
  234. data/test/ruby/rails/application_spawner_spec.rb +15 -4
  235. data/test/ruby/rails/framework_spawner_spec.rb +4 -2
  236. data/test/ruby/rails/spawner_error_handling_spec.rb +4 -4
  237. data/test/ruby/spawn_manager_spec.rb +22 -9
  238. data/test/ruby/utils_spec.rb +18 -12
  239. data/test/ruby/wsgi/application_spawner_spec.rb +16 -7
  240. data/test/stub/apache2/httpd.conf.erb +1 -0
  241. data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
  242. metadata +1064 -1090
  243. data/doc/Users guide Apache.html +0 -3127
  244. data/doc/Users guide Nginx.html +0 -1458
@@ -371,460 +371,466 @@
371
371
  <a name="l00355"></a>00355 }
372
372
  <a name="l00356"></a>00356 <span class="keywordflow">return</span> result.str();
373
373
  <a name="l00357"></a>00357 }
374
- <a name="l00358"></a>00358
375
- <a name="l00359"></a>00359 <span class="keywordtype">bool</span> needsRestart(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot, Domain *domain, <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) {
376
- <a name="l00360"></a>00360 <span class="keywordflow">return</span> domain-&gt;alwaysRestartFileStatter.refresh(options.<a class="code" href="structPassenger_1_1PoolOptions.html#eaf5a998b4a5da2246685c2dfb8a8c6d" title="A throttling rate for file stats.">statThrottleRate</a>) == 0
377
- <a name="l00361"></a>00361 || domain-&gt;restartFileChecker.changed(options.<a class="code" href="structPassenger_1_1PoolOptions.html#eaf5a998b4a5da2246685c2dfb8a8c6d" title="A throttling rate for file stats.">statThrottleRate</a>);
378
- <a name="l00362"></a>00362 }
379
- <a name="l00363"></a>00363
380
- <a name="l00364"></a>00364 <span class="keywordtype">void</span> cleanerThreadMainLoop() {
381
- <a name="l00365"></a>00365 this_thread::disable_syscall_interruption dsi;
382
- <a name="l00366"></a>00366 unique_lock&lt;boost::mutex&gt; l(lock);
383
- <a name="l00367"></a>00367 <span class="keywordflow">try</span> {
384
- <a name="l00368"></a>00368 <span class="keywordflow">while</span> (!done &amp;&amp; !this_thread::interruption_requested()) {
385
- <a name="l00369"></a>00369 xtime xt;
386
- <a name="l00370"></a>00370 xtime_get(&amp;xt, TIME_UTC);
387
- <a name="l00371"></a>00371 xt.sec += maxIdleTime + 1;
388
- <a name="l00372"></a>00372 <span class="keywordflow">if</span> (cleanerThreadSleeper.timed_wait(l, xt)) {
389
- <a name="l00373"></a>00373 <span class="comment">// Condition was woken up.</span>
390
- <a name="l00374"></a>00374 <span class="keywordflow">if</span> (done) {
391
- <a name="l00375"></a>00375 <span class="comment">// StandardApplicationPool is being destroyed.</span>
392
- <a name="l00376"></a>00376 <span class="keywordflow">break</span>;
393
- <a name="l00377"></a>00377 } <span class="keywordflow">else</span> {
394
- <a name="l00378"></a>00378 <span class="comment">// maxIdleTime changed.</span>
395
- <a name="l00379"></a>00379 <span class="keywordflow">continue</span>;
396
- <a name="l00380"></a>00380 }
397
- <a name="l00381"></a>00381 }
398
- <a name="l00382"></a>00382
399
- <a name="l00383"></a>00383 time_t now = syscalls::time(NULL);
400
- <a name="l00384"></a>00384 AppContainerList::iterator it;
401
- <a name="l00385"></a>00385 <span class="keywordflow">for</span> (it = inactiveApps.begin(); it != inactiveApps.end(); it++) {
402
- <a name="l00386"></a>00386 AppContainer &amp;container(*it-&gt;get());
403
- <a name="l00387"></a>00387 ApplicationPtr app(container.app);
404
- <a name="l00388"></a>00388 Domain *domain = domains[app-&gt;getAppRoot()].get();
405
- <a name="l00389"></a>00389 AppContainerList *instances = &amp;domain-&gt;instances;
406
- <a name="l00390"></a>00390
407
- <a name="l00391"></a>00391 <span class="keywordflow">if</span> (maxIdleTime &gt; 0 &amp;&amp;
408
- <a name="l00392"></a>00392 (now - container.lastUsed &gt; (time_t) maxIdleTime)) {
409
- <a name="l00393"></a>00393 P_DEBUG(<span class="stringliteral">"Cleaning idle app "</span> &lt;&lt; app-&gt;getAppRoot() &lt;&lt;
410
- <a name="l00394"></a>00394 <span class="stringliteral">" (PID "</span> &lt;&lt; app-&gt;getPid() &lt;&lt; <span class="stringliteral">")"</span>);
411
- <a name="l00395"></a>00395 instances-&gt;erase(container.iterator);
412
- <a name="l00396"></a>00396
413
- <a name="l00397"></a>00397 AppContainerList::iterator prev = it;
414
- <a name="l00398"></a>00398 prev--;
415
- <a name="l00399"></a>00399 inactiveApps.erase(it);
416
- <a name="l00400"></a>00400 it = prev;
417
- <a name="l00401"></a>00401
418
- <a name="l00402"></a>00402 domain-&gt;size--;
419
- <a name="l00403"></a>00403
420
- <a name="l00404"></a>00404 count--;
421
- <a name="l00405"></a>00405 }
422
- <a name="l00406"></a>00406 <span class="keywordflow">if</span> (instances-&gt;empty()) {
423
- <a name="l00407"></a>00407 domains.erase(app-&gt;getAppRoot());
424
- <a name="l00408"></a>00408 }
425
- <a name="l00409"></a>00409 }
426
- <a name="l00410"></a>00410 }
427
- <a name="l00411"></a>00411 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> exception &amp;e) {
428
- <a name="l00412"></a>00412 P_ERROR(<span class="stringliteral">"Uncaught exception: "</span> &lt;&lt; e.what());
429
- <a name="l00413"></a>00413 }
430
- <a name="l00414"></a>00414 }
431
- <a name="l00415"></a>00415 <span class="comment"></span>
432
- <a name="l00416"></a>00416 <span class="comment"> /**</span>
433
- <a name="l00417"></a>00417 <span class="comment"> * Spawn a new application instance, or use an existing one that's in the pool.</span>
434
- <a name="l00418"></a>00418 <span class="comment"> *</span>
435
- <a name="l00419"></a>00419 <span class="comment"> * @throws boost::thread_interrupted</span>
436
- <a name="l00420"></a>00420 <span class="comment"> * @throws SpawnException</span>
437
- <a name="l00421"></a>00421 <span class="comment"> * @throws SystemException</span>
438
- <a name="l00422"></a>00422 <span class="comment"> */</span>
439
- <a name="l00423"></a>00423 pair&lt;AppContainerPtr, Domain *&gt;
440
- <a name="l00424"></a>00424 spawnOrUseExisting(boost::mutex::scoped_lock &amp;l, <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) {
441
- <a name="l00425"></a>00425 beginning_of_function:
442
- <a name="l00426"></a>00426
443
- <a name="l00427"></a>00427 TRACE_POINT();
444
- <a name="l00428"></a>00428 this_thread::disable_interruption di;
445
- <a name="l00429"></a>00429 this_thread::disable_syscall_interruption dsi;
446
- <a name="l00430"></a>00430 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot(options.<a class="code" href="structPassenger_1_1PoolOptions.html#822039d204b48d9ed49184646734acf3" title="The root directory of the application to spawn.">appRoot</a>);
447
- <a name="l00431"></a>00431 AppContainerPtr container;
448
- <a name="l00432"></a>00432 Domain *domain;
449
- <a name="l00433"></a>00433 AppContainerList *instances;
450
- <a name="l00434"></a>00434
451
- <a name="l00435"></a>00435 <span class="keywordflow">try</span> {
452
- <a name="l00436"></a>00436 DomainMap::iterator it(domains.find(appRoot));
453
- <a name="l00437"></a>00437
454
- <a name="l00438"></a>00438 <span class="keywordflow">if</span> (it != domains.end() &amp;&amp; needsRestart(appRoot, it-&gt;second.get(), options)) {
455
- <a name="l00439"></a>00439 AppContainerList::iterator it2;
456
- <a name="l00440"></a>00440 instances = &amp;it-&gt;second-&gt;instances;
457
- <a name="l00441"></a>00441 <span class="keywordflow">for</span> (it2 = instances-&gt;begin(); it2 != instances-&gt;end(); it2++) {
458
- <a name="l00442"></a>00442 container = *it2;
459
- <a name="l00443"></a>00443 <span class="keywordflow">if</span> (container-&gt;sessions == 0) {
460
- <a name="l00444"></a>00444 inactiveApps.erase(container-&gt;ia_iterator);
461
- <a name="l00445"></a>00445 } <span class="keywordflow">else</span> {
462
- <a name="l00446"></a>00446 active--;
463
- <a name="l00447"></a>00447 }
464
- <a name="l00448"></a>00448 it2--;
465
- <a name="l00449"></a>00449 instances-&gt;erase(container-&gt;iterator);
466
- <a name="l00450"></a>00450 count--;
467
- <a name="l00451"></a>00451 }
468
- <a name="l00452"></a>00452 domains.erase(appRoot);
469
- <a name="l00453"></a>00453 spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#2e85c43042b9556ca2fd74b8d28956ce" title="Remove the cached application instances at the given application root.">reload</a>(appRoot);
470
- <a name="l00454"></a>00454 it = domains.end();
471
- <a name="l00455"></a>00455 activeOrMaxChanged.notify_all();
472
- <a name="l00456"></a>00456 }
473
- <a name="l00457"></a>00457
474
- <a name="l00458"></a>00458 <span class="keywordflow">if</span> (it != domains.end()) {
475
- <a name="l00459"></a>00459 domain = it-&gt;second.get();
476
- <a name="l00460"></a>00460 instances = &amp;domain-&gt;instances;
477
- <a name="l00461"></a>00461
478
- <a name="l00462"></a>00462 <span class="keywordflow">if</span> (instances-&gt;front()-&gt;sessions == 0) {
479
- <a name="l00463"></a>00463 container = instances-&gt;front();
480
- <a name="l00464"></a>00464 instances-&gt;pop_front();
481
- <a name="l00465"></a>00465 instances-&gt;push_back(container);
482
- <a name="l00466"></a>00466 container-&gt;iterator = instances-&gt;end();
483
- <a name="l00467"></a>00467 container-&gt;iterator--;
484
- <a name="l00468"></a>00468 inactiveApps.erase(container-&gt;ia_iterator);
485
- <a name="l00469"></a>00469 active++;
486
- <a name="l00470"></a>00470 activeOrMaxChanged.notify_all();
487
- <a name="l00471"></a>00471 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (count &gt;= max || (
488
- <a name="l00472"></a>00472 maxPerApp != 0 &amp;&amp; domain-&gt;size &gt;= maxPerApp )
489
- <a name="l00473"></a>00473 ) {
490
- <a name="l00474"></a>00474 <span class="keywordflow">if</span> (options.<a class="code" href="structPassenger_1_1PoolOptions.html#b610e568a7b5d3bb27460d6e35952b7e" title="Whether to use a global queue instead of a per-backend process queue.">useGlobalQueue</a>) {
491
- <a name="l00475"></a>00475 UPDATE_TRACE_POINT();
492
- <a name="l00476"></a>00476 waitingOnGlobalQueue++;
493
- <a name="l00477"></a>00477 activeOrMaxChanged.wait(l);
494
- <a name="l00478"></a>00478 waitingOnGlobalQueue--;
495
- <a name="l00479"></a>00479 <span class="keywordflow">goto</span> beginning_of_function;
496
- <a name="l00480"></a>00480 } <span class="keywordflow">else</span> {
497
- <a name="l00481"></a>00481 AppContainerList::iterator it(instances-&gt;begin());
498
- <a name="l00482"></a>00482 AppContainerList::iterator smallest(instances-&gt;begin());
499
- <a name="l00483"></a>00483 it++;
500
- <a name="l00484"></a>00484 <span class="keywordflow">for</span> (; it != instances-&gt;end(); it++) {
501
- <a name="l00485"></a>00485 <span class="keywordflow">if</span> ((*it)-&gt;sessions &lt; (*smallest)-&gt;sessions) {
502
- <a name="l00486"></a>00486 smallest = it;
503
- <a name="l00487"></a>00487 }
504
- <a name="l00488"></a>00488 }
505
- <a name="l00489"></a>00489 container = *smallest;
506
- <a name="l00490"></a>00490 instances-&gt;erase(smallest);
507
- <a name="l00491"></a>00491 instances-&gt;push_back(container);
508
- <a name="l00492"></a>00492 container-&gt;iterator = instances-&gt;end();
509
- <a name="l00493"></a>00493 container-&gt;iterator--;
510
- <a name="l00494"></a>00494 }
511
- <a name="l00495"></a>00495 } <span class="keywordflow">else</span> {
512
- <a name="l00496"></a>00496 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());
513
- <a name="l00497"></a>00497 {
514
- <a name="l00498"></a>00498 this_thread::restore_interruption ri(di);
515
- <a name="l00499"></a>00499 this_thread::restore_syscall_interruption rsi(dsi);
516
- <a name="l00500"></a>00500 container-&gt;app = spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#af035d564cc4e6683508939c9d6dbb64" title="Spawn a new instance of an application.">spawn</a>(options);
517
- <a name="l00501"></a>00501 }
518
- <a name="l00502"></a>00502 container-&gt;sessions = 0;
519
- <a name="l00503"></a>00503 instances-&gt;push_back(container);
520
- <a name="l00504"></a>00504 container-&gt;iterator = instances-&gt;end();
521
- <a name="l00505"></a>00505 container-&gt;iterator--;
522
- <a name="l00506"></a>00506 domain-&gt;size++;
523
- <a name="l00507"></a>00507 count++;
524
- <a name="l00508"></a>00508 active++;
525
- <a name="l00509"></a>00509 activeOrMaxChanged.notify_all();
526
- <a name="l00510"></a>00510 }
527
- <a name="l00511"></a>00511 } <span class="keywordflow">else</span> {
528
- <a name="l00512"></a>00512 <span class="keywordflow">if</span> (active &gt;= max) {
529
- <a name="l00513"></a>00513 UPDATE_TRACE_POINT();
530
- <a name="l00514"></a>00514 activeOrMaxChanged.wait(l);
531
- <a name="l00515"></a>00515 <span class="keywordflow">goto</span> beginning_of_function;
532
- <a name="l00516"></a>00516 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (count == max) {
533
- <a name="l00517"></a>00517 container = inactiveApps.front();
534
- <a name="l00518"></a>00518 inactiveApps.pop_front();
535
- <a name="l00519"></a>00519 domain = domains[container-&gt;app-&gt;getAppRoot()].get();
536
- <a name="l00520"></a>00520 instances = &amp;domain-&gt;instances;
537
- <a name="l00521"></a>00521 instances-&gt;erase(container-&gt;iterator);
538
- <a name="l00522"></a>00522 <span class="keywordflow">if</span> (instances-&gt;empty()) {
539
- <a name="l00523"></a>00523 domains.erase(container-&gt;app-&gt;getAppRoot());
540
- <a name="l00524"></a>00524 } <span class="keywordflow">else</span> {
541
- <a name="l00525"></a>00525 domain-&gt;size--;
542
- <a name="l00526"></a>00526 }
543
- <a name="l00527"></a>00527 count--;
544
- <a name="l00528"></a>00528 }
545
- <a name="l00529"></a>00529
546
- <a name="l00530"></a>00530 UPDATE_TRACE_POINT();
547
- <a name="l00531"></a>00531 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());
548
- <a name="l00532"></a>00532 {
549
- <a name="l00533"></a>00533 this_thread::restore_interruption ri(di);
550
- <a name="l00534"></a>00534 this_thread::restore_syscall_interruption rsi(dsi);
551
- <a name="l00535"></a>00535 container-&gt;app = spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#af035d564cc4e6683508939c9d6dbb64" title="Spawn a new instance of an application.">spawn</a>(options);
552
- <a name="l00536"></a>00536 }
553
- <a name="l00537"></a>00537 container-&gt;sessions = 0;
554
- <a name="l00538"></a>00538 it = domains.find(appRoot);
555
- <a name="l00539"></a>00539 <span class="keywordflow">if</span> (it == domains.end()) {
556
- <a name="l00540"></a>00540 domain = <span class="keyword">new</span> Domain(options);
557
- <a name="l00541"></a>00541 domain-&gt;size = 1;
558
- <a name="l00542"></a>00542 domain-&gt;maxRequests = options.<a class="code" href="structPassenger_1_1PoolOptions.html#70251ed3cb3713cb26a0b166c6b015c0" title="The maximum number of requests that the spawned application may process before exiting...">maxRequests</a>;
559
- <a name="l00543"></a>00543 domains[appRoot] = <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(domain);
560
- <a name="l00544"></a>00544 } <span class="keywordflow">else</span> {
561
- <a name="l00545"></a>00545 domain = it-&gt;second.get();
562
- <a name="l00546"></a>00546 domain-&gt;size++;
563
- <a name="l00547"></a>00547 }
564
- <a name="l00548"></a>00548 instances = &amp;domain-&gt;instances;
565
- <a name="l00549"></a>00549 instances-&gt;push_back(container);
566
- <a name="l00550"></a>00550 container-&gt;iterator = instances-&gt;end();
567
- <a name="l00551"></a>00551 container-&gt;iterator--;
568
- <a name="l00552"></a>00552 count++;
569
- <a name="l00553"></a>00553 active++;
570
- <a name="l00554"></a>00554 activeOrMaxChanged.notify_all();
571
- <a name="l00555"></a>00555 }
572
- <a name="l00556"></a>00556 } <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) {
573
- <a name="l00557"></a>00557 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot spawn application '"</span>);
574
- <a name="l00558"></a>00558 message.append(appRoot);
575
- <a name="l00559"></a>00559 message.append(<span class="stringliteral">"': "</span>);
576
- <a name="l00560"></a>00560 message.append(e.<a class="code" href="classPassenger_1_1SpawnException.html#d2da180f89a43423a4b37248249972ff">what</a>());
577
- <a name="l00561"></a>00561 <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>()) {
578
- <a name="l00562"></a>00562 <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>());
579
- <a name="l00563"></a>00563 } <span class="keywordflow">else</span> {
580
- <a name="l00564"></a>00564 <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);
581
- <a name="l00565"></a>00565 }
582
- <a name="l00566"></a>00566 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> exception &amp;e) {
583
- <a name="l00567"></a>00567 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot spawn application '"</span>);
584
- <a name="l00568"></a>00568 message.append(appRoot);
585
- <a name="l00569"></a>00569 message.append(<span class="stringliteral">"': "</span>);
586
- <a name="l00570"></a>00570 message.append(e.what());
587
- <a name="l00571"></a>00571 <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);
588
- <a name="l00572"></a>00572 }
589
- <a name="l00573"></a>00573
590
- <a name="l00574"></a>00574 <span class="keywordflow">return</span> make_pair(container, domain);
591
- <a name="l00575"></a>00575 }
592
- <a name="l00576"></a>00576
593
- <a name="l00577"></a>00577 <span class="keyword">public</span>:<span class="comment"></span>
594
- <a name="l00578"></a>00578 <span class="comment"> /**</span>
595
- <a name="l00579"></a>00579 <span class="comment"> * Create a new StandardApplicationPool object.</span>
596
- <a name="l00580"></a>00580 <span class="comment"> *</span>
597
- <a name="l00581"></a>00581 <span class="comment"> * @param spawnServerCommand The filename of the spawn server to use.</span>
598
- <a name="l00582"></a>00582 <span class="comment"> * @param logFile Specify a log file that the spawn server should use.</span>
599
- <a name="l00583"></a>00583 <span class="comment"> * Messages on its standard output and standard error channels</span>
600
- <a name="l00584"></a>00584 <span class="comment"> * will be written to this log file. If an empty string is</span>
601
- <a name="l00585"></a>00585 <span class="comment"> * specified, no log file will be used, and the spawn server</span>
602
- <a name="l00586"></a>00586 <span class="comment"> * will use the same standard output/error channels as the</span>
603
- <a name="l00587"></a>00587 <span class="comment"> * current process.</span>
604
- <a name="l00588"></a>00588 <span class="comment"> * @param rubyCommand The Ruby interpreter's command.</span>
605
- <a name="l00589"></a>00589 <span class="comment"> * @param user The user that the spawn manager should run as. This</span>
606
- <a name="l00590"></a>00590 <span class="comment"> * parameter only has effect if the current process is</span>
607
- <a name="l00591"></a>00591 <span class="comment"> * running as root. If the empty string is given, or if</span>
608
- <a name="l00592"></a>00592 <span class="comment"> * the &lt;tt&gt;user&lt;/tt&gt; is not a valid username, then</span>
609
- <a name="l00593"></a>00593 <span class="comment"> * the spawn manager will be run as the current user.</span>
610
- <a name="l00594"></a>00594 <span class="comment"> * @throws SystemException An error occured while trying to setup the spawn server.</span>
611
- <a name="l00595"></a>00595 <span class="comment"> * @throws IOException The specified log file could not be opened.</span>
612
- <a name="l00596"></a>00596 <span class="comment"> */</span>
613
- <a name="l00597"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#f175704fc477f37ba1d387be09fa2e6b">00597</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,
614
- <a name="l00598"></a>00598 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;logFile = <span class="stringliteral">""</span>,
615
- <a name="l00599"></a>00599 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;rubyCommand = <span class="stringliteral">"ruby"</span>,
616
- <a name="l00600"></a>00600 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;user = <span class="stringliteral">""</span>)
617
- <a name="l00601"></a>00601 :
618
- <a name="l00602"></a>00602 #ifndef PASSENGER_USE_DUMMY_SPAWN_MANAGER
619
- <a name="l00603"></a>00603 spawnManager(spawnServerCommand, logFile, rubyCommand, user),
620
- <a name="l00604"></a>00604 #endif
621
- <a name="l00605"></a>00605 data(new SharedData()),
622
- <a name="l00606"></a>00606 lock(data-&gt;lock),
623
- <a name="l00607"></a>00607 activeOrMaxChanged(data-&gt;activeOrMaxChanged),
624
- <a name="l00608"></a>00608 domains(data-&gt;domains),
625
- <a name="l00609"></a>00609 max(data-&gt;max),
626
- <a name="l00610"></a>00610 count(data-&gt;count),
627
- <a name="l00611"></a>00611 active(data-&gt;active),
628
- <a name="l00612"></a>00612 maxPerApp(data-&gt;maxPerApp),
629
- <a name="l00613"></a>00613 inactiveApps(data-&gt;inactiveApps),
630
- <a name="l00614"></a>00614 appInstanceCount(data-&gt;appInstanceCount)
631
- <a name="l00615"></a>00615 {
632
- <a name="l00616"></a>00616 TRACE_POINT();
633
- <a name="l00617"></a>00617 detached = <span class="keyword">false</span>;
634
- <a name="l00618"></a>00618 done = <span class="keyword">false</span>;
635
- <a name="l00619"></a>00619 max = DEFAULT_MAX_POOL_SIZE;
636
- <a name="l00620"></a>00620 count = 0;
637
- <a name="l00621"></a>00621 active = 0;
638
- <a name="l00622"></a>00622 waitingOnGlobalQueue = 0;
639
- <a name="l00623"></a>00623 maxPerApp = DEFAULT_MAX_INSTANCES_PER_APP;
640
- <a name="l00624"></a>00624 maxIdleTime = DEFAULT_MAX_IDLE_TIME;
641
- <a name="l00625"></a>00625 cleanerThread = <span class="keyword">new</span> boost::thread(
642
- <a name="l00626"></a>00626 bind(&amp;StandardApplicationPool::cleanerThreadMainLoop, <span class="keyword">this</span>),
643
- <a name="l00627"></a>00627 CLEANER_THREAD_STACK_SIZE
644
- <a name="l00628"></a>00628 );
645
- <a name="l00629"></a>00629 }
646
- <a name="l00630"></a>00630
647
- <a name="l00631"></a>00631 <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>() {
648
- <a name="l00632"></a>00632 <span class="keywordflow">if</span> (!detached) {
649
- <a name="l00633"></a>00633 this_thread::disable_interruption di;
650
- <a name="l00634"></a>00634 {
651
- <a name="l00635"></a>00635 boost::mutex::scoped_lock l(lock);
652
- <a name="l00636"></a>00636 done = <span class="keyword">true</span>;
653
- <a name="l00637"></a>00637 cleanerThreadSleeper.notify_one();
654
- <a name="l00638"></a>00638 }
655
- <a name="l00639"></a>00639 cleanerThread-&gt;join();
656
- <a name="l00640"></a>00640 }
657
- <a name="l00641"></a>00641 <span class="keyword">delete</span> cleanerThread;
658
- <a name="l00642"></a>00642 }
659
- <a name="l00643"></a>00643
660
- <a name="l00644"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#5a33f0766bbcfb2a48e08fc27bd1b684">00644</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>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot) {
661
- <a name="l00645"></a>00645 <span class="keywordflow">return</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#0b206eb4eb2869423d75c042a0653c67" title="Open a new session with the application specified by PoolOptions.appRoot.">ApplicationPool::get</a>(appRoot);
662
- <a name="l00646"></a>00646 }
663
- <a name="l00647"></a>00647
664
- <a name="l00648"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#ffc8f3ef8b1d925d203794d191d7fef4">00648</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>(<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) {
665
- <a name="l00649"></a>00649 TRACE_POINT();
666
- <a name="l00650"></a>00650 <span class="keyword">using namespace </span>boost::posix_time;
667
- <a name="l00651"></a>00651 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> attempt = 0;
668
- <a name="l00652"></a>00652 <span class="comment">// TODO: We should probably add a timeout to the following</span>
669
- <a name="l00653"></a>00653 <span class="comment">// lock. This way we can fail gracefully if the server's under</span>
670
- <a name="l00654"></a>00654 <span class="comment">// rediculous load. Though I'm not sure how much it really helps.</span>
671
- <a name="l00655"></a>00655 unique_lock&lt;boost::mutex&gt; l(lock);
672
- <a name="l00656"></a>00656
673
- <a name="l00657"></a>00657 <span class="keywordflow">while</span> (<span class="keyword">true</span>) {
674
- <a name="l00658"></a>00658 attempt++;
675
- <a name="l00659"></a>00659
676
- <a name="l00660"></a>00660 pair&lt;AppContainerPtr, Domain *&gt; p(
677
- <a name="l00661"></a>00661 spawnOrUseExisting(l, options)
678
- <a name="l00662"></a>00662 );
679
- <a name="l00663"></a>00663 AppContainerPtr &amp;container = p.first;
680
- <a name="l00664"></a>00664 Domain *domain = p.second;
681
- <a name="l00665"></a>00665
682
- <a name="l00666"></a>00666 container-&gt;lastUsed = time(NULL);
683
- <a name="l00667"></a>00667 container-&gt;sessions++;
684
- <a name="l00668"></a>00668
685
- <a name="l00669"></a>00669 P_ASSERT(verifyState(), <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a>(),
686
- <a name="l00670"></a>00670 <span class="stringliteral">"State is valid:\n"</span> &lt;&lt; <a class="code" href="classPassenger_1_1StandardApplicationPool.html#22b4149ca8256c3042fc342e681b0383" title="Returns a textual description of the internal state of the application pool.">toString</a>(<span class="keyword">false</span>));
687
- <a name="l00671"></a>00671 <span class="keywordflow">try</span> {
688
- <a name="l00672"></a>00672 UPDATE_TRACE_POINT();
689
- <a name="l00673"></a>00673 <span class="keywordflow">return</span> container-&gt;app-&gt;connect(SessionCloseCallback(data, container));
690
- <a name="l00674"></a>00674 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> exception &amp;e) {
691
- <a name="l00675"></a>00675 container-&gt;sessions--;
692
- <a name="l00676"></a>00676
693
- <a name="l00677"></a>00677 AppContainerList &amp;instances(domain-&gt;instances);
694
- <a name="l00678"></a>00678 instances.erase(container-&gt;iterator);
695
- <a name="l00679"></a>00679 domain-&gt;size--;
696
- <a name="l00680"></a>00680 <span class="keywordflow">if</span> (instances.empty()) {
697
- <a name="l00681"></a>00681 domains.erase(options.<a class="code" href="structPassenger_1_1PoolOptions.html#822039d204b48d9ed49184646734acf3" title="The root directory of the application to spawn.">appRoot</a>);
698
- <a name="l00682"></a>00682 }
699
- <a name="l00683"></a>00683 count--;
700
- <a name="l00684"></a>00684 active--;
701
- <a name="l00685"></a>00685 activeOrMaxChanged.notify_all();
702
- <a name="l00686"></a>00686 P_ASSERT(verifyState(), <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a>(),
703
- <a name="l00687"></a>00687 <span class="stringliteral">"State is valid: "</span> &lt;&lt; <a class="code" href="classPassenger_1_1StandardApplicationPool.html#22b4149ca8256c3042fc342e681b0383" title="Returns a textual description of the internal state of the application pool.">toString</a>(<span class="keyword">false</span>));
704
- <a name="l00688"></a>00688 <span class="keywordflow">if</span> (attempt == MAX_GET_ATTEMPTS) {
705
- <a name="l00689"></a>00689 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot connect to an existing "</span>
706
- <a name="l00690"></a>00690 <span class="stringliteral">"application instance for '"</span>);
707
- <a name="l00691"></a>00691 message.append(options.<a class="code" href="structPassenger_1_1PoolOptions.html#822039d204b48d9ed49184646734acf3" title="The root directory of the application to spawn.">appRoot</a>);
708
- <a name="l00692"></a>00692 message.append(<span class="stringliteral">"': "</span>);
709
- <a name="l00693"></a>00693 <span class="keywordflow">try</span> {
710
- <a name="l00694"></a>00694 <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 =
711
- <a name="l00695"></a>00695 <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);
712
- <a name="l00696"></a>00696 message.append(syse.<a class="code" href="classPassenger_1_1SystemException.html#0ef41d755fea2c9b1db2252e7c418dc8" title="Returns the system&amp;#39;s error message.">sys</a>());
713
- <a name="l00697"></a>00697 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> bad_cast &amp;) {
714
- <a name="l00698"></a>00698 message.append(e.what());
715
- <a name="l00699"></a>00699 }
716
- <a name="l00700"></a>00700 <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);
717
- <a name="l00701"></a>00701 }
718
- <a name="l00702"></a>00702 }
719
- <a name="l00703"></a>00703 }
720
- <a name="l00704"></a>00704 <span class="comment">// Never reached; shut up compiler warning</span>
721
- <a name="l00705"></a>00705 <span class="keywordflow">return</span> <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a>();
722
- <a name="l00706"></a>00706 }
723
- <a name="l00707"></a>00707
724
- <a name="l00708"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#bcf8faeb4f431ae07ea0e20270661d08">00708</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>() {
725
- <a name="l00709"></a>00709 boost::mutex::scoped_lock l(lock);
726
- <a name="l00710"></a>00710 domains.clear();
727
- <a name="l00711"></a>00711 inactiveApps.clear();
728
- <a name="l00712"></a>00712 appInstanceCount.clear();
729
- <a name="l00713"></a>00713 count = 0;
730
- <a name="l00714"></a>00714 active = 0;
731
- <a name="l00715"></a>00715 activeOrMaxChanged.notify_all();
732
- <a name="l00716"></a>00716 }
733
- <a name="l00717"></a>00717
734
- <a name="l00718"></a>00718 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMaxIdleTime(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> seconds) {
735
- <a name="l00719"></a>00719 boost::mutex::scoped_lock l(lock);
736
- <a name="l00720"></a>00720 maxIdleTime = seconds;
737
- <a name="l00721"></a>00721 cleanerThreadSleeper.notify_one();
374
+ <a name="l00358"></a>00358 <span class="comment"></span>
375
+ <a name="l00359"></a>00359 <span class="comment"> /**</span>
376
+ <a name="l00360"></a>00360 <span class="comment"> * Checks whether the given application domain needs to be restarted.</span>
377
+ <a name="l00361"></a>00361 <span class="comment"> *</span>
378
+ <a name="l00362"></a>00362 <span class="comment"> * @throws SystemException Something went wrong while retrieving the system time.</span>
379
+ <a name="l00363"></a>00363 <span class="comment"> * @throws boost::thread_interrupted</span>
380
+ <a name="l00364"></a>00364 <span class="comment"> */</span>
381
+ <a name="l00365"></a>00365 <span class="keywordtype">bool</span> needsRestart(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot, Domain *domain, <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) {
382
+ <a name="l00366"></a>00366 <span class="keywordflow">return</span> domain-&gt;alwaysRestartFileStatter.refresh(options.<a class="code" href="structPassenger_1_1PoolOptions.html#eaf5a998b4a5da2246685c2dfb8a8c6d" title="A throttling rate for file stats.">statThrottleRate</a>) == 0
383
+ <a name="l00367"></a>00367 || domain-&gt;restartFileChecker.changed(options.<a class="code" href="structPassenger_1_1PoolOptions.html#eaf5a998b4a5da2246685c2dfb8a8c6d" title="A throttling rate for file stats.">statThrottleRate</a>);
384
+ <a name="l00368"></a>00368 }
385
+ <a name="l00369"></a>00369
386
+ <a name="l00370"></a>00370 <span class="keywordtype">void</span> cleanerThreadMainLoop() {
387
+ <a name="l00371"></a>00371 this_thread::disable_syscall_interruption dsi;
388
+ <a name="l00372"></a>00372 unique_lock&lt;boost::mutex&gt; l(lock);
389
+ <a name="l00373"></a>00373 <span class="keywordflow">try</span> {
390
+ <a name="l00374"></a>00374 <span class="keywordflow">while</span> (!done &amp;&amp; !this_thread::interruption_requested()) {
391
+ <a name="l00375"></a>00375 xtime xt;
392
+ <a name="l00376"></a>00376 xtime_get(&amp;xt, TIME_UTC);
393
+ <a name="l00377"></a>00377 xt.sec += maxIdleTime + 1;
394
+ <a name="l00378"></a>00378 <span class="keywordflow">if</span> (cleanerThreadSleeper.timed_wait(l, xt)) {
395
+ <a name="l00379"></a>00379 <span class="comment">// Condition was woken up.</span>
396
+ <a name="l00380"></a>00380 <span class="keywordflow">if</span> (done) {
397
+ <a name="l00381"></a>00381 <span class="comment">// StandardApplicationPool is being destroyed.</span>
398
+ <a name="l00382"></a>00382 <span class="keywordflow">break</span>;
399
+ <a name="l00383"></a>00383 } <span class="keywordflow">else</span> {
400
+ <a name="l00384"></a>00384 <span class="comment">// maxIdleTime changed.</span>
401
+ <a name="l00385"></a>00385 <span class="keywordflow">continue</span>;
402
+ <a name="l00386"></a>00386 }
403
+ <a name="l00387"></a>00387 }
404
+ <a name="l00388"></a>00388
405
+ <a name="l00389"></a>00389 time_t now = syscalls::time(NULL);
406
+ <a name="l00390"></a>00390 AppContainerList::iterator it;
407
+ <a name="l00391"></a>00391 <span class="keywordflow">for</span> (it = inactiveApps.begin(); it != inactiveApps.end(); it++) {
408
+ <a name="l00392"></a>00392 AppContainer &amp;container(*it-&gt;get());
409
+ <a name="l00393"></a>00393 ApplicationPtr app(container.app);
410
+ <a name="l00394"></a>00394 Domain *domain = domains[app-&gt;getAppRoot()].get();
411
+ <a name="l00395"></a>00395 AppContainerList *instances = &amp;domain-&gt;instances;
412
+ <a name="l00396"></a>00396
413
+ <a name="l00397"></a>00397 <span class="keywordflow">if</span> (maxIdleTime &gt; 0 &amp;&amp;
414
+ <a name="l00398"></a>00398 (now - container.lastUsed &gt; (time_t) maxIdleTime)) {
415
+ <a name="l00399"></a>00399 P_DEBUG(<span class="stringliteral">"Cleaning idle app "</span> &lt;&lt; app-&gt;getAppRoot() &lt;&lt;
416
+ <a name="l00400"></a>00400 <span class="stringliteral">" (PID "</span> &lt;&lt; app-&gt;getPid() &lt;&lt; <span class="stringliteral">")"</span>);
417
+ <a name="l00401"></a>00401 instances-&gt;erase(container.iterator);
418
+ <a name="l00402"></a>00402
419
+ <a name="l00403"></a>00403 AppContainerList::iterator prev = it;
420
+ <a name="l00404"></a>00404 prev--;
421
+ <a name="l00405"></a>00405 inactiveApps.erase(it);
422
+ <a name="l00406"></a>00406 it = prev;
423
+ <a name="l00407"></a>00407
424
+ <a name="l00408"></a>00408 domain-&gt;size--;
425
+ <a name="l00409"></a>00409
426
+ <a name="l00410"></a>00410 count--;
427
+ <a name="l00411"></a>00411 }
428
+ <a name="l00412"></a>00412 <span class="keywordflow">if</span> (instances-&gt;empty()) {
429
+ <a name="l00413"></a>00413 domains.erase(app-&gt;getAppRoot());
430
+ <a name="l00414"></a>00414 }
431
+ <a name="l00415"></a>00415 }
432
+ <a name="l00416"></a>00416 }
433
+ <a name="l00417"></a>00417 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> exception &amp;e) {
434
+ <a name="l00418"></a>00418 P_ERROR(<span class="stringliteral">"Uncaught exception: "</span> &lt;&lt; e.what());
435
+ <a name="l00419"></a>00419 }
436
+ <a name="l00420"></a>00420 }
437
+ <a name="l00421"></a>00421 <span class="comment"></span>
438
+ <a name="l00422"></a>00422 <span class="comment"> /**</span>
439
+ <a name="l00423"></a>00423 <span class="comment"> * Spawn a new application instance, or use an existing one that's in the pool.</span>
440
+ <a name="l00424"></a>00424 <span class="comment"> *</span>
441
+ <a name="l00425"></a>00425 <span class="comment"> * @throws boost::thread_interrupted</span>
442
+ <a name="l00426"></a>00426 <span class="comment"> * @throws SpawnException</span>
443
+ <a name="l00427"></a>00427 <span class="comment"> * @throws SystemException</span>
444
+ <a name="l00428"></a>00428 <span class="comment"> */</span>
445
+ <a name="l00429"></a>00429 pair&lt;AppContainerPtr, Domain *&gt;
446
+ <a name="l00430"></a>00430 spawnOrUseExisting(boost::mutex::scoped_lock &amp;l, <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) {
447
+ <a name="l00431"></a>00431 beginning_of_function:
448
+ <a name="l00432"></a>00432
449
+ <a name="l00433"></a>00433 TRACE_POINT();
450
+ <a name="l00434"></a>00434 this_thread::disable_interruption di;
451
+ <a name="l00435"></a>00435 this_thread::disable_syscall_interruption dsi;
452
+ <a name="l00436"></a>00436 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot(options.<a class="code" href="structPassenger_1_1PoolOptions.html#822039d204b48d9ed49184646734acf3" title="The root directory of the application to spawn.">appRoot</a>);
453
+ <a name="l00437"></a>00437 AppContainerPtr container;
454
+ <a name="l00438"></a>00438 Domain *domain;
455
+ <a name="l00439"></a>00439 AppContainerList *instances;
456
+ <a name="l00440"></a>00440
457
+ <a name="l00441"></a>00441 <span class="keywordflow">try</span> {
458
+ <a name="l00442"></a>00442 DomainMap::iterator it(domains.find(appRoot));
459
+ <a name="l00443"></a>00443
460
+ <a name="l00444"></a>00444 <span class="keywordflow">if</span> (it != domains.end() &amp;&amp; needsRestart(appRoot, it-&gt;second.get(), options)) {
461
+ <a name="l00445"></a>00445 AppContainerList::iterator it2;
462
+ <a name="l00446"></a>00446 instances = &amp;it-&gt;second-&gt;instances;
463
+ <a name="l00447"></a>00447 <span class="keywordflow">for</span> (it2 = instances-&gt;begin(); it2 != instances-&gt;end(); it2++) {
464
+ <a name="l00448"></a>00448 container = *it2;
465
+ <a name="l00449"></a>00449 <span class="keywordflow">if</span> (container-&gt;sessions == 0) {
466
+ <a name="l00450"></a>00450 inactiveApps.erase(container-&gt;ia_iterator);
467
+ <a name="l00451"></a>00451 } <span class="keywordflow">else</span> {
468
+ <a name="l00452"></a>00452 active--;
469
+ <a name="l00453"></a>00453 }
470
+ <a name="l00454"></a>00454 it2--;
471
+ <a name="l00455"></a>00455 instances-&gt;erase(container-&gt;iterator);
472
+ <a name="l00456"></a>00456 count--;
473
+ <a name="l00457"></a>00457 }
474
+ <a name="l00458"></a>00458 domains.erase(appRoot);
475
+ <a name="l00459"></a>00459 spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#2e85c43042b9556ca2fd74b8d28956ce" title="Remove the cached application instances at the given application root.">reload</a>(appRoot);
476
+ <a name="l00460"></a>00460 it = domains.end();
477
+ <a name="l00461"></a>00461 activeOrMaxChanged.notify_all();
478
+ <a name="l00462"></a>00462 }
479
+ <a name="l00463"></a>00463
480
+ <a name="l00464"></a>00464 <span class="keywordflow">if</span> (it != domains.end()) {
481
+ <a name="l00465"></a>00465 domain = it-&gt;second.get();
482
+ <a name="l00466"></a>00466 instances = &amp;domain-&gt;instances;
483
+ <a name="l00467"></a>00467
484
+ <a name="l00468"></a>00468 <span class="keywordflow">if</span> (instances-&gt;front()-&gt;sessions == 0) {
485
+ <a name="l00469"></a>00469 container = instances-&gt;front();
486
+ <a name="l00470"></a>00470 instances-&gt;pop_front();
487
+ <a name="l00471"></a>00471 instances-&gt;push_back(container);
488
+ <a name="l00472"></a>00472 container-&gt;iterator = instances-&gt;end();
489
+ <a name="l00473"></a>00473 container-&gt;iterator--;
490
+ <a name="l00474"></a>00474 inactiveApps.erase(container-&gt;ia_iterator);
491
+ <a name="l00475"></a>00475 active++;
492
+ <a name="l00476"></a>00476 activeOrMaxChanged.notify_all();
493
+ <a name="l00477"></a>00477 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (count &gt;= max || (
494
+ <a name="l00478"></a>00478 maxPerApp != 0 &amp;&amp; domain-&gt;size &gt;= maxPerApp )
495
+ <a name="l00479"></a>00479 ) {
496
+ <a name="l00480"></a>00480 <span class="keywordflow">if</span> (options.<a class="code" href="structPassenger_1_1PoolOptions.html#b610e568a7b5d3bb27460d6e35952b7e" title="Whether to use a global queue instead of a per-backend process queue.">useGlobalQueue</a>) {
497
+ <a name="l00481"></a>00481 UPDATE_TRACE_POINT();
498
+ <a name="l00482"></a>00482 waitingOnGlobalQueue++;
499
+ <a name="l00483"></a>00483 activeOrMaxChanged.wait(l);
500
+ <a name="l00484"></a>00484 waitingOnGlobalQueue--;
501
+ <a name="l00485"></a>00485 <span class="keywordflow">goto</span> beginning_of_function;
502
+ <a name="l00486"></a>00486 } <span class="keywordflow">else</span> {
503
+ <a name="l00487"></a>00487 AppContainerList::iterator it(instances-&gt;begin());
504
+ <a name="l00488"></a>00488 AppContainerList::iterator smallest(instances-&gt;begin());
505
+ <a name="l00489"></a>00489 it++;
506
+ <a name="l00490"></a>00490 <span class="keywordflow">for</span> (; it != instances-&gt;end(); it++) {
507
+ <a name="l00491"></a>00491 <span class="keywordflow">if</span> ((*it)-&gt;sessions &lt; (*smallest)-&gt;sessions) {
508
+ <a name="l00492"></a>00492 smallest = it;
509
+ <a name="l00493"></a>00493 }
510
+ <a name="l00494"></a>00494 }
511
+ <a name="l00495"></a>00495 container = *smallest;
512
+ <a name="l00496"></a>00496 instances-&gt;erase(smallest);
513
+ <a name="l00497"></a>00497 instances-&gt;push_back(container);
514
+ <a name="l00498"></a>00498 container-&gt;iterator = instances-&gt;end();
515
+ <a name="l00499"></a>00499 container-&gt;iterator--;
516
+ <a name="l00500"></a>00500 }
517
+ <a name="l00501"></a>00501 } <span class="keywordflow">else</span> {
518
+ <a name="l00502"></a>00502 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());
519
+ <a name="l00503"></a>00503 {
520
+ <a name="l00504"></a>00504 this_thread::restore_interruption ri(di);
521
+ <a name="l00505"></a>00505 this_thread::restore_syscall_interruption rsi(dsi);
522
+ <a name="l00506"></a>00506 container-&gt;app = spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#af035d564cc4e6683508939c9d6dbb64" title="Spawn a new instance of an application.">spawn</a>(options);
523
+ <a name="l00507"></a>00507 }
524
+ <a name="l00508"></a>00508 container-&gt;sessions = 0;
525
+ <a name="l00509"></a>00509 instances-&gt;push_back(container);
526
+ <a name="l00510"></a>00510 container-&gt;iterator = instances-&gt;end();
527
+ <a name="l00511"></a>00511 container-&gt;iterator--;
528
+ <a name="l00512"></a>00512 domain-&gt;size++;
529
+ <a name="l00513"></a>00513 count++;
530
+ <a name="l00514"></a>00514 active++;
531
+ <a name="l00515"></a>00515 activeOrMaxChanged.notify_all();
532
+ <a name="l00516"></a>00516 }
533
+ <a name="l00517"></a>00517 } <span class="keywordflow">else</span> {
534
+ <a name="l00518"></a>00518 <span class="keywordflow">if</span> (active &gt;= max) {
535
+ <a name="l00519"></a>00519 UPDATE_TRACE_POINT();
536
+ <a name="l00520"></a>00520 activeOrMaxChanged.wait(l);
537
+ <a name="l00521"></a>00521 <span class="keywordflow">goto</span> beginning_of_function;
538
+ <a name="l00522"></a>00522 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (count == max) {
539
+ <a name="l00523"></a>00523 container = inactiveApps.front();
540
+ <a name="l00524"></a>00524 inactiveApps.pop_front();
541
+ <a name="l00525"></a>00525 domain = domains[container-&gt;app-&gt;getAppRoot()].get();
542
+ <a name="l00526"></a>00526 instances = &amp;domain-&gt;instances;
543
+ <a name="l00527"></a>00527 instances-&gt;erase(container-&gt;iterator);
544
+ <a name="l00528"></a>00528 <span class="keywordflow">if</span> (instances-&gt;empty()) {
545
+ <a name="l00529"></a>00529 domains.erase(container-&gt;app-&gt;getAppRoot());
546
+ <a name="l00530"></a>00530 } <span class="keywordflow">else</span> {
547
+ <a name="l00531"></a>00531 domain-&gt;size--;
548
+ <a name="l00532"></a>00532 }
549
+ <a name="l00533"></a>00533 count--;
550
+ <a name="l00534"></a>00534 }
551
+ <a name="l00535"></a>00535
552
+ <a name="l00536"></a>00536 UPDATE_TRACE_POINT();
553
+ <a name="l00537"></a>00537 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());
554
+ <a name="l00538"></a>00538 {
555
+ <a name="l00539"></a>00539 this_thread::restore_interruption ri(di);
556
+ <a name="l00540"></a>00540 this_thread::restore_syscall_interruption rsi(dsi);
557
+ <a name="l00541"></a>00541 container-&gt;app = spawnManager.<a class="code" href="classPassenger_1_1SpawnManager.html#af035d564cc4e6683508939c9d6dbb64" title="Spawn a new instance of an application.">spawn</a>(options);
558
+ <a name="l00542"></a>00542 }
559
+ <a name="l00543"></a>00543 container-&gt;sessions = 0;
560
+ <a name="l00544"></a>00544 it = domains.find(appRoot);
561
+ <a name="l00545"></a>00545 <span class="keywordflow">if</span> (it == domains.end()) {
562
+ <a name="l00546"></a>00546 domain = <span class="keyword">new</span> Domain(options);
563
+ <a name="l00547"></a>00547 domain-&gt;size = 1;
564
+ <a name="l00548"></a>00548 domain-&gt;maxRequests = options.<a class="code" href="structPassenger_1_1PoolOptions.html#70251ed3cb3713cb26a0b166c6b015c0" title="The maximum number of requests that the spawned application may process before exiting...">maxRequests</a>;
565
+ <a name="l00549"></a>00549 domains[appRoot] = <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(domain);
566
+ <a name="l00550"></a>00550 } <span class="keywordflow">else</span> {
567
+ <a name="l00551"></a>00551 domain = it-&gt;second.get();
568
+ <a name="l00552"></a>00552 domain-&gt;size++;
569
+ <a name="l00553"></a>00553 }
570
+ <a name="l00554"></a>00554 instances = &amp;domain-&gt;instances;
571
+ <a name="l00555"></a>00555 instances-&gt;push_back(container);
572
+ <a name="l00556"></a>00556 container-&gt;iterator = instances-&gt;end();
573
+ <a name="l00557"></a>00557 container-&gt;iterator--;
574
+ <a name="l00558"></a>00558 count++;
575
+ <a name="l00559"></a>00559 active++;
576
+ <a name="l00560"></a>00560 activeOrMaxChanged.notify_all();
577
+ <a name="l00561"></a>00561 }
578
+ <a name="l00562"></a>00562 } <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) {
579
+ <a name="l00563"></a>00563 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot spawn application '"</span>);
580
+ <a name="l00564"></a>00564 message.append(appRoot);
581
+ <a name="l00565"></a>00565 message.append(<span class="stringliteral">"': "</span>);
582
+ <a name="l00566"></a>00566 message.append(e.<a class="code" href="classPassenger_1_1SpawnException.html#d2da180f89a43423a4b37248249972ff">what</a>());
583
+ <a name="l00567"></a>00567 <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>()) {
584
+ <a name="l00568"></a>00568 <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>());
585
+ <a name="l00569"></a>00569 } <span class="keywordflow">else</span> {
586
+ <a name="l00570"></a>00570 <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);
587
+ <a name="l00571"></a>00571 }
588
+ <a name="l00572"></a>00572 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> exception &amp;e) {
589
+ <a name="l00573"></a>00573 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot spawn application '"</span>);
590
+ <a name="l00574"></a>00574 message.append(appRoot);
591
+ <a name="l00575"></a>00575 message.append(<span class="stringliteral">"': "</span>);
592
+ <a name="l00576"></a>00576 message.append(e.what());
593
+ <a name="l00577"></a>00577 <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);
594
+ <a name="l00578"></a>00578 }
595
+ <a name="l00579"></a>00579
596
+ <a name="l00580"></a>00580 <span class="keywordflow">return</span> make_pair(container, domain);
597
+ <a name="l00581"></a>00581 }
598
+ <a name="l00582"></a>00582
599
+ <a name="l00583"></a>00583 <span class="keyword">public</span>:<span class="comment"></span>
600
+ <a name="l00584"></a>00584 <span class="comment"> /**</span>
601
+ <a name="l00585"></a>00585 <span class="comment"> * Create a new StandardApplicationPool object.</span>
602
+ <a name="l00586"></a>00586 <span class="comment"> *</span>
603
+ <a name="l00587"></a>00587 <span class="comment"> * @param spawnServerCommand The filename of the spawn server to use.</span>
604
+ <a name="l00588"></a>00588 <span class="comment"> * @param logFile Specify a log file that the spawn server should use.</span>
605
+ <a name="l00589"></a>00589 <span class="comment"> * Messages on its standard output and standard error channels</span>
606
+ <a name="l00590"></a>00590 <span class="comment"> * will be written to this log file. If an empty string is</span>
607
+ <a name="l00591"></a>00591 <span class="comment"> * specified, no log file will be used, and the spawn server</span>
608
+ <a name="l00592"></a>00592 <span class="comment"> * will use the same standard output/error channels as the</span>
609
+ <a name="l00593"></a>00593 <span class="comment"> * current process.</span>
610
+ <a name="l00594"></a>00594 <span class="comment"> * @param rubyCommand The Ruby interpreter's command.</span>
611
+ <a name="l00595"></a>00595 <span class="comment"> * @param user The user that the spawn manager should run as. This</span>
612
+ <a name="l00596"></a>00596 <span class="comment"> * parameter only has effect if the current process is</span>
613
+ <a name="l00597"></a>00597 <span class="comment"> * running as root. If the empty string is given, or if</span>
614
+ <a name="l00598"></a>00598 <span class="comment"> * the &lt;tt&gt;user&lt;/tt&gt; is not a valid username, then</span>
615
+ <a name="l00599"></a>00599 <span class="comment"> * the spawn manager will be run as the current user.</span>
616
+ <a name="l00600"></a>00600 <span class="comment"> * @throws SystemException An error occured while trying to setup the spawn server.</span>
617
+ <a name="l00601"></a>00601 <span class="comment"> * @throws IOException The specified log file could not be opened.</span>
618
+ <a name="l00602"></a>00602 <span class="comment"> */</span>
619
+ <a name="l00603"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#f175704fc477f37ba1d387be09fa2e6b">00603</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,
620
+ <a name="l00604"></a>00604 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;logFile = <span class="stringliteral">""</span>,
621
+ <a name="l00605"></a>00605 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;rubyCommand = <span class="stringliteral">"ruby"</span>,
622
+ <a name="l00606"></a>00606 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;user = <span class="stringliteral">""</span>)
623
+ <a name="l00607"></a>00607 :
624
+ <a name="l00608"></a>00608 #ifndef PASSENGER_USE_DUMMY_SPAWN_MANAGER
625
+ <a name="l00609"></a>00609 spawnManager(spawnServerCommand, logFile, rubyCommand, user),
626
+ <a name="l00610"></a>00610 #endif
627
+ <a name="l00611"></a>00611 data(new SharedData()),
628
+ <a name="l00612"></a>00612 lock(data-&gt;lock),
629
+ <a name="l00613"></a>00613 activeOrMaxChanged(data-&gt;activeOrMaxChanged),
630
+ <a name="l00614"></a>00614 domains(data-&gt;domains),
631
+ <a name="l00615"></a>00615 max(data-&gt;max),
632
+ <a name="l00616"></a>00616 count(data-&gt;count),
633
+ <a name="l00617"></a>00617 active(data-&gt;active),
634
+ <a name="l00618"></a>00618 maxPerApp(data-&gt;maxPerApp),
635
+ <a name="l00619"></a>00619 inactiveApps(data-&gt;inactiveApps),
636
+ <a name="l00620"></a>00620 appInstanceCount(data-&gt;appInstanceCount)
637
+ <a name="l00621"></a>00621 {
638
+ <a name="l00622"></a>00622 TRACE_POINT();
639
+ <a name="l00623"></a>00623 detached = <span class="keyword">false</span>;
640
+ <a name="l00624"></a>00624 done = <span class="keyword">false</span>;
641
+ <a name="l00625"></a>00625 max = DEFAULT_MAX_POOL_SIZE;
642
+ <a name="l00626"></a>00626 count = 0;
643
+ <a name="l00627"></a>00627 active = 0;
644
+ <a name="l00628"></a>00628 waitingOnGlobalQueue = 0;
645
+ <a name="l00629"></a>00629 maxPerApp = DEFAULT_MAX_INSTANCES_PER_APP;
646
+ <a name="l00630"></a>00630 maxIdleTime = DEFAULT_MAX_IDLE_TIME;
647
+ <a name="l00631"></a>00631 cleanerThread = <span class="keyword">new</span> boost::thread(
648
+ <a name="l00632"></a>00632 bind(&amp;StandardApplicationPool::cleanerThreadMainLoop, <span class="keyword">this</span>),
649
+ <a name="l00633"></a>00633 CLEANER_THREAD_STACK_SIZE
650
+ <a name="l00634"></a>00634 );
651
+ <a name="l00635"></a>00635 }
652
+ <a name="l00636"></a>00636
653
+ <a name="l00637"></a>00637 <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>() {
654
+ <a name="l00638"></a>00638 <span class="keywordflow">if</span> (!detached) {
655
+ <a name="l00639"></a>00639 this_thread::disable_interruption di;
656
+ <a name="l00640"></a>00640 {
657
+ <a name="l00641"></a>00641 boost::mutex::scoped_lock l(lock);
658
+ <a name="l00642"></a>00642 done = <span class="keyword">true</span>;
659
+ <a name="l00643"></a>00643 cleanerThreadSleeper.notify_one();
660
+ <a name="l00644"></a>00644 }
661
+ <a name="l00645"></a>00645 cleanerThread-&gt;join();
662
+ <a name="l00646"></a>00646 }
663
+ <a name="l00647"></a>00647 <span class="keyword">delete</span> cleanerThread;
664
+ <a name="l00648"></a>00648 }
665
+ <a name="l00649"></a>00649
666
+ <a name="l00650"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#5a33f0766bbcfb2a48e08fc27bd1b684">00650</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>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appRoot) {
667
+ <a name="l00651"></a>00651 <span class="keywordflow">return</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#0b206eb4eb2869423d75c042a0653c67" title="Open a new session with the application specified by PoolOptions.appRoot.">ApplicationPool::get</a>(appRoot);
668
+ <a name="l00652"></a>00652 }
669
+ <a name="l00653"></a>00653
670
+ <a name="l00654"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#ffc8f3ef8b1d925d203794d191d7fef4">00654</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>(<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) {
671
+ <a name="l00655"></a>00655 TRACE_POINT();
672
+ <a name="l00656"></a>00656 <span class="keyword">using namespace </span>boost::posix_time;
673
+ <a name="l00657"></a>00657 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> attempt = 0;
674
+ <a name="l00658"></a>00658 <span class="comment">// TODO: We should probably add a timeout to the following</span>
675
+ <a name="l00659"></a>00659 <span class="comment">// lock. This way we can fail gracefully if the server's under</span>
676
+ <a name="l00660"></a>00660 <span class="comment">// rediculous load. Though I'm not sure how much it really helps.</span>
677
+ <a name="l00661"></a>00661 unique_lock&lt;boost::mutex&gt; l(lock);
678
+ <a name="l00662"></a>00662
679
+ <a name="l00663"></a>00663 <span class="keywordflow">while</span> (<span class="keyword">true</span>) {
680
+ <a name="l00664"></a>00664 attempt++;
681
+ <a name="l00665"></a>00665
682
+ <a name="l00666"></a>00666 pair&lt;AppContainerPtr, Domain *&gt; p(
683
+ <a name="l00667"></a>00667 spawnOrUseExisting(l, options)
684
+ <a name="l00668"></a>00668 );
685
+ <a name="l00669"></a>00669 AppContainerPtr &amp;container = p.first;
686
+ <a name="l00670"></a>00670 Domain *domain = p.second;
687
+ <a name="l00671"></a>00671
688
+ <a name="l00672"></a>00672 container-&gt;lastUsed = time(NULL);
689
+ <a name="l00673"></a>00673 container-&gt;sessions++;
690
+ <a name="l00674"></a>00674
691
+ <a name="l00675"></a>00675 P_ASSERT(verifyState(), <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a>(),
692
+ <a name="l00676"></a>00676 <span class="stringliteral">"State is valid:\n"</span> &lt;&lt; <a class="code" href="classPassenger_1_1StandardApplicationPool.html#22b4149ca8256c3042fc342e681b0383" title="Returns a textual description of the internal state of the application pool.">toString</a>(<span class="keyword">false</span>));
693
+ <a name="l00677"></a>00677 <span class="keywordflow">try</span> {
694
+ <a name="l00678"></a>00678 UPDATE_TRACE_POINT();
695
+ <a name="l00679"></a>00679 <span class="keywordflow">return</span> container-&gt;app-&gt;connect(SessionCloseCallback(data, container));
696
+ <a name="l00680"></a>00680 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> exception &amp;e) {
697
+ <a name="l00681"></a>00681 container-&gt;sessions--;
698
+ <a name="l00682"></a>00682
699
+ <a name="l00683"></a>00683 AppContainerList &amp;instances(domain-&gt;instances);
700
+ <a name="l00684"></a>00684 instances.erase(container-&gt;iterator);
701
+ <a name="l00685"></a>00685 domain-&gt;size--;
702
+ <a name="l00686"></a>00686 <span class="keywordflow">if</span> (instances.empty()) {
703
+ <a name="l00687"></a>00687 domains.erase(options.<a class="code" href="structPassenger_1_1PoolOptions.html#822039d204b48d9ed49184646734acf3" title="The root directory of the application to spawn.">appRoot</a>);
704
+ <a name="l00688"></a>00688 }
705
+ <a name="l00689"></a>00689 count--;
706
+ <a name="l00690"></a>00690 active--;
707
+ <a name="l00691"></a>00691 activeOrMaxChanged.notify_all();
708
+ <a name="l00692"></a>00692 P_ASSERT(verifyState(), <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a>(),
709
+ <a name="l00693"></a>00693 <span class="stringliteral">"State is valid: "</span> &lt;&lt; <a class="code" href="classPassenger_1_1StandardApplicationPool.html#22b4149ca8256c3042fc342e681b0383" title="Returns a textual description of the internal state of the application pool.">toString</a>(<span class="keyword">false</span>));
710
+ <a name="l00694"></a>00694 <span class="keywordflow">if</span> (attempt == MAX_GET_ATTEMPTS) {
711
+ <a name="l00695"></a>00695 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot connect to an existing "</span>
712
+ <a name="l00696"></a>00696 <span class="stringliteral">"application instance for '"</span>);
713
+ <a name="l00697"></a>00697 message.append(options.<a class="code" href="structPassenger_1_1PoolOptions.html#822039d204b48d9ed49184646734acf3" title="The root directory of the application to spawn.">appRoot</a>);
714
+ <a name="l00698"></a>00698 message.append(<span class="stringliteral">"': "</span>);
715
+ <a name="l00699"></a>00699 <span class="keywordflow">try</span> {
716
+ <a name="l00700"></a>00700 <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 =
717
+ <a name="l00701"></a>00701 <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);
718
+ <a name="l00702"></a>00702 message.append(syse.<a class="code" href="classPassenger_1_1SystemException.html#0ef41d755fea2c9b1db2252e7c418dc8" title="Returns the system&amp;#39;s error message.">sys</a>());
719
+ <a name="l00703"></a>00703 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> bad_cast &amp;) {
720
+ <a name="l00704"></a>00704 message.append(e.what());
721
+ <a name="l00705"></a>00705 }
722
+ <a name="l00706"></a>00706 <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);
723
+ <a name="l00707"></a>00707 }
724
+ <a name="l00708"></a>00708 }
725
+ <a name="l00709"></a>00709 }
726
+ <a name="l00710"></a>00710 <span class="comment">// Never reached; shut up compiler warning</span>
727
+ <a name="l00711"></a>00711 <span class="keywordflow">return</span> <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">Application::SessionPtr</a>();
728
+ <a name="l00712"></a>00712 }
729
+ <a name="l00713"></a>00713
730
+ <a name="l00714"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#bcf8faeb4f431ae07ea0e20270661d08">00714</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>() {
731
+ <a name="l00715"></a>00715 boost::mutex::scoped_lock l(lock);
732
+ <a name="l00716"></a>00716 domains.clear();
733
+ <a name="l00717"></a>00717 inactiveApps.clear();
734
+ <a name="l00718"></a>00718 appInstanceCount.clear();
735
+ <a name="l00719"></a>00719 count = 0;
736
+ <a name="l00720"></a>00720 active = 0;
737
+ <a name="l00721"></a>00721 activeOrMaxChanged.notify_all();
738
738
  <a name="l00722"></a>00722 }
739
739
  <a name="l00723"></a>00723
740
- <a name="l00724"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#04ef8c92da189520ad2022f4f82e9553">00724</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) {
740
+ <a name="l00724"></a>00724 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMaxIdleTime(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> seconds) {
741
741
  <a name="l00725"></a>00725 boost::mutex::scoped_lock l(lock);
742
- <a name="l00726"></a>00726 this-&gt;max = max;
743
- <a name="l00727"></a>00727 activeOrMaxChanged.notify_all();
742
+ <a name="l00726"></a>00726 maxIdleTime = seconds;
743
+ <a name="l00727"></a>00727 cleanerThreadSleeper.notify_one();
744
744
  <a name="l00728"></a>00728 }
745
745
  <a name="l00729"></a>00729
746
- <a name="l00730"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#7773c4a3dfbd88eac72401d063831788">00730</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>{
747
- <a name="l00731"></a>00731 <span class="keywordflow">return</span> active;
748
- <a name="l00732"></a>00732 }
749
- <a name="l00733"></a>00733
750
- <a name="l00734"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#cdbfe2b9ffacdab4438c879c2411bf02">00734</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>{
751
- <a name="l00735"></a>00735 <span class="keywordflow">return</span> count;
752
- <a name="l00736"></a>00736 }
753
- <a name="l00737"></a>00737
754
- <a name="l00738"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#3bafcda8d880f70561ad8a9da16e26ef">00738</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) {
755
- <a name="l00739"></a>00739 boost::mutex::scoped_lock l(lock);
756
- <a name="l00740"></a>00740 this-&gt;maxPerApp = maxPerApp;
757
- <a name="l00741"></a>00741 activeOrMaxChanged.notify_all();
746
+ <a name="l00730"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#04ef8c92da189520ad2022f4f82e9553">00730</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) {
747
+ <a name="l00731"></a>00731 boost::mutex::scoped_lock l(lock);
748
+ <a name="l00732"></a>00732 this-&gt;max = max;
749
+ <a name="l00733"></a>00733 activeOrMaxChanged.notify_all();
750
+ <a name="l00734"></a>00734 }
751
+ <a name="l00735"></a>00735
752
+ <a name="l00736"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#7773c4a3dfbd88eac72401d063831788">00736</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>{
753
+ <a name="l00737"></a>00737 <span class="keywordflow">return</span> active;
754
+ <a name="l00738"></a>00738 }
755
+ <a name="l00739"></a>00739
756
+ <a name="l00740"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#cdbfe2b9ffacdab4438c879c2411bf02">00740</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>{
757
+ <a name="l00741"></a>00741 <span class="keywordflow">return</span> count;
758
758
  <a name="l00742"></a>00742 }
759
759
  <a name="l00743"></a>00743
760
- <a name="l00744"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#6955152d237920988d20297d2fff5660">00744</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>{
761
- <a name="l00745"></a>00745 <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>();
762
- <a name="l00746"></a>00746 }
763
- <a name="l00747"></a>00747 <span class="comment"></span>
764
- <a name="l00748"></a>00748 <span class="comment"> /**</span>
765
- <a name="l00749"></a>00749 <span class="comment"> * Returns a textual description of the internal state of</span>
766
- <a name="l00750"></a>00750 <span class="comment"> * the application pool.</span>
767
- <a name="l00751"></a>00751 <span class="comment"> */</span>
768
- <a name="l00752"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#22b4149ca8256c3042fc342e681b0383">00752</a> <span class="keyword">virtual</span> <span class="keywordtype">string</span> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#22b4149ca8256c3042fc342e681b0383" title="Returns a textual description of the internal state of the application pool.">toString</a>(<span class="keywordtype">bool</span> lockMutex = <span class="keyword">true</span>)<span class="keyword"> const </span>{
769
- <a name="l00753"></a>00753 <span class="keywordflow">if</span> (lockMutex) {
770
- <a name="l00754"></a>00754 unique_lock&lt;boost::mutex&gt; l(lock);
771
- <a name="l00755"></a>00755 <span class="keywordflow">return</span> toStringWithoutLock();
772
- <a name="l00756"></a>00756 } <span class="keywordflow">else</span> {
773
- <a name="l00757"></a>00757 <span class="keywordflow">return</span> toStringWithoutLock();
774
- <a name="l00758"></a>00758 }
775
- <a name="l00759"></a>00759 }
776
- <a name="l00760"></a>00760 <span class="comment"></span>
777
- <a name="l00761"></a>00761 <span class="comment"> /**</span>
778
- <a name="l00762"></a>00762 <span class="comment"> * Returns an XML description of the internal state of the</span>
779
- <a name="l00763"></a>00763 <span class="comment"> * application pool.</span>
780
- <a name="l00764"></a>00764 <span class="comment"> */</span>
781
- <a name="l00765"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#d153c41a1d0aca91d17cf36ed6fdda19">00765</a> <span class="keyword">virtual</span> <span class="keywordtype">string</span> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#d153c41a1d0aca91d17cf36ed6fdda19" title="Returns an XML description of the internal state of the application pool.">toXml</a>()<span class="keyword"> const </span>{
782
- <a name="l00766"></a>00766 unique_lock&lt;boost::mutex&gt; l(lock);
783
- <a name="l00767"></a>00767 stringstream result;
784
- <a name="l00768"></a>00768 DomainMap::const_iterator it;
785
- <a name="l00769"></a>00769
786
- <a name="l00770"></a>00770 result &lt;&lt; <span class="stringliteral">"&lt;?xml version=\"1.0\" encoding=\"iso8859-1\" ?&gt;\n"</span>;
787
- <a name="l00771"></a>00771 result &lt;&lt; <span class="stringliteral">"&lt;info&gt;"</span>;
788
- <a name="l00772"></a>00772
789
- <a name="l00773"></a>00773 result &lt;&lt; <span class="stringliteral">"&lt;domains&gt;"</span>;
790
- <a name="l00774"></a>00774 <span class="keywordflow">for</span> (it = domains.begin(); it != domains.end(); it++) {
791
- <a name="l00775"></a>00775 Domain *domain = it-&gt;second.get();
792
- <a name="l00776"></a>00776 AppContainerList *instances = &amp;domain-&gt;instances;
793
- <a name="l00777"></a>00777 AppContainerList::const_iterator lit;
794
- <a name="l00778"></a>00778
795
- <a name="l00779"></a>00779 result &lt;&lt; <span class="stringliteral">"&lt;domain&gt;"</span>;
796
- <a name="l00780"></a>00780 result &lt;&lt; <span class="stringliteral">"&lt;name&gt;"</span> &lt;&lt; <a class="code" href="group__Support.html#ge74addedf73782a1eb1f6dd48d6fce06" title="Escape the given raw string into an XML value.">escapeForXml</a>(it-&gt;first) &lt;&lt; <span class="stringliteral">"&lt;/name&gt;"</span>;
797
- <a name="l00781"></a>00781
798
- <a name="l00782"></a>00782 result &lt;&lt; <span class="stringliteral">"&lt;instances&gt;"</span>;
799
- <a name="l00783"></a>00783 <span class="keywordflow">for</span> (lit = instances-&gt;begin(); lit != instances-&gt;end(); lit++) {
800
- <a name="l00784"></a>00784 AppContainer *container = lit-&gt;get();
801
- <a name="l00785"></a>00785
802
- <a name="l00786"></a>00786 result &lt;&lt; <span class="stringliteral">"&lt;instance&gt;"</span>;
803
- <a name="l00787"></a>00787 result &lt;&lt; <span class="stringliteral">"&lt;pid&gt;"</span> &lt;&lt; container-&gt;app-&gt;getPid() &lt;&lt; <span class="stringliteral">"&lt;/pid&gt;"</span>;
804
- <a name="l00788"></a>00788 result &lt;&lt; <span class="stringliteral">"&lt;sessions&gt;"</span> &lt;&lt; container-&gt;sessions &lt;&lt; <span class="stringliteral">"&lt;/sessions&gt;"</span>;
805
- <a name="l00789"></a>00789 result &lt;&lt; <span class="stringliteral">"&lt;processed&gt;"</span> &lt;&lt; container-&gt;processed &lt;&lt; <span class="stringliteral">"&lt;/processed&gt;"</span>;
806
- <a name="l00790"></a>00790 result &lt;&lt; <span class="stringliteral">"&lt;uptime&gt;"</span> &lt;&lt; container-&gt;uptime() &lt;&lt; <span class="stringliteral">"&lt;/uptime&gt;"</span>;
807
- <a name="l00791"></a>00791 result &lt;&lt; <span class="stringliteral">"&lt;/instance&gt;"</span>;
808
- <a name="l00792"></a>00792 }
809
- <a name="l00793"></a>00793 result &lt;&lt; <span class="stringliteral">"&lt;/instances&gt;"</span>;
810
- <a name="l00794"></a>00794
811
- <a name="l00795"></a>00795 result &lt;&lt; <span class="stringliteral">"&lt;/domain&gt;"</span>;
812
- <a name="l00796"></a>00796 }
813
- <a name="l00797"></a>00797 result &lt;&lt; <span class="stringliteral">"&lt;/domains&gt;"</span>;
814
- <a name="l00798"></a>00798
815
- <a name="l00799"></a>00799 result &lt;&lt; <span class="stringliteral">"&lt;/info&gt;"</span>;
816
- <a name="l00800"></a>00800 <span class="keywordflow">return</span> result.str();
817
- <a name="l00801"></a>00801 }
818
- <a name="l00802"></a>00802 };
819
- <a name="l00803"></a>00803
820
- <a name="l00804"></a>00804 <span class="keyword">typedef</span> shared_ptr&lt;StandardApplicationPool&gt; StandardApplicationPoolPtr;
821
- <a name="l00805"></a>00805
822
- <a name="l00806"></a>00806 } <span class="comment">// namespace Passenger</span>
823
- <a name="l00807"></a>00807
824
- <a name="l00808"></a>00808 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_STANDARD_APPLICATION_POOL_H_ */</span>
760
+ <a name="l00744"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#3bafcda8d880f70561ad8a9da16e26ef">00744</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) {
761
+ <a name="l00745"></a>00745 boost::mutex::scoped_lock l(lock);
762
+ <a name="l00746"></a>00746 this-&gt;maxPerApp = maxPerApp;
763
+ <a name="l00747"></a>00747 activeOrMaxChanged.notify_all();
764
+ <a name="l00748"></a>00748 }
765
+ <a name="l00749"></a>00749
766
+ <a name="l00750"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#6955152d237920988d20297d2fff5660">00750</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>{
767
+ <a name="l00751"></a>00751 <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>();
768
+ <a name="l00752"></a>00752 }
769
+ <a name="l00753"></a>00753 <span class="comment"></span>
770
+ <a name="l00754"></a>00754 <span class="comment"> /**</span>
771
+ <a name="l00755"></a>00755 <span class="comment"> * Returns a textual description of the internal state of</span>
772
+ <a name="l00756"></a>00756 <span class="comment"> * the application pool.</span>
773
+ <a name="l00757"></a>00757 <span class="comment"> */</span>
774
+ <a name="l00758"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#22b4149ca8256c3042fc342e681b0383">00758</a> <span class="keyword">virtual</span> <span class="keywordtype">string</span> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#22b4149ca8256c3042fc342e681b0383" title="Returns a textual description of the internal state of the application pool.">toString</a>(<span class="keywordtype">bool</span> lockMutex = <span class="keyword">true</span>)<span class="keyword"> const </span>{
775
+ <a name="l00759"></a>00759 <span class="keywordflow">if</span> (lockMutex) {
776
+ <a name="l00760"></a>00760 unique_lock&lt;boost::mutex&gt; l(lock);
777
+ <a name="l00761"></a>00761 <span class="keywordflow">return</span> toStringWithoutLock();
778
+ <a name="l00762"></a>00762 } <span class="keywordflow">else</span> {
779
+ <a name="l00763"></a>00763 <span class="keywordflow">return</span> toStringWithoutLock();
780
+ <a name="l00764"></a>00764 }
781
+ <a name="l00765"></a>00765 }
782
+ <a name="l00766"></a>00766 <span class="comment"></span>
783
+ <a name="l00767"></a>00767 <span class="comment"> /**</span>
784
+ <a name="l00768"></a>00768 <span class="comment"> * Returns an XML description of the internal state of the</span>
785
+ <a name="l00769"></a>00769 <span class="comment"> * application pool.</span>
786
+ <a name="l00770"></a>00770 <span class="comment"> */</span>
787
+ <a name="l00771"></a><a class="code" href="classPassenger_1_1StandardApplicationPool.html#d153c41a1d0aca91d17cf36ed6fdda19">00771</a> <span class="keyword">virtual</span> <span class="keywordtype">string</span> <a class="code" href="classPassenger_1_1StandardApplicationPool.html#d153c41a1d0aca91d17cf36ed6fdda19" title="Returns an XML description of the internal state of the application pool.">toXml</a>()<span class="keyword"> const </span>{
788
+ <a name="l00772"></a>00772 unique_lock&lt;boost::mutex&gt; l(lock);
789
+ <a name="l00773"></a>00773 stringstream result;
790
+ <a name="l00774"></a>00774 DomainMap::const_iterator it;
791
+ <a name="l00775"></a>00775
792
+ <a name="l00776"></a>00776 result &lt;&lt; <span class="stringliteral">"&lt;?xml version=\"1.0\" encoding=\"iso8859-1\" ?&gt;\n"</span>;
793
+ <a name="l00777"></a>00777 result &lt;&lt; <span class="stringliteral">"&lt;info&gt;"</span>;
794
+ <a name="l00778"></a>00778
795
+ <a name="l00779"></a>00779 result &lt;&lt; <span class="stringliteral">"&lt;domains&gt;"</span>;
796
+ <a name="l00780"></a>00780 <span class="keywordflow">for</span> (it = domains.begin(); it != domains.end(); it++) {
797
+ <a name="l00781"></a>00781 Domain *domain = it-&gt;second.get();
798
+ <a name="l00782"></a>00782 AppContainerList *instances = &amp;domain-&gt;instances;
799
+ <a name="l00783"></a>00783 AppContainerList::const_iterator lit;
800
+ <a name="l00784"></a>00784
801
+ <a name="l00785"></a>00785 result &lt;&lt; <span class="stringliteral">"&lt;domain&gt;"</span>;
802
+ <a name="l00786"></a>00786 result &lt;&lt; <span class="stringliteral">"&lt;name&gt;"</span> &lt;&lt; <a class="code" href="group__Support.html#ge74addedf73782a1eb1f6dd48d6fce06" title="Escape the given raw string into an XML value.">escapeForXml</a>(it-&gt;first) &lt;&lt; <span class="stringliteral">"&lt;/name&gt;"</span>;
803
+ <a name="l00787"></a>00787
804
+ <a name="l00788"></a>00788 result &lt;&lt; <span class="stringliteral">"&lt;instances&gt;"</span>;
805
+ <a name="l00789"></a>00789 <span class="keywordflow">for</span> (lit = instances-&gt;begin(); lit != instances-&gt;end(); lit++) {
806
+ <a name="l00790"></a>00790 AppContainer *container = lit-&gt;get();
807
+ <a name="l00791"></a>00791
808
+ <a name="l00792"></a>00792 result &lt;&lt; <span class="stringliteral">"&lt;instance&gt;"</span>;
809
+ <a name="l00793"></a>00793 result &lt;&lt; <span class="stringliteral">"&lt;pid&gt;"</span> &lt;&lt; container-&gt;app-&gt;getPid() &lt;&lt; <span class="stringliteral">"&lt;/pid&gt;"</span>;
810
+ <a name="l00794"></a>00794 result &lt;&lt; <span class="stringliteral">"&lt;sessions&gt;"</span> &lt;&lt; container-&gt;sessions &lt;&lt; <span class="stringliteral">"&lt;/sessions&gt;"</span>;
811
+ <a name="l00795"></a>00795 result &lt;&lt; <span class="stringliteral">"&lt;processed&gt;"</span> &lt;&lt; container-&gt;processed &lt;&lt; <span class="stringliteral">"&lt;/processed&gt;"</span>;
812
+ <a name="l00796"></a>00796 result &lt;&lt; <span class="stringliteral">"&lt;uptime&gt;"</span> &lt;&lt; container-&gt;uptime() &lt;&lt; <span class="stringliteral">"&lt;/uptime&gt;"</span>;
813
+ <a name="l00797"></a>00797 result &lt;&lt; <span class="stringliteral">"&lt;/instance&gt;"</span>;
814
+ <a name="l00798"></a>00798 }
815
+ <a name="l00799"></a>00799 result &lt;&lt; <span class="stringliteral">"&lt;/instances&gt;"</span>;
816
+ <a name="l00800"></a>00800
817
+ <a name="l00801"></a>00801 result &lt;&lt; <span class="stringliteral">"&lt;/domain&gt;"</span>;
818
+ <a name="l00802"></a>00802 }
819
+ <a name="l00803"></a>00803 result &lt;&lt; <span class="stringliteral">"&lt;/domains&gt;"</span>;
820
+ <a name="l00804"></a>00804
821
+ <a name="l00805"></a>00805 result &lt;&lt; <span class="stringliteral">"&lt;/info&gt;"</span>;
822
+ <a name="l00806"></a>00806 <span class="keywordflow">return</span> result.str();
823
+ <a name="l00807"></a>00807 }
824
+ <a name="l00808"></a>00808 };
825
825
  <a name="l00809"></a>00809
826
+ <a name="l00810"></a>00810 <span class="keyword">typedef</span> shared_ptr&lt;StandardApplicationPool&gt; StandardApplicationPoolPtr;
827
+ <a name="l00811"></a>00811
828
+ <a name="l00812"></a>00812 } <span class="comment">// namespace Passenger</span>
829
+ <a name="l00813"></a>00813
830
+ <a name="l00814"></a>00814 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_STANDARD_APPLICATION_POOL_H_ */</span>
831
+ <a name="l00815"></a>00815
826
832
  </pre></div></div>
827
- <hr size="1"><address style="text-align: right;"><small>Generated on Fri Mar 13 19:24:32 2009 for Passenger by&nbsp;
833
+ <hr size="1"><address style="text-align: right;"><small>Generated on Tue Mar 31 14:00:28 2009 for Passenger by&nbsp;
828
834
  <a href="http://www.doxygen.org/index.html">
829
835
  <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
830
836
  </body>