passenger 2.0.6 → 2.1.2

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

Potentially problematic release.


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

Files changed (497) hide show
  1. data/DEVELOPERS.TXT +10 -4
  2. data/LICENSE +1 -1
  3. data/NEWS +0 -0
  4. data/Rakefile +183 -117
  5. data/benchmark/dispatcher.rb +5 -9
  6. data/bin/passenger-install-apache2-module +52 -18
  7. data/bin/passenger-memory-stats +67 -13
  8. data/bin/passenger-spawn-server +8 -4
  9. data/bin/passenger-status +21 -46
  10. data/bin/passenger-stress-test +5 -5
  11. data/debian/postinst +1 -1
  12. data/doc/ApplicationPool algorithm.txt +180 -128
  13. data/doc/Architectural overview.html +1 -778
  14. data/doc/Security of user switching support.html +1 -643
  15. data/doc/Users guide Apache.html +3127 -0
  16. data/doc/Users guide Nginx.html +1458 -0
  17. data/doc/Users guide.html +1404 -467
  18. data/doc/Users guide.txt +843 -105
  19. data/doc/cxxapi/ApplicationPoolServer_8h-source.html +751 -641
  20. data/doc/cxxapi/ApplicationPool_8h-source.html +168 -171
  21. data/doc/cxxapi/Application_8h-source.html +494 -394
  22. data/doc/cxxapi/Bucket_8h-source.html +21 -15
  23. data/doc/cxxapi/CachedFileStat_8h-source.html +191 -0
  24. data/doc/cxxapi/Configuration_8h-source.html +311 -149
  25. data/doc/cxxapi/DirectoryMapper_8h-source.html +309 -0
  26. data/doc/cxxapi/DummySpawnManager_8h-source.html +3 -4
  27. data/doc/cxxapi/Exceptions_8h-source.html +182 -165
  28. data/doc/cxxapi/FileChecker_8h-source.html +130 -0
  29. data/doc/cxxapi/Hooks_8h-source.html +2 -3
  30. data/doc/cxxapi/Logging_8h-source.html +92 -89
  31. data/doc/cxxapi/MessageChannel_8h-source.html +585 -477
  32. data/doc/cxxapi/PoolOptions_8h-source.html +305 -0
  33. data/doc/cxxapi/SpawnManager_8h-source.html +515 -540
  34. data/doc/cxxapi/StandardApplicationPool_8h-source.html +779 -679
  35. data/doc/cxxapi/SystemTime_8h-source.html +104 -0
  36. data/doc/cxxapi/Utils_8h-source.html +331 -227
  37. data/doc/cxxapi/annotated.html +6 -7
  38. data/doc/cxxapi/classClient-members.html +1 -2
  39. data/doc/cxxapi/classClient.html +1 -2
  40. data/doc/cxxapi/classHooks-members.html +5 -2
  41. data/doc/cxxapi/classHooks.html +112 -2
  42. data/doc/cxxapi/classPassenger_1_1Application-members.html +2 -3
  43. data/doc/cxxapi/classPassenger_1_1Application.html +8 -9
  44. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +4 -4
  45. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +42 -81
  46. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -2
  47. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +3 -4
  48. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
  49. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +3 -2
  50. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +74 -3
  51. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +1 -2
  52. data/doc/cxxapi/classPassenger_1_1BusyException.html +2 -3
  53. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +1 -2
  54. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +2 -3
  55. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +38 -0
  56. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +256 -0
  57. data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -2
  58. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +2 -3
  59. data/doc/cxxapi/{classPassenger_1_1Thread-members.html → classPassenger_1_1FileChecker-members.html} +4 -5
  60. data/doc/cxxapi/classPassenger_1_1FileChecker.html +121 -0
  61. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -2
  62. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +2 -3
  63. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  64. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +2 -3
  65. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +2 -3
  66. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  67. data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -2
  68. data/doc/cxxapi/classPassenger_1_1IOException.html +2 -3
  69. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  70. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +5 -2
  71. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +155 -5
  72. data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption-members.html → classPassenger_1_1RuntimeException-members.html} +2 -3
  73. data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption.html → classPassenger_1_1RuntimeException.html} +10 -8
  74. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -2
  75. data/doc/cxxapi/classPassenger_1_1SpawnException.html +2 -3
  76. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +2 -3
  77. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +15 -56
  78. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +5 -4
  79. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +20 -81
  80. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
  81. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +2 -3
  82. data/doc/cxxapi/classPassenger_1_1SystemException.html +9 -10
  83. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  84. data/doc/cxxapi/{classboost_1_1this__thread_1_1disable__syscall__interruption-members.html → classPassenger_1_1SystemTime-members.html} +5 -3
  85. data/doc/cxxapi/classPassenger_1_1SystemTime.html +86 -0
  86. data/doc/cxxapi/classPassenger_1_1TempFile-members.html +2 -3
  87. data/doc/cxxapi/classPassenger_1_1TempFile.html +17 -9
  88. data/doc/cxxapi/definitions_8h-source.html +1 -2
  89. data/doc/cxxapi/files.html +6 -3
  90. data/doc/cxxapi/functions.html +98 -35
  91. data/doc/cxxapi/functions_func.html +60 -32
  92. data/doc/cxxapi/functions_type.html +1 -2
  93. data/doc/cxxapi/functions_vars.html +27 -2
  94. data/doc/cxxapi/graph_legend.html +1 -2
  95. data/doc/cxxapi/graph_legend.png +0 -0
  96. data/doc/cxxapi/group__Configuration.html +3 -4
  97. data/doc/cxxapi/group__Configuration.png +0 -0
  98. data/doc/cxxapi/group__Core.html +3 -4
  99. data/doc/cxxapi/group__Core.png +0 -0
  100. data/doc/cxxapi/group__Exceptions.html +4 -2
  101. data/doc/cxxapi/group__Hooks.html +1 -6
  102. data/doc/cxxapi/group__Hooks.png +0 -0
  103. data/doc/cxxapi/group__Support.html +259 -36
  104. data/doc/cxxapi/hierarchy.html +6 -7
  105. data/doc/cxxapi/inherit__graph__0.map +1 -1
  106. data/doc/cxxapi/inherit__graph__0.md5 +1 -1
  107. data/doc/cxxapi/inherit__graph__0.png +0 -0
  108. data/doc/cxxapi/inherit__graph__1.map +1 -1
  109. data/doc/cxxapi/inherit__graph__1.md5 +1 -1
  110. data/doc/cxxapi/inherit__graph__1.png +0 -0
  111. data/doc/cxxapi/inherit__graph__10.map +1 -1
  112. data/doc/cxxapi/inherit__graph__10.md5 +1 -1
  113. data/doc/cxxapi/inherit__graph__10.png +0 -0
  114. data/doc/cxxapi/inherit__graph__11.map +1 -1
  115. data/doc/cxxapi/inherit__graph__11.md5 +1 -1
  116. data/doc/cxxapi/inherit__graph__11.png +0 -0
  117. data/doc/cxxapi/inherit__graph__12.map +2 -1
  118. data/doc/cxxapi/inherit__graph__12.md5 +1 -1
  119. data/doc/cxxapi/inherit__graph__12.png +0 -0
  120. data/doc/cxxapi/inherit__graph__13.map +1 -1
  121. data/doc/cxxapi/inherit__graph__13.md5 +1 -1
  122. data/doc/cxxapi/inherit__graph__13.png +0 -0
  123. data/doc/cxxapi/inherit__graph__14.map +1 -2
  124. data/doc/cxxapi/inherit__graph__14.md5 +1 -1
  125. data/doc/cxxapi/inherit__graph__14.png +0 -0
  126. data/doc/cxxapi/inherit__graph__15.map +1 -1
  127. data/doc/cxxapi/inherit__graph__15.md5 +1 -1
  128. data/doc/cxxapi/inherit__graph__15.png +0 -0
  129. data/doc/cxxapi/inherit__graph__16.map +1 -1
  130. data/doc/cxxapi/inherit__graph__16.md5 +1 -1
  131. data/doc/cxxapi/inherit__graph__16.png +0 -0
  132. data/doc/cxxapi/inherit__graph__17.png +0 -0
  133. data/doc/cxxapi/inherit__graph__18.png +0 -0
  134. data/doc/cxxapi/inherit__graph__19.png +0 -0
  135. data/doc/cxxapi/inherit__graph__2.map +1 -1
  136. data/doc/cxxapi/inherit__graph__2.md5 +1 -1
  137. data/doc/cxxapi/inherit__graph__2.png +0 -0
  138. data/doc/cxxapi/inherit__graph__20.map +1 -1
  139. data/doc/cxxapi/inherit__graph__20.md5 +1 -1
  140. data/doc/cxxapi/inherit__graph__20.png +0 -0
  141. data/doc/cxxapi/inherit__graph__21.map +1 -1
  142. data/doc/cxxapi/inherit__graph__21.md5 +1 -1
  143. data/doc/cxxapi/inherit__graph__21.png +0 -0
  144. data/doc/cxxapi/inherit__graph__3.map +1 -1
  145. data/doc/cxxapi/inherit__graph__3.md5 +1 -1
  146. data/doc/cxxapi/inherit__graph__3.png +0 -0
  147. data/doc/cxxapi/inherit__graph__4.map +1 -1
  148. data/doc/cxxapi/inherit__graph__4.md5 +1 -1
  149. data/doc/cxxapi/inherit__graph__4.png +0 -0
  150. data/doc/cxxapi/inherit__graph__5.map +2 -1
  151. data/doc/cxxapi/inherit__graph__5.md5 +1 -1
  152. data/doc/cxxapi/inherit__graph__5.png +0 -0
  153. data/doc/cxxapi/inherit__graph__6.map +1 -1
  154. data/doc/cxxapi/inherit__graph__6.md5 +1 -1
  155. data/doc/cxxapi/inherit__graph__6.png +0 -0
  156. data/doc/cxxapi/inherit__graph__7.map +1 -1
  157. data/doc/cxxapi/inherit__graph__7.md5 +1 -1
  158. data/doc/cxxapi/inherit__graph__7.png +0 -0
  159. data/doc/cxxapi/inherit__graph__8.map +1 -1
  160. data/doc/cxxapi/inherit__graph__8.md5 +1 -1
  161. data/doc/cxxapi/inherit__graph__8.png +0 -0
  162. data/doc/cxxapi/inherit__graph__9.map +1 -2
  163. data/doc/cxxapi/inherit__graph__9.md5 +1 -1
  164. data/doc/cxxapi/inherit__graph__9.png +0 -0
  165. data/doc/cxxapi/inherits.html +30 -31
  166. data/doc/cxxapi/main.html +1 -2
  167. data/doc/cxxapi/modules.html +1 -2
  168. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -2
  169. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +2 -3
  170. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -2
  171. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +2 -3
  172. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +49 -0
  173. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +404 -0
  174. data/doc/cxxapi/tree.html +18 -20
  175. data/doc/images/conservative_spawning.png +0 -0
  176. data/doc/images/conservative_spawning.svg +248 -0
  177. data/doc/images/smart-lv2.png +0 -0
  178. data/doc/images/smart-lv2.svg +320 -0
  179. data/doc/rdoc/classes/ConditionVariable.html +68 -34
  180. data/doc/rdoc/classes/Exception.html +16 -16
  181. data/doc/rdoc/classes/GC.html +9 -9
  182. data/doc/rdoc/classes/IO.html +36 -17
  183. data/doc/rdoc/classes/PhusionPassenger.html +183 -0
  184. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +511 -0
  185. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer.html +285 -242
  186. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerAlreadyStarted.html +3 -3
  187. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerError.html +3 -3
  188. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerNotStarted.html +3 -3
  189. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/UnknownMessage.html +3 -3
  190. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
  191. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
  192. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +247 -0
  193. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
  194. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AppInitError.html +36 -19
  195. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/Application.html +81 -96
  196. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/ConsoleTextTemplate.html +18 -18
  197. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/FrameworkInitError.html +20 -18
  198. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/HTMLTemplate.html +18 -18
  199. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/InitializationError.html +9 -9
  200. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
  201. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/MessageChannel.html +93 -92
  202. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/NativeSupport.html +55 -25
  203. data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
  204. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +185 -0
  205. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +182 -0
  206. data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
  207. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +424 -0
  208. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
  209. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
  210. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +444 -0
  211. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
  212. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +154 -0
  213. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +408 -0
  214. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/UnknownError.html +13 -13
  215. data/doc/rdoc/classes/PhusionPassenger/Utils.html +687 -0
  216. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/VersionNotFound.html +8 -8
  217. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
  218. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
  219. data/doc/rdoc/classes/PlatformInfo.html +663 -159
  220. data/doc/rdoc/classes/RakeExtensions.html +4 -4
  221. data/doc/rdoc/classes/Signal.html +134 -0
  222. data/doc/rdoc/created.rid +1 -1
  223. data/doc/rdoc/files/DEVELOPERS_TXT.html +15 -10
  224. data/doc/rdoc/files/README.html +5 -7
  225. data/doc/rdoc/files/ext/{passenger → phusion_passenger}/native_support_c.html +2 -2
  226. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_request_handler_rb.html +7 -9
  227. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +120 -0
  228. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_server_rb.html +7 -10
  229. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +99 -0
  230. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +92 -0
  231. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/application_rb.html +6 -8
  232. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/console_text_template_rb.html +5 -7
  233. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/constants_rb.html +4 -5
  234. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/dependencies_rb.html +6 -8
  235. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +116 -0
  236. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/exceptions_rb.html +5 -7
  237. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/html_template_rb.html +5 -7
  238. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/message_channel_rb.html +5 -7
  239. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/platform_info_rb.html +6 -7
  240. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +123 -0
  241. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +117 -0
  242. data/doc/rdoc/files/lib/{passenger/utils_rb.html → phusion_passenger/railz/application_spawner_rb.html} +24 -17
  243. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
  244. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +139 -0
  245. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +118 -0
  246. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/simple_benchmarking_rb.html +5 -7
  247. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/spawn_manager_rb.html +40 -24
  248. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +169 -0
  249. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +120 -0
  250. data/doc/rdoc/files/lib/rake/extensions_rb.html +3 -4
  251. data/doc/rdoc/fr_class_index.html +37 -19
  252. data/doc/rdoc/fr_file_index.html +25 -14
  253. data/doc/rdoc/fr_method_index.html +145 -74
  254. data/ext/apache2/Application.h +145 -44
  255. data/ext/apache2/ApplicationPool.h +27 -29
  256. data/ext/apache2/ApplicationPoolServer.h +183 -72
  257. data/ext/apache2/ApplicationPoolServerExecutable.cpp +249 -42
  258. data/ext/apache2/Bucket.cpp +61 -9
  259. data/ext/apache2/Bucket.h +15 -8
  260. data/ext/apache2/CachedFileStat.cpp +114 -0
  261. data/ext/apache2/CachedFileStat.h +169 -0
  262. data/ext/apache2/Configuration.cpp +213 -22
  263. data/ext/apache2/Configuration.h +176 -13
  264. data/ext/apache2/DirectoryMapper.h +287 -0
  265. data/ext/apache2/Exceptions.h +30 -12
  266. data/ext/apache2/FileChecker.h +108 -0
  267. data/ext/apache2/Hooks.cpp +709 -493
  268. data/ext/apache2/LICENSE-CNRI.TXT +15 -0
  269. data/ext/apache2/Logging.h +26 -22
  270. data/ext/apache2/MessageChannel.h +124 -15
  271. data/ext/apache2/PoolOptions.h +283 -0
  272. data/ext/apache2/SpawnManager.h +75 -99
  273. data/ext/apache2/StandardApplicationPool.h +296 -195
  274. data/ext/apache2/SystemTime.cpp +28 -0
  275. data/ext/apache2/SystemTime.h +82 -0
  276. data/ext/apache2/Utils.cpp +172 -18
  277. data/ext/apache2/Utils.h +124 -19
  278. data/ext/boost/cstdint.hpp +4 -2
  279. data/ext/boost/current_function.hpp +67 -0
  280. data/ext/boost/detail/sp_counted_base.hpp +4 -4
  281. data/ext/boost/thread/exceptions.hpp +2 -1
  282. data/ext/boost/thread/pthread/thread.hpp +11 -3
  283. data/ext/boost/thread/pthread/thread_data.hpp +2 -1
  284. data/ext/oxt/backtrace.cpp +172 -0
  285. data/ext/oxt/backtrace.hpp +135 -0
  286. data/ext/oxt/detail/backtrace_disabled.hpp +39 -0
  287. data/ext/oxt/detail/backtrace_enabled.hpp +155 -0
  288. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +82 -0
  289. data/ext/oxt/detail/spin_lock_portable.hpp +38 -0
  290. data/ext/oxt/detail/spin_lock_pthreads.hpp +97 -0
  291. data/ext/oxt/detail/tracable_exception_disabled.hpp +46 -0
  292. data/ext/oxt/detail/tracable_exception_enabled.hpp +48 -0
  293. data/ext/oxt/macros.hpp +58 -0
  294. data/ext/oxt/spin_lock.hpp +55 -0
  295. data/ext/{apache2/System.cpp → oxt/system_calls.cpp} +87 -52
  296. data/ext/oxt/system_calls.hpp +234 -0
  297. data/ext/oxt/thread.cpp +32 -0
  298. data/ext/oxt/thread.hpp +223 -0
  299. data/ext/oxt/tracable_exception.cpp +87 -0
  300. data/ext/oxt/tracable_exception.hpp +35 -0
  301. data/{lib/passenger/constants.rb → ext/phusion_passenger/extconf.rb} +14 -9
  302. data/ext/{passenger → phusion_passenger}/native_support.c +33 -6
  303. data/lib/{passenger → phusion_passenger}/abstract_request_handler.rb +209 -93
  304. data/lib/{passenger → phusion_passenger}/abstract_server.rb +23 -8
  305. data/lib/phusion_passenger/abstract_server_collection.rb +301 -0
  306. data/lib/phusion_passenger/admin_tools.rb +25 -0
  307. data/lib/phusion_passenger/admin_tools/control_process.rb +107 -0
  308. data/lib/{passenger → phusion_passenger}/application.rb +13 -16
  309. data/lib/{passenger → phusion_passenger}/console_text_template.rb +2 -2
  310. data/{ext/passenger/extconf.rb → lib/phusion_passenger/constants.rb} +5 -5
  311. data/lib/{passenger → phusion_passenger}/dependencies.rb +38 -32
  312. data/lib/phusion_passenger/events.rb +45 -0
  313. data/lib/{passenger → phusion_passenger}/exceptions.rb +12 -5
  314. data/lib/{passenger → phusion_passenger}/html_template.rb +2 -2
  315. data/lib/{passenger → phusion_passenger}/message_channel.rb +3 -2
  316. data/lib/phusion_passenger/platform_info.rb +500 -0
  317. data/lib/{passenger → phusion_passenger}/rack/application_spawner.rb +29 -22
  318. data/lib/{passenger → phusion_passenger}/rack/request_handler.rb +14 -9
  319. data/lib/{passenger → phusion_passenger}/railz/application_spawner.rb +94 -74
  320. data/lib/{passenger → phusion_passenger}/railz/cgi_fixed.rb +2 -2
  321. data/lib/{passenger → phusion_passenger}/railz/framework_spawner.rb +86 -98
  322. data/lib/{passenger → phusion_passenger}/railz/request_handler.rb +6 -6
  323. data/lib/{passenger → phusion_passenger}/simple_benchmarking.rb +0 -0
  324. data/lib/{passenger → phusion_passenger}/spawn_manager.rb +136 -128
  325. data/lib/{passenger → phusion_passenger}/templates/apache2_config_snippets.txt.erb +0 -0
  326. data/lib/{passenger → phusion_passenger}/templates/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  327. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +38 -0
  328. data/lib/{passenger → phusion_passenger}/templates/app_init_error.html.erb +0 -0
  329. data/lib/{passenger → phusion_passenger}/templates/database_error.html.erb +0 -0
  330. data/lib/{passenger → phusion_passenger}/templates/deployment_example.txt.erb +1 -1
  331. data/lib/{passenger → phusion_passenger}/templates/error_layout.css +0 -0
  332. data/lib/{passenger → phusion_passenger}/templates/error_layout.html.erb +0 -0
  333. data/lib/{passenger → phusion_passenger}/templates/framework_init_error.html.erb +0 -0
  334. data/lib/{passenger → phusion_passenger}/templates/general_error.html.erb +0 -0
  335. data/lib/{passenger → phusion_passenger}/templates/invalid_app_root.html.erb +1 -1
  336. data/lib/{passenger → phusion_passenger}/templates/load_error.html.erb +0 -0
  337. data/lib/{passenger → phusion_passenger}/templates/no_write_permission_to_passenger_root.txt.erb +0 -0
  338. data/lib/{passenger → phusion_passenger}/templates/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  339. data/lib/{passenger → phusion_passenger}/templates/run_installer_as_root.txt.erb +0 -0
  340. data/lib/{passenger → phusion_passenger}/templates/version_not_found.html.erb +0 -0
  341. data/lib/{passenger → phusion_passenger}/templates/welcome.txt.erb +0 -0
  342. data/lib/{passenger → phusion_passenger}/utils.rb +210 -44
  343. data/lib/{passenger → phusion_passenger}/wsgi/application_spawner.rb +18 -15
  344. data/lib/{passenger → phusion_passenger}/wsgi/request_handler.py +7 -1
  345. data/man/passenger-memory-stats.8 +1 -1
  346. data/misc/render_error_pages.rb +1 -1
  347. data/test/ApplicationPoolServerTest.cpp +0 -28
  348. data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +4 -0
  349. data/test/ApplicationPoolTest.cpp +307 -69
  350. data/test/CachedFileStatTest.cpp +262 -0
  351. data/test/FileCheckerTest.cpp +79 -0
  352. data/test/MessageChannelTest.cpp +3 -3
  353. data/test/PoolOptionsTest.cpp +37 -0
  354. data/test/SpawnManagerTest.cpp +4 -4
  355. data/test/StandardApplicationPoolTest.cpp +4 -0
  356. data/test/SystemTimeTest.cpp +37 -0
  357. data/test/UtilsTest.cpp +137 -0
  358. data/test/integration_tests.rb +270 -23
  359. data/test/oxt/backtrace_test.cpp +128 -0
  360. data/test/oxt/oxt_test_main.cpp +25 -0
  361. data/test/oxt/syscall_interruption_test.cpp +50 -0
  362. data/test/ruby/abstract_request_handler_spec.rb +83 -0
  363. data/test/ruby/abstract_server_collection_spec.rb +246 -0
  364. data/test/ruby/application_spec.rb +3 -3
  365. data/test/ruby/message_channel_spec.rb +2 -2
  366. data/test/ruby/rack/application_spawner_spec.rb +3 -5
  367. data/test/ruby/rails/application_spawner_spec.rb +54 -15
  368. data/test/ruby/rails/framework_spawner_spec.rb +6 -8
  369. data/test/ruby/rails/minimal_spawner_spec.rb +29 -0
  370. data/test/ruby/rails/spawner_error_handling_spec.rb +1 -1
  371. data/test/ruby/rails/spawner_privilege_lowering_spec.rb +3 -3
  372. data/test/ruby/spawn_manager_spec.rb +23 -12
  373. data/test/ruby/utils_spec.rb +36 -2
  374. data/test/ruby/wsgi/application_spawner_spec.rb +47 -0
  375. data/test/stub/apache2/httpd.conf.erb +3 -5
  376. data/test/stub/message_channel.rb +2 -2
  377. data/test/stub/message_channel_2.rb +2 -2
  378. data/test/stub/message_channel_3.rb +3 -3
  379. data/test/stub/minimal-railsapp/README +0 -0
  380. data/test/stub/minimal-railsapp/config/application.rb +0 -0
  381. data/test/stub/minimal-railsapp/config/environment.rb +0 -0
  382. data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
  383. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -0
  384. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
  385. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
  386. data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -0
  387. data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
  388. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -0
  389. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
  390. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
  391. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -0
  392. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -0
  393. data/test/stub/rails_apps/foobar/app/controllers/foo_controller.rb +8 -0
  394. data/test/stub/rails_apps/foobar/config/environments/development.rb +1 -2
  395. data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +21 -1
  396. data/test/stub/rails_apps/mycook/sites/some.site/public/uploads.html +26 -0
  397. data/test/stub/rails_apps/mycook/sites/some.site/public/welcome/cached.html +26 -0
  398. data/test/stub/railsapp/app/controllers/application.rb +0 -0
  399. data/test/stub/railsapp/app/controllers/bar_controller_1.rb +0 -0
  400. data/test/stub/railsapp/app/controllers/bar_controller_2.rb +1 -1
  401. data/test/stub/railsapp/app/controllers/foo_controller.rb +4 -0
  402. data/test/stub/railsapp/app/helpers/application_helper.rb +0 -0
  403. data/test/stub/railsapp/config/boot.rb +0 -0
  404. data/test/stub/railsapp/config/database.yml +0 -0
  405. data/test/stub/railsapp/config/environment.rb +0 -0
  406. data/test/stub/railsapp/config/environments/development.rb +0 -0
  407. data/test/stub/railsapp/config/environments/production.rb +0 -0
  408. data/test/stub/railsapp/config/initializers/inflections.rb +0 -0
  409. data/test/stub/railsapp/config/initializers/mime_types.rb +0 -0
  410. data/test/stub/railsapp/config/routes.rb +0 -0
  411. data/test/stub/railsapp/public/useless.txt +0 -0
  412. data/test/stub/spawn_server.rb +3 -4
  413. data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
  414. data/test/support/apache2_controller.rb +57 -7
  415. data/test/support/tut.h +15 -0
  416. data/vendor/README +12 -0
  417. data/vendor/README_FOR_PACKAGERS +1 -0
  418. data/vendor/rack-0.9.1/AUTHORS +8 -0
  419. data/vendor/rack-0.9.1/COPYING +18 -0
  420. data/vendor/rack-0.9.1/ChangeLog +1423 -0
  421. data/vendor/rack-0.9.1/KNOWN-ISSUES +18 -0
  422. data/vendor/rack-0.9.1/README +306 -0
  423. data/vendor/rack-0.9.1/Rakefile +188 -0
  424. data/vendor/rack-0.9.1/SPEC +129 -0
  425. data/vendor/rack-0.9.1/lib/rack.rb +86 -0
  426. data/vendor/rack-0.9.1/lib/rack/adapter/camping.rb +22 -0
  427. data/vendor/rack-0.9.1/lib/rack/auth/abstract/handler.rb +28 -0
  428. data/vendor/rack-0.9.1/lib/rack/auth/abstract/request.rb +37 -0
  429. data/vendor/rack-0.9.1/lib/rack/auth/basic.rb +58 -0
  430. data/vendor/rack-0.9.1/lib/rack/auth/digest/md5.rb +124 -0
  431. data/vendor/rack-0.9.1/lib/rack/auth/digest/nonce.rb +51 -0
  432. data/vendor/rack-0.9.1/lib/rack/auth/digest/params.rb +55 -0
  433. data/vendor/rack-0.9.1/lib/rack/auth/digest/request.rb +40 -0
  434. data/vendor/rack-0.9.1/lib/rack/auth/openid.rb +438 -0
  435. data/vendor/rack-0.9.1/lib/rack/builder.rb +67 -0
  436. data/vendor/rack-0.9.1/lib/rack/cascade.rb +36 -0
  437. data/vendor/rack-0.9.1/lib/rack/commonlogger.rb +61 -0
  438. data/vendor/rack-0.9.1/lib/rack/conditionalget.rb +43 -0
  439. data/vendor/rack-0.9.1/lib/rack/content_length.rb +25 -0
  440. data/vendor/rack-0.9.1/lib/rack/deflater.rb +87 -0
  441. data/vendor/rack-0.9.1/lib/rack/directory.rb +150 -0
  442. data/vendor/rack-0.9.1/lib/rack/file.rb +85 -0
  443. data/vendor/rack-0.9.1/lib/rack/handler.rb +48 -0
  444. data/vendor/rack-0.9.1/lib/rack/handler/cgi.rb +57 -0
  445. data/vendor/rack-0.9.1/lib/rack/handler/evented_mongrel.rb +8 -0
  446. data/vendor/rack-0.9.1/lib/rack/handler/fastcgi.rb +86 -0
  447. data/vendor/rack-0.9.1/lib/rack/handler/lsws.rb +52 -0
  448. data/vendor/rack-0.9.1/lib/rack/handler/mongrel.rb +82 -0
  449. data/vendor/rack-0.9.1/lib/rack/handler/scgi.rb +57 -0
  450. data/vendor/rack-0.9.1/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
  451. data/vendor/rack-0.9.1/lib/rack/handler/thin.rb +15 -0
  452. data/vendor/rack-0.9.1/lib/rack/handler/webrick.rb +61 -0
  453. data/vendor/rack-0.9.1/lib/rack/head.rb +19 -0
  454. data/vendor/rack-0.9.1/lib/rack/lint.rb +465 -0
  455. data/vendor/rack-0.9.1/lib/rack/lobster.rb +65 -0
  456. data/vendor/rack-0.9.1/lib/rack/methodoverride.rb +27 -0
  457. data/vendor/rack-0.9.1/lib/rack/mime.rb +204 -0
  458. data/vendor/rack-0.9.1/lib/rack/mock.rb +160 -0
  459. data/vendor/rack-0.9.1/lib/rack/recursive.rb +57 -0
  460. data/vendor/rack-0.9.1/lib/rack/reloader.rb +64 -0
  461. data/vendor/rack-0.9.1/lib/rack/request.rb +218 -0
  462. data/vendor/rack-0.9.1/lib/rack/response.rb +171 -0
  463. data/vendor/rack-0.9.1/lib/rack/session/abstract/id.rb +153 -0
  464. data/vendor/rack-0.9.1/lib/rack/session/cookie.rb +89 -0
  465. data/vendor/rack-0.9.1/lib/rack/session/memcache.rb +97 -0
  466. data/vendor/rack-0.9.1/lib/rack/session/pool.rb +73 -0
  467. data/vendor/rack-0.9.1/lib/rack/showexceptions.rb +348 -0
  468. data/vendor/rack-0.9.1/lib/rack/showstatus.rb +106 -0
  469. data/vendor/rack-0.9.1/lib/rack/static.rb +38 -0
  470. data/vendor/rack-0.9.1/lib/rack/urlmap.rb +48 -0
  471. data/vendor/rack-0.9.1/lib/rack/utils.rb +347 -0
  472. metadata +1197 -1055
  473. data/doc/cxxapi/System_8h-source.html +0 -251
  474. data/doc/cxxapi/classDirectoryMapper-members.html +0 -38
  475. data/doc/cxxapi/classDirectoryMapper.html +0 -203
  476. data/doc/cxxapi/classPassenger_1_1Thread.html +0 -100
  477. data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption.html +0 -46
  478. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption-members.html +0 -33
  479. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption.html +0 -44
  480. data/doc/cxxapi/namespacePassenger.html +0 -208
  481. data/doc/cxxapi/namespacePassenger_1_1InterruptableCalls.html +0 -43
  482. data/doc/cxxapi/namespacemembers.html +0 -70
  483. data/doc/cxxapi/namespacemembers_func.html +0 -66
  484. data/doc/cxxapi/namespacemembers_type.html +0 -46
  485. data/doc/cxxapi/namespaces.html +0 -35
  486. data/doc/rdoc/classes/Passenger.html +0 -136
  487. data/doc/rdoc/classes/Passenger/AbstractRequestHandler.html +0 -402
  488. data/doc/rdoc/classes/Passenger/SpawnManager.html +0 -379
  489. data/doc/rdoc/classes/Passenger/Utils.html +0 -578
  490. data/ext/apache2/System.h +0 -228
  491. data/lib/passenger/platform_info.rb +0 -302
  492. data/lib/passenger/templates/app_exited_during_initialization.html.erb +0 -19
  493. data/test/stub/apache2/httpd.conf +0 -75
  494. data/test/stub/rails_apps/foobar/config/environments/test.rb +0 -22
  495. data/test/stub/rails_apps/mycook/config/environments/test.rb +0 -22
  496. data/test/stub/railsapp/config/environments/test.rb +0 -22
  497. data/test/stub/railsapp2/config/environments/test.rb +0 -22
@@ -10,7 +10,6 @@
10
10
  <ul>
11
11
  <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
12
12
  <li><a href="modules.html"><span>Modules</span></a></li>
13
- <li><a href="namespaces.html"><span>Namespaces</span></a></li>
14
13
  <li><a href="annotated.html"><span>Classes</span></a></li>
15
14
  <li class="current"><a href="files.html"><span>Files</span></a></li>
16
15
  </ul>
@@ -41,183 +40,181 @@
41
40
  <a name="l00024"></a>00024 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
42
41
  <a name="l00025"></a>00025
43
42
  <a name="l00026"></a>00026 <span class="preprocessor">#include "Application.h"</span>
44
- <a name="l00027"></a>00027
45
- <a name="l00028"></a>00028 <span class="keyword">namespace </span>Passenger {
46
- <a name="l00029"></a>00029
47
- <a name="l00030"></a>00030 <span class="keyword">using namespace </span>std;
48
- <a name="l00031"></a>00031 <span class="keyword">using namespace </span>boost;
49
- <a name="l00032"></a>00032 <span class="comment"></span>
50
- <a name="l00033"></a>00033 <span class="comment">/**</span>
51
- <a name="l00034"></a>00034 <span class="comment"> * A persistent pool of Applications.</span>
52
- <a name="l00035"></a>00035 <span class="comment"> *</span>
53
- <a name="l00036"></a>00036 <span class="comment"> * Spawning application instances, especially Ruby on Rails ones, is a very expensive operation.</span>
54
- <a name="l00037"></a>00037 <span class="comment"> * Despite best efforts to make the operation less expensive (see SpawnManager),</span>
55
- <a name="l00038"></a>00038 <span class="comment"> * it remains expensive compared to the cost of processing an HTTP request/response.</span>
56
- <a name="l00039"></a>00039 <span class="comment"> * So, in order to solve this, some sort of caching/pooling mechanism will be required.</span>
57
- <a name="l00040"></a>00040 <span class="comment"> * ApplicationPool provides this.</span>
58
- <a name="l00041"></a>00041 <span class="comment"> *</span>
59
- <a name="l00042"></a>00042 <span class="comment"> * Normally, one would use SpawnManager to spawn a new RoR/Rack application instance,</span>
60
- <a name="l00043"></a>00043 <span class="comment"> * then use Application::connect() to create a new session with that application</span>
61
- <a name="l00044"></a>00044 <span class="comment"> * instance, and then use the returned Session object to send the request and</span>
62
- <a name="l00045"></a>00045 <span class="comment"> * to read the HTTP response. ApplicationPool replaces the first step with</span>
63
- <a name="l00046"></a>00046 <span class="comment"> * a call to Application::get(). For example:</span>
64
- <a name="l00047"></a>00047 <span class="comment"> * @code</span>
65
- <a name="l00048"></a>00048 <span class="comment"> * ApplicationPool pool = some_function_which_creates_an_application_pool();</span>
66
- <a name="l00049"></a>00049 <span class="comment"> * </span>
67
- <a name="l00050"></a>00050 <span class="comment"> * // Connect to the application and get the newly opened session.</span>
68
- <a name="l00051"></a>00051 <span class="comment"> * Application::SessionPtr session(pool-&gt;get("/home/webapps/foo"));</span>
69
- <a name="l00052"></a>00052 <span class="comment"> * </span>
70
- <a name="l00053"></a>00053 <span class="comment"> * // Send the request headers and request body data.</span>
71
- <a name="l00054"></a>00054 <span class="comment"> * session-&gt;sendHeaders(...);</span>
72
- <a name="l00055"></a>00055 <span class="comment"> * session-&gt;sendBodyBlock(...);</span>
73
- <a name="l00056"></a>00056 <span class="comment"> * // Done sending data, so we shutdown the writer stream.</span>
74
- <a name="l00057"></a>00057 <span class="comment"> * session-&gt;shutdownWriter();</span>
75
- <a name="l00058"></a>00058 <span class="comment"> *</span>
76
- <a name="l00059"></a>00059 <span class="comment"> * // Now read the HTTP response.</span>
77
- <a name="l00060"></a>00060 <span class="comment"> * string responseData = readAllDataFromSocket(session-&gt;getStream());</span>
78
- <a name="l00061"></a>00061 <span class="comment"> * // Done reading data, so we shutdown the reader stream.</span>
79
- <a name="l00062"></a>00062 <span class="comment"> * session-&gt;shutdownReader();</span>
80
- <a name="l00063"></a>00063 <span class="comment"> *</span>
81
- <a name="l00064"></a>00064 <span class="comment"> * // This session has now finished, so we close the session by resetting</span>
82
- <a name="l00065"></a>00065 <span class="comment"> * // the smart pointer to NULL (thereby destroying the Session object).</span>
83
- <a name="l00066"></a>00066 <span class="comment"> * session.reset();</span>
84
- <a name="l00067"></a>00067 <span class="comment"> *</span>
85
- <a name="l00068"></a>00068 <span class="comment"> * // We can connect to an Application multiple times. Just make sure</span>
86
- <a name="l00069"></a>00069 <span class="comment"> * // the previous session is closed.</span>
87
- <a name="l00070"></a>00070 <span class="comment"> * session = app-&gt;connect("/home/webapps/bar")</span>
88
- <a name="l00071"></a>00071 <span class="comment"> * @endcode</span>
89
- <a name="l00072"></a>00072 <span class="comment"> *</span>
90
- <a name="l00073"></a>00073 <span class="comment"> * Internally, ApplicationPool::get() will keep spawned applications instances in</span>
91
- <a name="l00074"></a>00074 <span class="comment"> * memory, and reuse them if possible. It wil* @throw l try to keep spawning to a minimum.</span>
92
- <a name="l00075"></a>00075 <span class="comment"> * Furthermore, if an application instance hasn't been used for a while, it</span>
93
- <a name="l00076"></a>00076 <span class="comment"> * will be automatically shutdown in order to save memory. Restart requests are</span>
94
- <a name="l00077"></a>00077 <span class="comment"> * honored: if an application has the file 'restart.txt' in its 'tmp' folder,</span>
95
- <a name="l00078"></a>00078 <span class="comment"> * then get() will shutdown existing instances of that application and spawn</span>
96
- <a name="l00079"></a>00079 <span class="comment"> * a new instance (this is useful when a new version of an application has been</span>
97
- <a name="l00080"></a>00080 <span class="comment"> * deployed). And finally, one can set a hard limit on the maximum number of</span>
98
- <a name="l00081"></a>00081 <span class="comment"> * applications instances that may be spawned (see ApplicationPool::setMax()).</span>
99
- <a name="l00082"></a>00082 <span class="comment"> *</span>
100
- <a name="l00083"></a>00083 <span class="comment"> * Note that ApplicationPool is just an interface (i.e. a pure virtual class).</span>
101
- <a name="l00084"></a>00084 <span class="comment"> * For concrete classes, see StandardApplicationPool and ApplicationPoolServer.</span>
102
- <a name="l00085"></a>00085 <span class="comment"> * The exact pooling algorithm depends on the implementation class.</span>
103
- <a name="l00086"></a>00086 <span class="comment"> *</span>
104
- <a name="l00087"></a>00087 <span class="comment"> * @ingroup Support</span>
105
- <a name="l00088"></a>00088 <span class="comment"> */</span>
106
- <a name="l00089"></a><a class="code" href="classPassenger_1_1ApplicationPool.html">00089</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1ApplicationPool.html" title="A persistent pool of Applications.">ApplicationPool</a> {
107
- <a name="l00090"></a>00090 <span class="keyword">public</span>:
108
- <a name="l00091"></a>00091 <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1ApplicationPool.html" title="A persistent pool of Applications.">ApplicationPool</a>() {};
109
- <a name="l00092"></a>00092 <span class="comment"></span>
110
- <a name="l00093"></a>00093 <span class="comment"> /**</span>
111
- <a name="l00094"></a>00094 <span class="comment"> * Open a new session with the application specified by &lt;tt&gt;appRoot&lt;/tt&gt;.</span>
112
- <a name="l00095"></a>00095 <span class="comment"> * See the class description for ApplicationPool, as well as Application::connect(),</span>
113
- <a name="l00096"></a>00096 <span class="comment"> * on how to use the returned session object.</span>
43
+ <a name="l00027"></a>00027 <span class="preprocessor">#include "PoolOptions.h"</span>
44
+ <a name="l00028"></a>00028
45
+ <a name="l00029"></a>00029 <span class="keyword">namespace </span>Passenger {
46
+ <a name="l00030"></a>00030
47
+ <a name="l00031"></a>00031 <span class="keyword">using namespace </span>std;
48
+ <a name="l00032"></a>00032 <span class="keyword">using namespace </span>boost;
49
+ <a name="l00033"></a>00033 <span class="comment"></span>
50
+ <a name="l00034"></a>00034 <span class="comment">/**</span>
51
+ <a name="l00035"></a>00035 <span class="comment"> * A persistent pool of Applications.</span>
52
+ <a name="l00036"></a>00036 <span class="comment"> *</span>
53
+ <a name="l00037"></a>00037 <span class="comment"> * Spawning application instances, especially Ruby on Rails ones, is a very expensive operation.</span>
54
+ <a name="l00038"></a>00038 <span class="comment"> * Despite best efforts to make the operation less expensive (see SpawnManager),</span>
55
+ <a name="l00039"></a>00039 <span class="comment"> * it remains expensive compared to the cost of processing an HTTP request/response.</span>
56
+ <a name="l00040"></a>00040 <span class="comment"> * So, in order to solve this, some sort of caching/pooling mechanism will be required.</span>
57
+ <a name="l00041"></a>00041 <span class="comment"> * ApplicationPool provides this.</span>
58
+ <a name="l00042"></a>00042 <span class="comment"> *</span>
59
+ <a name="l00043"></a>00043 <span class="comment"> * Normally, one would use SpawnManager to spawn a new RoR/Rack application instance,</span>
60
+ <a name="l00044"></a>00044 <span class="comment"> * then use Application::connect() to create a new session with that application</span>
61
+ <a name="l00045"></a>00045 <span class="comment"> * instance, and then use the returned Session object to send the request and</span>
62
+ <a name="l00046"></a>00046 <span class="comment"> * to read the HTTP response. ApplicationPool replaces the first step with</span>
63
+ <a name="l00047"></a>00047 <span class="comment"> * a call to Application::get(). For example:</span>
64
+ <a name="l00048"></a>00048 <span class="comment"> * @code</span>
65
+ <a name="l00049"></a>00049 <span class="comment"> * ApplicationPool pool = some_function_which_creates_an_application_pool();</span>
66
+ <a name="l00050"></a>00050 <span class="comment"> * </span>
67
+ <a name="l00051"></a>00051 <span class="comment"> * // Connect to the application and get the newly opened session.</span>
68
+ <a name="l00052"></a>00052 <span class="comment"> * Application::SessionPtr session(pool-&gt;get("/home/webapps/foo"));</span>
69
+ <a name="l00053"></a>00053 <span class="comment"> * </span>
70
+ <a name="l00054"></a>00054 <span class="comment"> * // Send the request headers and request body data.</span>
71
+ <a name="l00055"></a>00055 <span class="comment"> * session-&gt;sendHeaders(...);</span>
72
+ <a name="l00056"></a>00056 <span class="comment"> * session-&gt;sendBodyBlock(...);</span>
73
+ <a name="l00057"></a>00057 <span class="comment"> * // Done sending data, so we shutdown the writer stream.</span>
74
+ <a name="l00058"></a>00058 <span class="comment"> * session-&gt;shutdownWriter();</span>
75
+ <a name="l00059"></a>00059 <span class="comment"> *</span>
76
+ <a name="l00060"></a>00060 <span class="comment"> * // Now read the HTTP response.</span>
77
+ <a name="l00061"></a>00061 <span class="comment"> * string responseData = readAllDataFromSocket(session-&gt;getStream());</span>
78
+ <a name="l00062"></a>00062 <span class="comment"> * // Done reading data, so we shutdown the reader stream.</span>
79
+ <a name="l00063"></a>00063 <span class="comment"> * session-&gt;shutdownReader();</span>
80
+ <a name="l00064"></a>00064 <span class="comment"> *</span>
81
+ <a name="l00065"></a>00065 <span class="comment"> * // This session has now finished, so we close the session by resetting</span>
82
+ <a name="l00066"></a>00066 <span class="comment"> * // the smart pointer to NULL (thereby destroying the Session object).</span>
83
+ <a name="l00067"></a>00067 <span class="comment"> * session.reset();</span>
84
+ <a name="l00068"></a>00068 <span class="comment"> *</span>
85
+ <a name="l00069"></a>00069 <span class="comment"> * // We can connect to an Application multiple times. Just make sure</span>
86
+ <a name="l00070"></a>00070 <span class="comment"> * // the previous session is closed.</span>
87
+ <a name="l00071"></a>00071 <span class="comment"> * session = app-&gt;connect("/home/webapps/bar")</span>
88
+ <a name="l00072"></a>00072 <span class="comment"> * @endcode</span>
89
+ <a name="l00073"></a>00073 <span class="comment"> *</span>
90
+ <a name="l00074"></a>00074 <span class="comment"> * Internally, ApplicationPool::get() will keep spawned applications instances in</span>
91
+ <a name="l00075"></a>00075 <span class="comment"> * memory, and reuse them if possible. It wil* @throw l try to keep spawning to a minimum.</span>
92
+ <a name="l00076"></a>00076 <span class="comment"> * Furthermore, if an application instance hasn't been used for a while, it</span>
93
+ <a name="l00077"></a>00077 <span class="comment"> * will be automatically shutdown in order to save memory. Restart requests are</span>
94
+ <a name="l00078"></a>00078 <span class="comment"> * honored: if an application has the file 'restart.txt' in its 'tmp' folder,</span>
95
+ <a name="l00079"></a>00079 <span class="comment"> * then get() will shutdown existing instances of that application and spawn</span>
96
+ <a name="l00080"></a>00080 <span class="comment"> * a new instance (this is useful when a new version of an application has been</span>
97
+ <a name="l00081"></a>00081 <span class="comment"> * deployed). And finally, one can set a hard limit on the maximum number of</span>
98
+ <a name="l00082"></a>00082 <span class="comment"> * applications instances that may be spawned (see ApplicationPool::setMax()).</span>
99
+ <a name="l00083"></a>00083 <span class="comment"> *</span>
100
+ <a name="l00084"></a>00084 <span class="comment"> * Note that ApplicationPool is just an interface (i.e. a pure virtual class).</span>
101
+ <a name="l00085"></a>00085 <span class="comment"> * For concrete classes, see StandardApplicationPool and ApplicationPoolServer.</span>
102
+ <a name="l00086"></a>00086 <span class="comment"> * The exact pooling algorithm depends on the implementation class.</span>
103
+ <a name="l00087"></a>00087 <span class="comment"> *</span>
104
+ <a name="l00088"></a>00088 <span class="comment"> * @ingroup Support</span>
105
+ <a name="l00089"></a>00089 <span class="comment"> */</span>
106
+ <a name="l00090"></a><a class="code" href="classPassenger_1_1ApplicationPool.html">00090</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1ApplicationPool.html" title="A persistent pool of Applications.">ApplicationPool</a> {
107
+ <a name="l00091"></a>00091 <span class="keyword">public</span>:
108
+ <a name="l00092"></a>00092 <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1ApplicationPool.html" title="A persistent pool of Applications.">ApplicationPool</a>() {};
109
+ <a name="l00093"></a>00093 <span class="comment"></span>
110
+ <a name="l00094"></a>00094 <span class="comment"> /**</span>
111
+ <a name="l00095"></a>00095 <span class="comment"> * Checks whether this ApplicationPool object is still connected to the</span>
112
+ <a name="l00096"></a>00096 <span class="comment"> * ApplicationPool server.</span>
114
113
  <a name="l00097"></a>00097 <span class="comment"> *</span>
115
- <a name="l00098"></a>00098 <span class="comment"> * Internally, this method may either spawn a new application instance, or use</span>
116
- <a name="l00099"></a>00099 <span class="comment"> * an existing one.</span>
117
- <a name="l00100"></a>00100 <span class="comment"> *</span>
118
- <a name="l00101"></a>00101 <span class="comment"> * If &lt;tt&gt;lowerPrivilege&lt;/tt&gt; is true, then any newly spawned application</span>
119
- <a name="l00102"></a>00102 <span class="comment"> * instances will have lower privileges. See SpawnManager::SpawnManager()'s</span>
120
- <a name="l00103"></a>00103 <span class="comment"> * description of &lt;tt&gt;lowerPrivilege&lt;/tt&gt; and &lt;tt&gt;lowestUser&lt;/tt&gt; for details.</span>
121
- <a name="l00104"></a>00104 <span class="comment"> *</span>
122
- <a name="l00105"></a>00105 <span class="comment"> * @param appRoot The application root of a RoR application, i.e. the folder that</span>
123
- <a name="l00106"></a>00106 <span class="comment"> * contains 'app/', 'public/', 'config/', etc. This must be a valid</span>
124
- <a name="l00107"></a>00107 <span class="comment"> * directory, but does not have to be an absolute path.</span>
125
- <a name="l00108"></a>00108 <span class="comment"> * @param lowerPrivilege Whether to lower the application's privileges.</span>
126
- <a name="l00109"></a>00109 <span class="comment"> * @param lowestUser The user to fallback to if lowering privilege fails.</span>
127
- <a name="l00110"></a>00110 <span class="comment"> * @param environment The RAILS_ENV/RACK_ENV environment that should be used. May not be empty.</span>
128
- <a name="l00111"></a>00111 <span class="comment"> * @param spawnMethod The spawn method to use. Either "smart" or "conservative".</span>
129
- <a name="l00112"></a>00112 <span class="comment"> * See the Ruby class SpawnManager for details.</span>
130
- <a name="l00113"></a>00113 <span class="comment"> * @param appType The application type. Either "rails" or "rack".</span>
131
- <a name="l00114"></a>00114 <span class="comment"> * @return A session object.</span>
132
- <a name="l00115"></a>00115 <span class="comment"> * @throw SpawnException An attempt was made to spawn a new application instance, but that attempt failed.</span>
133
- <a name="l00116"></a>00116 <span class="comment"> * @throw BusyException The application pool is too busy right now, and cannot</span>
134
- <a name="l00117"></a>00117 <span class="comment"> * satisfy the request. One should either abort, or try again later.</span>
135
- <a name="l00118"></a>00118 <span class="comment"> * @throw IOException Something else went wrong.</span>
136
- <a name="l00119"></a>00119 <span class="comment"> * @throw thread_interrupted</span>
137
- <a name="l00120"></a>00120 <span class="comment"> * @note Applications are uniquely identified with the application root</span>
138
- <a name="l00121"></a>00121 <span class="comment"> * string. So although &lt;tt&gt;appRoot&lt;/tt&gt; does not have to be absolute, it</span>
139
- <a name="l00122"></a>00122 <span class="comment"> * should be. If one calls &lt;tt&gt;get("/home/foo")&lt;/tt&gt; and</span>
140
- <a name="l00123"></a>00123 <span class="comment"> * &lt;tt&gt;get("/home/../home/foo")&lt;/tt&gt;, then ApplicationPool will think</span>
141
- <a name="l00124"></a>00124 <span class="comment"> * they're 2 different applications, and thus will spawn 2 application instances.</span>
142
- <a name="l00125"></a>00125 <span class="comment"> */</span>
143
- <a name="l00126"></a>00126 <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, <span class="keywordtype">bool</span> lowerPrivilege = <span class="keyword">true</span>,
144
- <a name="l00127"></a>00127 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;lowestUser = <span class="stringliteral">"nobody"</span>, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;environment = <span class="stringliteral">"production"</span>,
145
- <a name="l00128"></a>00128 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;spawnMethod = <span class="stringliteral">"smart"</span>, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;appType = <span class="stringliteral">"rails"</span>) = 0;
146
- <a name="l00129"></a>00129 <span class="comment"></span>
147
- <a name="l00130"></a>00130 <span class="comment"> /**</span>
148
- <a name="l00131"></a>00131 <span class="comment"> * Clear all application instances that are currently in the pool.</span>
149
- <a name="l00132"></a>00132 <span class="comment"> *</span>
150
- <a name="l00133"></a>00133 <span class="comment"> * This method is used by unit tests to verify that the implementation is correct,</span>
151
- <a name="l00134"></a>00134 <span class="comment"> * and thus should not be called directly.</span>
114
+ <a name="l00098"></a>00098 <span class="comment"> * If that's not the case, then one should reconnect to the ApplicationPool server.</span>
115
+ <a name="l00099"></a>00099 <span class="comment"> *</span>
116
+ <a name="l00100"></a>00100 <span class="comment"> * This method is only meaningful for instances of type ApplicationPoolServer::Client.</span>
117
+ <a name="l00101"></a>00101 <span class="comment"> * The default implementation always returns true.</span>
118
+ <a name="l00102"></a>00102 <span class="comment"> */</span>
119
+ <a name="l00103"></a><a class="code" href="classPassenger_1_1ApplicationPool.html#c811d261345fcf579f049a2377b4b56b">00103</a> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#c811d261345fcf579f049a2377b4b56b" title="Checks whether this ApplicationPool object is still connected to the ApplicationPool...">connected</a>()<span class="keyword"> const </span>{
120
+ <a name="l00104"></a>00104 <span class="keywordflow">return</span> <span class="keyword">true</span>;
121
+ <a name="l00105"></a>00105 }
122
+ <a name="l00106"></a>00106 <span class="comment"></span>
123
+ <a name="l00107"></a>00107 <span class="comment"> /**</span>
124
+ <a name="l00108"></a>00108 <span class="comment"> * Open a new session with the application specified by &lt;tt&gt;PoolOptions.appRoot&lt;/tt&gt;.</span>
125
+ <a name="l00109"></a>00109 <span class="comment"> * See the class description for ApplicationPool, as well as Application::connect(),</span>
126
+ <a name="l00110"></a>00110 <span class="comment"> * on how to use the returned session object.</span>
127
+ <a name="l00111"></a>00111 <span class="comment"> *</span>
128
+ <a name="l00112"></a>00112 <span class="comment"> * Internally, this method may either spawn a new application instance, or use</span>
129
+ <a name="l00113"></a>00113 <span class="comment"> * an existing one.</span>
130
+ <a name="l00114"></a>00114 <span class="comment"> *</span>
131
+ <a name="l00115"></a>00115 <span class="comment"> * @param options An object containing information on which application to open</span>
132
+ <a name="l00116"></a>00116 <span class="comment"> * a session with, as well as spawning details. Spawning details will be used</span>
133
+ <a name="l00117"></a>00117 <span class="comment"> * if the pool decides that spawning a new application instance is necessary.</span>
134
+ <a name="l00118"></a>00118 <span class="comment"> * See SpawnManager and PoolOptions for details.</span>
135
+ <a name="l00119"></a>00119 <span class="comment"> * @return A session object.</span>
136
+ <a name="l00120"></a>00120 <span class="comment"> * @throw SpawnException An attempt was made to spawn a new application instance, but that attempt failed.</span>
137
+ <a name="l00121"></a>00121 <span class="comment"> * @throw BusyException The application pool is too busy right now, and cannot</span>
138
+ <a name="l00122"></a>00122 <span class="comment"> * satisfy the request. One should either abort, or try again later.</span>
139
+ <a name="l00123"></a>00123 <span class="comment"> * @throw IOException Something else went wrong.</span>
140
+ <a name="l00124"></a>00124 <span class="comment"> * @throw thread_interrupted</span>
141
+ <a name="l00125"></a>00125 <span class="comment"> * @note Applications are uniquely identified with the application root</span>
142
+ <a name="l00126"></a>00126 <span class="comment"> * string. So although &lt;tt&gt;appRoot&lt;/tt&gt; does not have to be absolute, it</span>
143
+ <a name="l00127"></a>00127 <span class="comment"> * should be. If one calls &lt;tt&gt;get("/home/foo")&lt;/tt&gt; and</span>
144
+ <a name="l00128"></a>00128 <span class="comment"> * &lt;tt&gt;get("/home/../home/foo")&lt;/tt&gt;, then ApplicationPool will think</span>
145
+ <a name="l00129"></a>00129 <span class="comment"> * they're 2 different applications, and thus will spawn 2 application instances.</span>
146
+ <a name="l00130"></a>00130 <span class="comment"> */</span>
147
+ <a name="l00131"></a>00131 <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) = 0;
148
+ <a name="l00132"></a>00132 <span class="comment"></span>
149
+ <a name="l00133"></a>00133 <span class="comment"> /**</span>
150
+ <a name="l00134"></a>00134 <span class="comment"> * Convenience shortcut for calling get() with default spawn options.</span>
152
151
  <a name="l00135"></a>00135 <span class="comment"> */</span>
153
- <a name="l00136"></a>00136 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#74db4d7a693d45b16320b2296a0c0997" title="Clear all application instances that are currently in the pool.">clear</a>() = 0;
154
- <a name="l00137"></a>00137
155
- <a name="l00138"></a>00138 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMaxIdleTime(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> seconds) = 0;
152
+ <a name="l00136"></a><a class="code" href="classPassenger_1_1ApplicationPool.html#b5cc9a7f0c1e7acb9d5815d4420e25ea">00136</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) {
153
+ <a name="l00137"></a>00137 <span class="keywordflow">return</span> <span class="keyword">get</span>(<a class="code" href="structPassenger_1_1PoolOptions.html" title="This struct encapsulates information for ApplicationPool::get() and for SpawnManager::spawn()...">PoolOptions</a>(appRoot));
154
+ <a name="l00138"></a>00138 }
156
155
  <a name="l00139"></a>00139 <span class="comment"></span>
157
156
  <a name="l00140"></a>00140 <span class="comment"> /**</span>
158
- <a name="l00141"></a>00141 <span class="comment"> * Set a hard limit on the number of application instances that this ApplicationPool</span>
159
- <a name="l00142"></a>00142 <span class="comment"> * may spawn. The exact behavior depends on the used algorithm, and is not specified by</span>
160
- <a name="l00143"></a>00143 <span class="comment"> * these API docs.</span>
161
- <a name="l00144"></a>00144 <span class="comment"> *</span>
162
- <a name="l00145"></a>00145 <span class="comment"> * It is allowed to set a limit lower than the current number of spawned applications.</span>
163
- <a name="l00146"></a>00146 <span class="comment"> */</span>
164
- <a name="l00147"></a>00147 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#0e0f21972ab130c9c0f90c2212328794" 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) = 0;
165
- <a name="l00148"></a>00148 <span class="comment"></span>
166
- <a name="l00149"></a>00149 <span class="comment"> /**</span>
167
- <a name="l00150"></a>00150 <span class="comment"> * Get the number of active applications in the pool.</span>
168
- <a name="l00151"></a>00151 <span class="comment"> *</span>
169
- <a name="l00152"></a>00152 <span class="comment"> * This method exposes an implementation detail of the underlying pooling algorithm.</span>
170
- <a name="l00153"></a>00153 <span class="comment"> * It is used by unit tests to verify that the implementation is correct,</span>
171
- <a name="l00154"></a>00154 <span class="comment"> * and thus should not be called directly.</span>
172
- <a name="l00155"></a>00155 <span class="comment"> */</span>
173
- <a name="l00156"></a>00156 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#06d1eae044d4d761ce77cf09049df8c8" title="Get the number of active applications in the pool.">getActive</a>() <span class="keyword">const</span> = 0;
174
- <a name="l00157"></a>00157 <span class="comment"></span>
175
- <a name="l00158"></a>00158 <span class="comment"> /**</span>
176
- <a name="l00159"></a>00159 <span class="comment"> * Get the number of active applications in the pool.</span>
177
- <a name="l00160"></a>00160 <span class="comment"> *</span>
178
- <a name="l00161"></a>00161 <span class="comment"> * This method exposes an implementation detail of the underlying pooling algorithm.</span>
179
- <a name="l00162"></a>00162 <span class="comment"> * It is used by unit tests to verify that the implementation is correct,</span>
180
- <a name="l00163"></a>00163 <span class="comment"> * and thus should not be called directly.</span>
181
- <a name="l00164"></a>00164 <span class="comment"> */</span>
182
- <a name="l00165"></a>00165 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#93b0277beb510855f85fee5de5c369bb" title="Get the number of active applications in the pool.">getCount</a>() <span class="keyword">const</span> = 0;
183
- <a name="l00166"></a>00166 <span class="comment"></span>
184
- <a name="l00167"></a>00167 <span class="comment"> /**</span>
185
- <a name="l00168"></a>00168 <span class="comment"> * Set a hard limit on the number of application instances that a single application</span>
186
- <a name="l00169"></a>00169 <span class="comment"> * may spawn in this ApplicationPool. The exact behavior depends on the used algorithm, </span>
187
- <a name="l00170"></a>00170 <span class="comment"> * and is not specified by these API docs.</span>
188
- <a name="l00171"></a>00171 <span class="comment"> *</span>
189
- <a name="l00172"></a>00172 <span class="comment"> * It is allowed to set a limit lower than the current number of spawned applications.</span>
190
- <a name="l00173"></a>00173 <span class="comment"> */</span>
191
- <a name="l00174"></a>00174 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#b0437434c79b5444ac0faf768f1410e8" 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> max) = 0;
192
- <a name="l00175"></a>00175 <span class="comment"></span>
193
- <a name="l00176"></a>00176 <span class="comment"> /**</span>
194
- <a name="l00177"></a>00177 <span class="comment"> * Sets whether to use a global queue instead of a per-backend process</span>
195
- <a name="l00178"></a>00178 <span class="comment"> * queue. If enabled, when all backend processes are active, get() will</span>
196
- <a name="l00179"></a>00179 <span class="comment"> * wait until there's at least one backend process that's idle, instead</span>
197
- <a name="l00180"></a>00180 <span class="comment"> * of queuing the request into a random process's private queue.</span>
198
- <a name="l00181"></a>00181 <span class="comment"> * This is especially useful if a website has one or more long-running</span>
199
- <a name="l00182"></a>00182 <span class="comment"> * requests.</span>
200
- <a name="l00183"></a>00183 <span class="comment"> *</span>
201
- <a name="l00184"></a>00184 <span class="comment"> * Defaults to false.</span>
202
- <a name="l00185"></a>00185 <span class="comment"> */</span>
203
- <a name="l00186"></a>00186 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#b5faf64421313e1387c187f80b95d0e7" title="Sets whether to use a global queue instead of a per-backend process queue.">setUseGlobalQueue</a>(<span class="keywordtype">bool</span> value) = 0;
204
- <a name="l00187"></a>00187 <span class="comment"></span>
205
- <a name="l00188"></a>00188 <span class="comment"> /**</span>
206
- <a name="l00189"></a>00189 <span class="comment"> * Get the process ID of the spawn server that is used.</span>
207
- <a name="l00190"></a>00190 <span class="comment"> *</span>
208
- <a name="l00191"></a>00191 <span class="comment"> * This method exposes an implementation detail. It is used by unit tests to verify</span>
209
- <a name="l00192"></a>00192 <span class="comment"> * that the implementation is correct, and thus should not be used directly.</span>
210
- <a name="l00193"></a>00193 <span class="comment"> */</span>
211
- <a name="l00194"></a>00194 <span class="keyword">virtual</span> pid_t <a class="code" href="classPassenger_1_1ApplicationPool.html#d9149c3b434ef8e18fd15a77af1a6c2c" title="Get the process ID of the spawn server that is used.">getSpawnServerPid</a>() <span class="keyword">const</span> = 0;
212
- <a name="l00195"></a>00195 };
157
+ <a name="l00141"></a>00141 <span class="comment"> * Clear all application instances that are currently in the pool.</span>
158
+ <a name="l00142"></a>00142 <span class="comment"> *</span>
159
+ <a name="l00143"></a>00143 <span class="comment"> * This method is used by unit tests to verify that the implementation is correct,</span>
160
+ <a name="l00144"></a>00144 <span class="comment"> * and thus should not be called directly.</span>
161
+ <a name="l00145"></a>00145 <span class="comment"> */</span>
162
+ <a name="l00146"></a>00146 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#74db4d7a693d45b16320b2296a0c0997" title="Clear all application instances that are currently in the pool.">clear</a>() = 0;
163
+ <a name="l00147"></a>00147
164
+ <a name="l00148"></a>00148 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setMaxIdleTime(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> seconds) = 0;
165
+ <a name="l00149"></a>00149 <span class="comment"></span>
166
+ <a name="l00150"></a>00150 <span class="comment"> /**</span>
167
+ <a name="l00151"></a>00151 <span class="comment"> * Set a hard limit on the number of application instances that this ApplicationPool</span>
168
+ <a name="l00152"></a>00152 <span class="comment"> * may spawn. The exact behavior depends on the used algorithm, and is not specified by</span>
169
+ <a name="l00153"></a>00153 <span class="comment"> * these API docs.</span>
170
+ <a name="l00154"></a>00154 <span class="comment"> *</span>
171
+ <a name="l00155"></a>00155 <span class="comment"> * It is allowed to set a limit lower than the current number of spawned applications.</span>
172
+ <a name="l00156"></a>00156 <span class="comment"> */</span>
173
+ <a name="l00157"></a>00157 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#0e0f21972ab130c9c0f90c2212328794" 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) = 0;
174
+ <a name="l00158"></a>00158 <span class="comment"></span>
175
+ <a name="l00159"></a>00159 <span class="comment"> /**</span>
176
+ <a name="l00160"></a>00160 <span class="comment"> * Get the number of active applications in the pool.</span>
177
+ <a name="l00161"></a>00161 <span class="comment"> *</span>
178
+ <a name="l00162"></a>00162 <span class="comment"> * This method exposes an implementation detail of the underlying pooling algorithm.</span>
179
+ <a name="l00163"></a>00163 <span class="comment"> * It is used by unit tests to verify that the implementation is correct,</span>
180
+ <a name="l00164"></a>00164 <span class="comment"> * and thus should not be called directly.</span>
181
+ <a name="l00165"></a>00165 <span class="comment"> */</span>
182
+ <a name="l00166"></a>00166 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#06d1eae044d4d761ce77cf09049df8c8" title="Get the number of active applications in the pool.">getActive</a>() <span class="keyword">const</span> = 0;
183
+ <a name="l00167"></a>00167 <span class="comment"></span>
184
+ <a name="l00168"></a>00168 <span class="comment"> /**</span>
185
+ <a name="l00169"></a>00169 <span class="comment"> * Get the number of active applications in the pool.</span>
186
+ <a name="l00170"></a>00170 <span class="comment"> *</span>
187
+ <a name="l00171"></a>00171 <span class="comment"> * This method exposes an implementation detail of the underlying pooling algorithm.</span>
188
+ <a name="l00172"></a>00172 <span class="comment"> * It is used by unit tests to verify that the implementation is correct,</span>
189
+ <a name="l00173"></a>00173 <span class="comment"> * and thus should not be called directly.</span>
190
+ <a name="l00174"></a>00174 <span class="comment"> */</span>
191
+ <a name="l00175"></a>00175 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#93b0277beb510855f85fee5de5c369bb" title="Get the number of active applications in the pool.">getCount</a>() <span class="keyword">const</span> = 0;
192
+ <a name="l00176"></a>00176 <span class="comment"></span>
193
+ <a name="l00177"></a>00177 <span class="comment"> /**</span>
194
+ <a name="l00178"></a>00178 <span class="comment"> * Set a hard limit on the number of application instances that a single application</span>
195
+ <a name="l00179"></a>00179 <span class="comment"> * may spawn in this ApplicationPool. The exact behavior depends on the used algorithm, </span>
196
+ <a name="l00180"></a>00180 <span class="comment"> * and is not specified by these API docs.</span>
197
+ <a name="l00181"></a>00181 <span class="comment"> *</span>
198
+ <a name="l00182"></a>00182 <span class="comment"> * It is allowed to set a limit lower than the current number of spawned applications.</span>
199
+ <a name="l00183"></a>00183 <span class="comment"> */</span>
200
+ <a name="l00184"></a>00184 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1ApplicationPool.html#b0437434c79b5444ac0faf768f1410e8" 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> max) = 0;
201
+ <a name="l00185"></a>00185 <span class="comment"></span>
202
+ <a name="l00186"></a>00186 <span class="comment"> /**</span>
203
+ <a name="l00187"></a>00187 <span class="comment"> * Get the process ID of the spawn server that is used.</span>
204
+ <a name="l00188"></a>00188 <span class="comment"> *</span>
205
+ <a name="l00189"></a>00189 <span class="comment"> * This method exposes an implementation detail. It is used by unit tests to verify</span>
206
+ <a name="l00190"></a>00190 <span class="comment"> * that the implementation is correct, and thus should not be used directly.</span>
207
+ <a name="l00191"></a>00191 <span class="comment"> */</span>
208
+ <a name="l00192"></a>00192 <span class="keyword">virtual</span> pid_t <a class="code" href="classPassenger_1_1ApplicationPool.html#d9149c3b434ef8e18fd15a77af1a6c2c" title="Get the process ID of the spawn server that is used.">getSpawnServerPid</a>() <span class="keyword">const</span> = 0;
209
+ <a name="l00193"></a>00193 };
210
+ <a name="l00194"></a>00194
211
+ <a name="l00195"></a>00195 <span class="keyword">typedef</span> shared_ptr&lt;ApplicationPool&gt; ApplicationPoolPtr;
213
212
  <a name="l00196"></a>00196
214
- <a name="l00197"></a>00197 <span class="keyword">typedef</span> shared_ptr&lt;ApplicationPool&gt; ApplicationPoolPtr;
213
+ <a name="l00197"></a>00197 }; <span class="comment">// namespace Passenger</span>
215
214
  <a name="l00198"></a>00198
216
- <a name="l00199"></a>00199 }; <span class="comment">// namespace Passenger</span>
217
- <a name="l00200"></a>00200
218
- <a name="l00201"></a>00201 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_APPLICATION_POOL_H_ */</span>
215
+ <a name="l00199"></a>00199 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_APPLICATION_POOL_H_ */</span>
219
216
  </pre></div></div>
220
- <hr size="1"><address style="text-align: right;"><small>Generated on Mon Dec 15 15:27:24 2008 for Passenger by&nbsp;
217
+ <hr size="1"><address style="text-align: right;"><small>Generated on Fri Mar 13 19:24:32 2009 for Passenger by&nbsp;
221
218
  <a href="http://www.doxygen.org/index.html">
222
219
  <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
223
220
  </body>
@@ -10,7 +10,6 @@
10
10
  <ul>
11
11
  <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
12
12
  <li><a href="modules.html"><span>Modules</span></a></li>
13
- <li><a href="namespaces.html"><span>Namespaces</span></a></li>
14
13
  <li><a href="annotated.html"><span>Classes</span></a></li>
15
14
  <li class="current"><a href="files.html"><span>Files</span></a></li>
16
15
  </ul>
@@ -39,409 +38,510 @@
39
38
  <a name="l00022"></a>00022 <span class="preprocessor"></span>
40
39
  <a name="l00023"></a>00023 <span class="preprocessor">#include &lt;boost/shared_ptr.hpp&gt;</span>
41
40
  <a name="l00024"></a>00024 <span class="preprocessor">#include &lt;boost/function.hpp&gt;</span>
42
- <a name="l00025"></a>00025 <span class="preprocessor">#include &lt;string&gt;</span>
43
- <a name="l00026"></a>00026
44
- <a name="l00027"></a>00027 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
45
- <a name="l00028"></a>00028 <span class="preprocessor">#include &lt;sys/socket.h&gt;</span>
46
- <a name="l00029"></a>00029 <span class="preprocessor">#include &lt;sys/un.h&gt;</span>
47
- <a name="l00030"></a>00030 <span class="preprocessor">#include &lt;unistd.h&gt;</span>
48
- <a name="l00031"></a>00031 <span class="preprocessor">#include &lt;errno.h&gt;</span>
49
- <a name="l00032"></a>00032 <span class="preprocessor">#include &lt;ctime&gt;</span>
50
- <a name="l00033"></a>00033 <span class="preprocessor">#include &lt;cstring&gt;</span>
51
- <a name="l00034"></a>00034
52
- <a name="l00035"></a>00035 <span class="preprocessor">#include "MessageChannel.h"</span>
53
- <a name="l00036"></a>00036 <span class="preprocessor">#include "Exceptions.h"</span>
54
- <a name="l00037"></a>00037 <span class="preprocessor">#include "Logging.h"</span>
41
+ <a name="l00025"></a>00025 <span class="preprocessor">#include &lt;oxt/system_calls.hpp&gt;</span>
42
+ <a name="l00026"></a>00026 <span class="preprocessor">#include &lt;oxt/backtrace.hpp&gt;</span>
43
+ <a name="l00027"></a>00027 <span class="preprocessor">#include &lt;string&gt;</span>
44
+ <a name="l00028"></a>00028 <span class="preprocessor">#include &lt;vector&gt;</span>
45
+ <a name="l00029"></a>00029
46
+ <a name="l00030"></a>00030 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
47
+ <a name="l00031"></a>00031 <span class="preprocessor">#include &lt;sys/socket.h&gt;</span>
48
+ <a name="l00032"></a>00032 <span class="preprocessor">#include &lt;sys/un.h&gt;</span>
49
+ <a name="l00033"></a>00033 <span class="preprocessor">#include &lt;netdb.h&gt;</span>
50
+ <a name="l00034"></a>00034 <span class="preprocessor">#include &lt;unistd.h&gt;</span>
51
+ <a name="l00035"></a>00035 <span class="preprocessor">#include &lt;errno.h&gt;</span>
52
+ <a name="l00036"></a>00036 <span class="preprocessor">#include &lt;ctime&gt;</span>
53
+ <a name="l00037"></a>00037 <span class="preprocessor">#include &lt;cstring&gt;</span>
55
54
  <a name="l00038"></a>00038
56
- <a name="l00039"></a><a class="code" href="namespacePassenger.html">00039</a> <span class="keyword">namespace </span>Passenger {
57
- <a name="l00040"></a>00040
58
- <a name="l00041"></a>00041 <span class="keyword">using namespace </span>std;
59
- <a name="l00042"></a>00042 <span class="keyword">using namespace </span>boost;
60
- <a name="l00043"></a>00043 <span class="comment"></span>
61
- <a name="l00044"></a>00044 <span class="comment">/**</span>
62
- <a name="l00045"></a>00045 <span class="comment"> * Represents a single Ruby on Rails or Rack application instance.</span>
63
- <a name="l00046"></a>00046 <span class="comment"> *</span>
64
- <a name="l00047"></a>00047 <span class="comment"> * @ingroup Support</span>
65
- <a name="l00048"></a>00048 <span class="comment"> */</span>
66
- <a name="l00049"></a><a class="code" href="classPassenger_1_1Application.html">00049</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1Application.html" title="Represents a single Ruby on Rails or Rack application instance.">Application</a> {
67
- <a name="l00050"></a>00050 <span class="keyword">public</span>:
68
- <a name="l00051"></a><a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9">00051</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1Application_1_1Session.html" title="Represents the life time of a single request/response pair of a Ruby on Rails or...">Session</a>;<span class="comment"></span>
69
- <a name="l00052"></a>00052 <span class="comment"> /** Convenient alias for Session smart pointer. */</span>
70
- <a name="l00053"></a>00053 <span class="keyword">typedef</span> shared_ptr&lt;Session&gt; <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">SessionPtr</a>;
71
- <a name="l00054"></a>00054 <span class="comment"></span>
72
- <a name="l00055"></a>00055 <span class="comment"> /**</span>
73
- <a name="l00056"></a>00056 <span class="comment"> * Represents the life time of a single request/response pair of a</span>
74
- <a name="l00057"></a>00057 <span class="comment"> * Ruby on Rails or Rack application.</span>
75
- <a name="l00058"></a>00058 <span class="comment"> *</span>
76
- <a name="l00059"></a>00059 <span class="comment"> * Session is used to forward a single HTTP request to a Ruby on Rails/Rack</span>
77
- <a name="l00060"></a>00060 <span class="comment"> * application. A Session has two communication channels: one for reading data</span>
78
- <a name="l00061"></a>00061 <span class="comment"> * from the application, and one for writing data to the application.</span>
79
- <a name="l00062"></a>00062 <span class="comment"> *</span>
80
- <a name="l00063"></a>00063 <span class="comment"> * In general, a session object is to be used in the following manner:</span>
81
- <a name="l00064"></a>00064 <span class="comment"> *</span>
82
- <a name="l00065"></a>00065 <span class="comment"> * -# Convert the HTTP request headers into a string, as expected by sendHeaders().</span>
83
- <a name="l00066"></a>00066 <span class="comment"> * Then send that string by calling sendHeaders().</span>
84
- <a name="l00067"></a>00067 <span class="comment"> * -# In case of a POST of PUT request, send the HTTP request body by calling</span>
85
- <a name="l00068"></a>00068 <span class="comment"> * sendBodyBlock(), possibly multiple times.</span>
86
- <a name="l00069"></a>00069 <span class="comment"> * -# Shutdown the writer channel since you're now done sending data.</span>
87
- <a name="l00070"></a>00070 <span class="comment"> * -# The HTTP response can now be read through the reader channel (getStream()).</span>
88
- <a name="l00071"></a>00071 <span class="comment"> * -# When the HTTP response has been read, the session must be closed.</span>
89
- <a name="l00072"></a>00072 <span class="comment"> * This is done by destroying the Session object.</span>
90
- <a name="l00073"></a>00073 <span class="comment"> *</span>
91
- <a name="l00074"></a>00074 <span class="comment"> * A usage example is shown in Application::connect(). </span>
92
- <a name="l00075"></a>00075 <span class="comment"> */</span>
93
- <a name="l00076"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html">00076</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1Application_1_1Session.html" title="Represents the life time of a single request/response pair of a Ruby on Rails or...">Session</a> {
94
- <a name="l00077"></a>00077 <span class="keyword">public</span>:<span class="comment"></span>
95
- <a name="l00078"></a>00078 <span class="comment"> /**</span>
96
- <a name="l00079"></a>00079 <span class="comment"> * Implementing classes might throw arbitrary exceptions.</span>
97
- <a name="l00080"></a>00080 <span class="comment"> */</span>
98
- <a name="l00081"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html#4fcaf0670234f7fb2ea6de4b8d8ef38c">00081</a> <span class="keyword">virtual</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#4fcaf0670234f7fb2ea6de4b8d8ef38c" title="Implementing classes might throw arbitrary exceptions.">~Session</a>() {}
99
- <a name="l00082"></a>00082 <span class="comment"></span>
55
+ <a name="l00039"></a>00039 <span class="preprocessor">#include "MessageChannel.h"</span>
56
+ <a name="l00040"></a>00040 <span class="preprocessor">#include "Exceptions.h"</span>
57
+ <a name="l00041"></a>00041 <span class="preprocessor">#include "Logging.h"</span>
58
+ <a name="l00042"></a>00042 <span class="preprocessor">#include "Utils.h"</span>
59
+ <a name="l00043"></a>00043
60
+ <a name="l00044"></a>00044 <span class="keyword">namespace </span>Passenger {
61
+ <a name="l00045"></a>00045
62
+ <a name="l00046"></a>00046 <span class="keyword">using namespace </span>std;
63
+ <a name="l00047"></a>00047 <span class="keyword">using namespace </span>boost;
64
+ <a name="l00048"></a>00048 <span class="comment"></span>
65
+ <a name="l00049"></a>00049 <span class="comment">/**</span>
66
+ <a name="l00050"></a>00050 <span class="comment"> * Represents a single Ruby on Rails or Rack application instance.</span>
67
+ <a name="l00051"></a>00051 <span class="comment"> *</span>
68
+ <a name="l00052"></a>00052 <span class="comment"> * @ingroup Support</span>
69
+ <a name="l00053"></a>00053 <span class="comment"> */</span>
70
+ <a name="l00054"></a><a class="code" href="classPassenger_1_1Application.html">00054</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1Application.html" title="Represents a single Ruby on Rails or Rack application instance.">Application</a> {
71
+ <a name="l00055"></a>00055 <span class="keyword">public</span>:
72
+ <a name="l00056"></a><a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9">00056</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1Application_1_1Session.html" title="Represents the life time of a single request/response pair of a Ruby on Rails or...">Session</a>;<span class="comment"></span>
73
+ <a name="l00057"></a>00057 <span class="comment"> /** Convenient alias for Session smart pointer. */</span>
74
+ <a name="l00058"></a>00058 <span class="keyword">typedef</span> shared_ptr&lt;Session&gt; <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">SessionPtr</a>;
75
+ <a name="l00059"></a>00059 <span class="comment"></span>
76
+ <a name="l00060"></a>00060 <span class="comment"> /**</span>
77
+ <a name="l00061"></a>00061 <span class="comment"> * Represents the life time of a single request/response pair of a</span>
78
+ <a name="l00062"></a>00062 <span class="comment"> * Ruby on Rails or Rack application.</span>
79
+ <a name="l00063"></a>00063 <span class="comment"> *</span>
80
+ <a name="l00064"></a>00064 <span class="comment"> * Session is used to forward a single HTTP request to a Ruby on Rails/Rack</span>
81
+ <a name="l00065"></a>00065 <span class="comment"> * application. A Session has two communication channels: one for reading data</span>
82
+ <a name="l00066"></a>00066 <span class="comment"> * from the application, and one for writing data to the application.</span>
83
+ <a name="l00067"></a>00067 <span class="comment"> *</span>
84
+ <a name="l00068"></a>00068 <span class="comment"> * In general, a session object is to be used in the following manner:</span>
85
+ <a name="l00069"></a>00069 <span class="comment"> *</span>
86
+ <a name="l00070"></a>00070 <span class="comment"> * -# Convert the HTTP request headers into a string, as expected by sendHeaders().</span>
87
+ <a name="l00071"></a>00071 <span class="comment"> * Then send that string by calling sendHeaders().</span>
88
+ <a name="l00072"></a>00072 <span class="comment"> * -# In case of a POST of PUT request, send the HTTP request body by calling</span>
89
+ <a name="l00073"></a>00073 <span class="comment"> * sendBodyBlock(), possibly multiple times.</span>
90
+ <a name="l00074"></a>00074 <span class="comment"> * -# Shutdown the writer channel since you're now done sending data.</span>
91
+ <a name="l00075"></a>00075 <span class="comment"> * -# The HTTP response can now be read through the reader channel (getStream()).</span>
92
+ <a name="l00076"></a>00076 <span class="comment"> * -# When the HTTP response has been read, the session must be closed.</span>
93
+ <a name="l00077"></a>00077 <span class="comment"> * This is done by destroying the Session object.</span>
94
+ <a name="l00078"></a>00078 <span class="comment"> *</span>
95
+ <a name="l00079"></a>00079 <span class="comment"> * A usage example is shown in Application::connect(). </span>
96
+ <a name="l00080"></a>00080 <span class="comment"> */</span>
97
+ <a name="l00081"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html">00081</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1Application_1_1Session.html" title="Represents the life time of a single request/response pair of a Ruby on Rails or...">Session</a> {
98
+ <a name="l00082"></a>00082 <span class="keyword">public</span>:<span class="comment"></span>
100
99
  <a name="l00083"></a>00083 <span class="comment"> /**</span>
101
- <a name="l00084"></a>00084 <span class="comment"> * Send HTTP request headers to the application. The HTTP headers must be</span>
102
- <a name="l00085"></a>00085 <span class="comment"> * converted into CGI headers, and then encoded into a string that matches this grammar:</span>
103
- <a name="l00086"></a>00086 <span class="comment"> *</span>
104
- <a name="l00087"></a>00087 <span class="comment"> @verbatim</span>
105
- <a name="l00088"></a>00088 <span class="comment"> headers ::= header*</span>
106
- <a name="l00089"></a>00089 <span class="comment"> header ::= name NUL value NUL</span>
107
- <a name="l00090"></a>00090 <span class="comment"> name ::= notnull+</span>
108
- <a name="l00091"></a>00091 <span class="comment"> value ::= notnull+</span>
109
- <a name="l00092"></a>00092 <span class="comment"> notnull ::= "\x01" | "\x02" | "\x02" | ... | "\xFF"</span>
110
- <a name="l00093"></a>00093 <span class="comment"> NUL = "\x00"</span>
111
- <a name="l00094"></a>00094 <span class="comment"> @endverbatim</span>
112
- <a name="l00095"></a>00095 <span class="comment"> *</span>
113
- <a name="l00096"></a>00096 <span class="comment"> * This method should be the first one to be called during the lifetime of a Session</span>
114
- <a name="l00097"></a>00097 <span class="comment"> * object. Otherwise strange things may happen.</span>
115
- <a name="l00098"></a>00098 <span class="comment"> *</span>
116
- <a name="l00099"></a>00099 <span class="comment"> * @param headers The HTTP request headers, converted into CGI headers and encoded as</span>
117
- <a name="l00100"></a>00100 <span class="comment"> * a string, according to the description.</span>
118
- <a name="l00101"></a>00101 <span class="comment"> * @param size The size, in bytes, of &lt;tt&gt;headers&lt;/tt&gt;.</span>
119
- <a name="l00102"></a>00102 <span class="comment"> * @pre headers != NULL</span>
120
- <a name="l00103"></a>00103 <span class="comment"> * @throws IOException The writer channel has already been closed.</span>
121
- <a name="l00104"></a>00104 <span class="comment"> * @throws SystemException Something went wrong during writing.</span>
122
- <a name="l00105"></a>00105 <span class="comment"> * @throws boost::thread_interrupted</span>
123
- <a name="l00106"></a>00106 <span class="comment"> */</span>
124
- <a name="l00107"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html#78a4c93fd80f6d913f092c488ea4d360">00107</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#78a4c93fd80f6d913f092c488ea4d360" title="Send HTTP request headers to the application.">sendHeaders</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *headers, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
125
- <a name="l00108"></a>00108 <span class="keywordtype">int</span> stream = <a class="code" href="classPassenger_1_1Application_1_1Session.html#2631b6d6b4927ec66b1f620df15d8c6e" title="Get the I/O stream&amp;#39;s file descriptor.">getStream</a>();
126
- <a name="l00109"></a>00109 <span class="keywordflow">if</span> (stream == -1) {
127
- <a name="l00110"></a>00110 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"Cannot write headers to the request handler "</span>
128
- <a name="l00111"></a>00111 <span class="stringliteral">"because the writer stream has already been closed."</span>);
129
- <a name="l00112"></a>00112 }
130
- <a name="l00113"></a>00113 <span class="keywordflow">try</span> {
131
- <a name="l00114"></a>00114 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a>(stream).writeScalar(headers, size);
132
- <a name="l00115"></a>00115 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> &amp;e) {
133
- <a name="l00116"></a>00116 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">"An error occured while writing headers "</span>
134
- <a name="l00117"></a>00117 <span class="stringliteral">"to the request handler"</span>, e.<a class="code" href="classPassenger_1_1SystemException.html#ee7a6672bf79b72a4c3ee70c57d6a47c" title="The value of errno at the time the error occured.">code</a>());
100
+ <a name="l00084"></a>00084 <span class="comment"> * Implementing classes might throw arbitrary exceptions.</span>
101
+ <a name="l00085"></a>00085 <span class="comment"> */</span>
102
+ <a name="l00086"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html#4fcaf0670234f7fb2ea6de4b8d8ef38c">00086</a> <span class="keyword">virtual</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#4fcaf0670234f7fb2ea6de4b8d8ef38c" title="Implementing classes might throw arbitrary exceptions.">~Session</a>() {}
103
+ <a name="l00087"></a>00087 <span class="comment"></span>
104
+ <a name="l00088"></a>00088 <span class="comment"> /**</span>
105
+ <a name="l00089"></a>00089 <span class="comment"> * Send HTTP request headers to the application. The HTTP headers must be</span>
106
+ <a name="l00090"></a>00090 <span class="comment"> * converted into CGI headers, and then encoded into a string that matches this grammar:</span>
107
+ <a name="l00091"></a>00091 <span class="comment"> *</span>
108
+ <a name="l00092"></a>00092 <span class="comment"> @verbatim</span>
109
+ <a name="l00093"></a>00093 <span class="comment"> headers ::= header*</span>
110
+ <a name="l00094"></a>00094 <span class="comment"> header ::= name NUL value NUL</span>
111
+ <a name="l00095"></a>00095 <span class="comment"> name ::= notnull+</span>
112
+ <a name="l00096"></a>00096 <span class="comment"> value ::= notnull+</span>
113
+ <a name="l00097"></a>00097 <span class="comment"> notnull ::= "\x01" | "\x02" | "\x02" | ... | "\xFF"</span>
114
+ <a name="l00098"></a>00098 <span class="comment"> NUL = "\x00"</span>
115
+ <a name="l00099"></a>00099 <span class="comment"> @endverbatim</span>
116
+ <a name="l00100"></a>00100 <span class="comment"> *</span>
117
+ <a name="l00101"></a>00101 <span class="comment"> * This method should be the first one to be called during the lifetime of a Session</span>
118
+ <a name="l00102"></a>00102 <span class="comment"> * object. Otherwise strange things may happen.</span>
119
+ <a name="l00103"></a>00103 <span class="comment"> *</span>
120
+ <a name="l00104"></a>00104 <span class="comment"> * @param headers The HTTP request headers, converted into CGI headers and encoded as</span>
121
+ <a name="l00105"></a>00105 <span class="comment"> * a string, according to the description.</span>
122
+ <a name="l00106"></a>00106 <span class="comment"> * @param size The size, in bytes, of &lt;tt&gt;headers&lt;/tt&gt;.</span>
123
+ <a name="l00107"></a>00107 <span class="comment"> * @pre headers != NULL</span>
124
+ <a name="l00108"></a>00108 <span class="comment"> * @throws IOException The writer channel has already been closed.</span>
125
+ <a name="l00109"></a>00109 <span class="comment"> * @throws SystemException Something went wrong during writing.</span>
126
+ <a name="l00110"></a>00110 <span class="comment"> * @throws boost::thread_interrupted</span>
127
+ <a name="l00111"></a>00111 <span class="comment"> */</span>
128
+ <a name="l00112"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html#78a4c93fd80f6d913f092c488ea4d360">00112</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#78a4c93fd80f6d913f092c488ea4d360" title="Send HTTP request headers to the application.">sendHeaders</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *headers, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
129
+ <a name="l00113"></a>00113 TRACE_POINT();
130
+ <a name="l00114"></a>00114 <span class="keywordtype">int</span> stream = <a class="code" href="classPassenger_1_1Application_1_1Session.html#2631b6d6b4927ec66b1f620df15d8c6e" title="Get the I/O stream&amp;#39;s file descriptor.">getStream</a>();
131
+ <a name="l00115"></a>00115 <span class="keywordflow">if</span> (stream == -1) {
132
+ <a name="l00116"></a>00116 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"Cannot write headers to the request handler "</span>
133
+ <a name="l00117"></a>00117 <span class="stringliteral">"because the writer stream has already been closed."</span>);
135
134
  <a name="l00118"></a>00118 }
136
- <a name="l00119"></a>00119 }
137
- <a name="l00120"></a>00120 <span class="comment"></span>
138
- <a name="l00121"></a>00121 <span class="comment"> /**</span>
139
- <a name="l00122"></a>00122 <span class="comment"> * Convenience shortcut for sendHeaders(const char *, unsigned int)</span>
140
- <a name="l00123"></a>00123 <span class="comment"> * @param headers</span>
141
- <a name="l00124"></a>00124 <span class="comment"> * @throws IOException The writer channel has already been closed.</span>
142
- <a name="l00125"></a>00125 <span class="comment"> * @throws SystemException Something went wrong during writing.</span>
143
- <a name="l00126"></a>00126 <span class="comment"> * @throws boost::thread_interrupted</span>
144
- <a name="l00127"></a>00127 <span class="comment"> */</span>
145
- <a name="l00128"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html#4fee03667f626d68c565495bcb19771a">00128</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#78a4c93fd80f6d913f092c488ea4d360" title="Send HTTP request headers to the application.">sendHeaders</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;headers) {
146
- <a name="l00129"></a>00129 <a class="code" href="classPassenger_1_1Application_1_1Session.html#78a4c93fd80f6d913f092c488ea4d360" title="Send HTTP request headers to the application.">sendHeaders</a>(headers.c_str(), headers.size());
147
- <a name="l00130"></a>00130 }
148
- <a name="l00131"></a>00131 <span class="comment"></span>
149
- <a name="l00132"></a>00132 <span class="comment"> /**</span>
150
- <a name="l00133"></a>00133 <span class="comment"> * Send a chunk of HTTP request body data to the application.</span>
151
- <a name="l00134"></a>00134 <span class="comment"> * You can call this method as many times as is required to transfer</span>
152
- <a name="l00135"></a>00135 <span class="comment"> * the entire HTTP request body.</span>
153
- <a name="l00136"></a>00136 <span class="comment"> *</span>
154
- <a name="l00137"></a>00137 <span class="comment"> * This method should only be called after a sendHeaders(). Otherwise</span>
155
- <a name="l00138"></a>00138 <span class="comment"> * strange things may happen.</span>
156
- <a name="l00139"></a>00139 <span class="comment"> *</span>
157
- <a name="l00140"></a>00140 <span class="comment"> * @param block A block of HTTP request body data to send.</span>
158
- <a name="l00141"></a>00141 <span class="comment"> * @param size The size, in bytes, of &lt;tt&gt;block&lt;/tt&gt;.</span>
159
- <a name="l00142"></a>00142 <span class="comment"> * @throws IOException The writer channel has already been closed.</span>
160
- <a name="l00143"></a>00143 <span class="comment"> * @throws SystemException Something went wrong during writing.</span>
161
- <a name="l00144"></a>00144 <span class="comment"> * @throws boost::thread_interrupted</span>
162
- <a name="l00145"></a>00145 <span class="comment"> */</span>
163
- <a name="l00146"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html#2091e4b60dcbe42ab80fa387610fd669">00146</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#2091e4b60dcbe42ab80fa387610fd669" title="Send a chunk of HTTP request body data to the application.">sendBodyBlock</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *block, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
164
- <a name="l00147"></a>00147 <span class="keywordtype">int</span> stream = <a class="code" href="classPassenger_1_1Application_1_1Session.html#2631b6d6b4927ec66b1f620df15d8c6e" title="Get the I/O stream&amp;#39;s file descriptor.">getStream</a>();
165
- <a name="l00148"></a>00148 <span class="keywordflow">if</span> (stream == -1) {
166
- <a name="l00149"></a>00149 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"Cannot write request body block to the "</span>
167
- <a name="l00150"></a>00150 <span class="stringliteral">"request handler because the writer stream has "</span>
168
- <a name="l00151"></a>00151 <span class="stringliteral">"already been closed."</span>);
169
- <a name="l00152"></a>00152 }
170
- <a name="l00153"></a>00153 <span class="keywordflow">try</span> {
171
- <a name="l00154"></a>00154 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a>(stream).writeRaw(block, size);
172
- <a name="l00155"></a>00155 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> &amp;e) {
173
- <a name="l00156"></a>00156 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">"An error occured while sending the "</span>
174
- <a name="l00157"></a>00157 <span class="stringliteral">"request body to the request handler"</span>, e.<a class="code" href="classPassenger_1_1SystemException.html#ee7a6672bf79b72a4c3ee70c57d6a47c" title="The value of errno at the time the error occured.">code</a>());
175
- <a name="l00158"></a>00158 }
176
- <a name="l00159"></a>00159 }
177
- <a name="l00160"></a>00160 <span class="comment"></span>
178
- <a name="l00161"></a>00161 <span class="comment"> /**</span>
179
- <a name="l00162"></a>00162 <span class="comment"> * Get the I/O stream's file descriptor. This steam is full-duplex,</span>
180
- <a name="l00163"></a>00163 <span class="comment"> * and will be automatically closed upon Session's destruction,</span>
181
- <a name="l00164"></a>00164 <span class="comment"> * unless discardStream() is called.</span>
182
- <a name="l00165"></a>00165 <span class="comment"> *</span>
183
- <a name="l00166"></a>00166 <span class="comment"> * @pre The stream has not been fully closed.</span>
184
- <a name="l00167"></a>00167 <span class="comment"> */</span>
185
- <a name="l00168"></a>00168 <span class="keyword">virtual</span> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#2631b6d6b4927ec66b1f620df15d8c6e" title="Get the I/O stream&amp;#39;s file descriptor.">getStream</a>() <span class="keyword">const</span> = 0;
135
+ <a name="l00119"></a>00119 <span class="keywordflow">try</span> {
136
+ <a name="l00120"></a>00120 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a>(stream).writeScalar(headers, size);
137
+ <a name="l00121"></a>00121 } <span class="keywordflow">catch</span> (<a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> &amp;e) {
138
+ <a name="l00122"></a>00122 e.<a class="code" href="classPassenger_1_1SystemException.html#6fc359f27a084158b7111ef35bec114f">setBriefMessage</a>(<span class="stringliteral">"An error occured while writing headers "</span>
139
+ <a name="l00123"></a>00123 <span class="stringliteral">"to the request handler"</span>);
140
+ <a name="l00124"></a>00124 <span class="keywordflow">throw</span>;
141
+ <a name="l00125"></a>00125 }
142
+ <a name="l00126"></a>00126 }
143
+ <a name="l00127"></a>00127 <span class="comment"></span>
144
+ <a name="l00128"></a>00128 <span class="comment"> /**</span>
145
+ <a name="l00129"></a>00129 <span class="comment"> * Convenience shortcut for sendHeaders(const char *, unsigned int)</span>
146
+ <a name="l00130"></a>00130 <span class="comment"> * @param headers</span>
147
+ <a name="l00131"></a>00131 <span class="comment"> * @throws IOException The writer channel has already been closed.</span>
148
+ <a name="l00132"></a>00132 <span class="comment"> * @throws SystemException Something went wrong during writing.</span>
149
+ <a name="l00133"></a>00133 <span class="comment"> * @throws boost::thread_interrupted</span>
150
+ <a name="l00134"></a>00134 <span class="comment"> */</span>
151
+ <a name="l00135"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html#4fee03667f626d68c565495bcb19771a">00135</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#78a4c93fd80f6d913f092c488ea4d360" title="Send HTTP request headers to the application.">sendHeaders</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;headers) {
152
+ <a name="l00136"></a>00136 <a class="code" href="classPassenger_1_1Application_1_1Session.html#78a4c93fd80f6d913f092c488ea4d360" title="Send HTTP request headers to the application.">sendHeaders</a>(headers.c_str(), headers.size());
153
+ <a name="l00137"></a>00137 }
154
+ <a name="l00138"></a>00138 <span class="comment"></span>
155
+ <a name="l00139"></a>00139 <span class="comment"> /**</span>
156
+ <a name="l00140"></a>00140 <span class="comment"> * Send a chunk of HTTP request body data to the application.</span>
157
+ <a name="l00141"></a>00141 <span class="comment"> * You can call this method as many times as is required to transfer</span>
158
+ <a name="l00142"></a>00142 <span class="comment"> * the entire HTTP request body.</span>
159
+ <a name="l00143"></a>00143 <span class="comment"> *</span>
160
+ <a name="l00144"></a>00144 <span class="comment"> * This method should only be called after a sendHeaders(). Otherwise</span>
161
+ <a name="l00145"></a>00145 <span class="comment"> * strange things may happen.</span>
162
+ <a name="l00146"></a>00146 <span class="comment"> *</span>
163
+ <a name="l00147"></a>00147 <span class="comment"> * @param block A block of HTTP request body data to send.</span>
164
+ <a name="l00148"></a>00148 <span class="comment"> * @param size The size, in bytes, of &lt;tt&gt;block&lt;/tt&gt;.</span>
165
+ <a name="l00149"></a>00149 <span class="comment"> * @throws IOException The writer channel has already been closed.</span>
166
+ <a name="l00150"></a>00150 <span class="comment"> * @throws SystemException Something went wrong during writing.</span>
167
+ <a name="l00151"></a>00151 <span class="comment"> * @throws boost::thread_interrupted</span>
168
+ <a name="l00152"></a>00152 <span class="comment"> */</span>
169
+ <a name="l00153"></a><a class="code" href="classPassenger_1_1Application_1_1Session.html#2091e4b60dcbe42ab80fa387610fd669">00153</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#2091e4b60dcbe42ab80fa387610fd669" title="Send a chunk of HTTP request body data to the application.">sendBodyBlock</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *block, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
170
+ <a name="l00154"></a>00154 TRACE_POINT();
171
+ <a name="l00155"></a>00155 <span class="keywordtype">int</span> stream = <a class="code" href="classPassenger_1_1Application_1_1Session.html#2631b6d6b4927ec66b1f620df15d8c6e" title="Get the I/O stream&amp;#39;s file descriptor.">getStream</a>();
172
+ <a name="l00156"></a>00156 <span class="keywordflow">if</span> (stream == -1) {
173
+ <a name="l00157"></a>00157 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"Cannot write request body block to the "</span>
174
+ <a name="l00158"></a>00158 <span class="stringliteral">"request handler because the writer stream has "</span>
175
+ <a name="l00159"></a>00159 <span class="stringliteral">"already been closed."</span>);
176
+ <a name="l00160"></a>00160 }
177
+ <a name="l00161"></a>00161 <span class="keywordflow">try</span> {
178
+ <a name="l00162"></a>00162 <a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a>(stream).writeRaw(block, size);
179
+ <a name="l00163"></a>00163 } <span class="keywordflow">catch</span> (<a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> &amp;e) {
180
+ <a name="l00164"></a>00164 e.<a class="code" href="classPassenger_1_1SystemException.html#6fc359f27a084158b7111ef35bec114f">setBriefMessage</a>(<span class="stringliteral">"An error occured while sending the "</span>
181
+ <a name="l00165"></a>00165 <span class="stringliteral">"request body to the request handler"</span>);
182
+ <a name="l00166"></a>00166 <span class="keywordflow">throw</span>;
183
+ <a name="l00167"></a>00167 }
184
+ <a name="l00168"></a>00168 }
186
185
  <a name="l00169"></a>00169 <span class="comment"></span>
187
186
  <a name="l00170"></a>00170 <span class="comment"> /**</span>
188
- <a name="l00171"></a>00171 <span class="comment"> * Indicate that we don't want to read data anymore from the I/O stream.</span>
189
- <a name="l00172"></a>00172 <span class="comment"> * Calling this method after closeStream() is called will have no effect.</span>
190
- <a name="l00173"></a>00173 <span class="comment"> *</span>
191
- <a name="l00174"></a>00174 <span class="comment"> * @throws SystemException Something went wrong.</span>
192
- <a name="l00175"></a>00175 <span class="comment"> * @throws boost::thread_interrupted</span>
187
+ <a name="l00171"></a>00171 <span class="comment"> * Get the I/O stream's file descriptor. This steam is full-duplex,</span>
188
+ <a name="l00172"></a>00172 <span class="comment"> * and will be automatically closed upon Session's destruction,</span>
189
+ <a name="l00173"></a>00173 <span class="comment"> * unless discardStream() is called.</span>
190
+ <a name="l00174"></a>00174 <span class="comment"> *</span>
191
+ <a name="l00175"></a>00175 <span class="comment"> * @pre The stream has not been fully closed.</span>
193
192
  <a name="l00176"></a>00176 <span class="comment"> */</span>
194
- <a name="l00177"></a>00177 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#45ad442dc1f4e7b73782bb3395d9e97d" title="Indicate that we don&amp;#39;t want to read data anymore from the I/O stream.">shutdownReader</a>() = 0;
193
+ <a name="l00177"></a>00177 <span class="keyword">virtual</span> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#2631b6d6b4927ec66b1f620df15d8c6e" title="Get the I/O stream&amp;#39;s file descriptor.">getStream</a>() <span class="keyword">const</span> = 0;
195
194
  <a name="l00178"></a>00178 <span class="comment"></span>
196
195
  <a name="l00179"></a>00179 <span class="comment"> /**</span>
197
- <a name="l00180"></a>00180 <span class="comment"> * Indicate that we don't want to write data anymore to the I/O stream.</span>
198
- <a name="l00181"></a>00181 <span class="comment"> * Calling this method after closeStream() is called will have no effect.</span>
199
- <a name="l00182"></a>00182 <span class="comment"> *</span>
200
- <a name="l00183"></a>00183 <span class="comment"> * @throws SystemException Something went wrong.</span>
201
- <a name="l00184"></a>00184 <span class="comment"> * @throws boost::thread_interrupted</span>
202
- <a name="l00185"></a>00185 <span class="comment"> */</span>
203
- <a name="l00186"></a>00186 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#dff449398adb872c93a9572ae4b701fb" title="Indicate that we don&amp;#39;t want to write data anymore to the I/O stream.">shutdownWriter</a>() = 0;
204
- <a name="l00187"></a>00187 <span class="comment"></span>
205
- <a name="l00188"></a>00188 <span class="comment"> /**</span>
206
- <a name="l00189"></a>00189 <span class="comment"> * Close the I/O stream.</span>
207
- <a name="l00190"></a>00190 <span class="comment"> *</span>
208
- <a name="l00191"></a>00191 <span class="comment"> * @throws SystemException Something went wrong.</span>
209
- <a name="l00192"></a>00192 <span class="comment"> * @throws boost::thread_interrupted</span>
210
- <a name="l00193"></a>00193 <span class="comment"> */</span>
211
- <a name="l00194"></a>00194 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#ddfeda914b17749a70016f5eb384f8a9" title="Close the I/O stream.">closeStream</a>() = 0;
212
- <a name="l00195"></a>00195 <span class="comment"></span>
213
- <a name="l00196"></a>00196 <span class="comment"> /**</span>
214
- <a name="l00197"></a>00197 <span class="comment"> * Discard the I/O stream's file descriptor, so that Session won't automatically</span>
215
- <a name="l00198"></a>00198 <span class="comment"> * closed it upon Session's destruction.</span>
216
- <a name="l00199"></a>00199 <span class="comment"> */</span>
217
- <a name="l00200"></a>00200 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#7f9ad70e75d21130d914d2134061c757" title="Discard the I/O stream&amp;#39;s file descriptor, so that Session won&amp;#39;t automatically...">discardStream</a>() = 0;
218
- <a name="l00201"></a>00201 <span class="comment"></span>
219
- <a name="l00202"></a>00202 <span class="comment"> /**</span>
220
- <a name="l00203"></a>00203 <span class="comment"> * Get the process ID of the application instance that belongs to this session.</span>
221
- <a name="l00204"></a>00204 <span class="comment"> */</span>
222
- <a name="l00205"></a>00205 <span class="keyword">virtual</span> pid_t <a class="code" href="classPassenger_1_1Application_1_1Session.html#2215bec32917c48d1a9f6386b88d018b" title="Get the process ID of the application instance that belongs to this session.">getPid</a>() <span class="keyword">const</span> = 0;
223
- <a name="l00206"></a>00206 };
224
- <a name="l00207"></a>00207
225
- <a name="l00208"></a>00208 <span class="keyword">private</span>:<span class="comment"></span>
226
- <a name="l00209"></a>00209 <span class="comment"> /**</span>
227
- <a name="l00210"></a>00210 <span class="comment"> * A "standard" implementation of Session.</span>
228
- <a name="l00211"></a>00211 <span class="comment"> */</span>
229
- <a name="l00212"></a>00212 <span class="keyword">class </span>StandardSession: <span class="keyword">public</span> Session {
230
- <a name="l00213"></a>00213 <span class="keyword">protected</span>:
231
- <a name="l00214"></a>00214 function&lt;void()&gt; closeCallback;
232
- <a name="l00215"></a>00215 <span class="keywordtype">int</span> fd;
233
- <a name="l00216"></a>00216 pid_t pid;
234
- <a name="l00217"></a>00217
235
- <a name="l00218"></a>00218 <span class="keyword">public</span>:
236
- <a name="l00219"></a>00219 StandardSession(pid_t pid,
237
- <a name="l00220"></a>00220 <span class="keyword">const</span> function&lt;<span class="keywordtype">void</span>()&gt; &amp;closeCallback,
238
- <a name="l00221"></a>00221 <span class="keywordtype">int</span> fd) {
239
- <a name="l00222"></a>00222 this-&gt;pid = pid;
240
- <a name="l00223"></a>00223 this-&gt;closeCallback = closeCallback;
241
- <a name="l00224"></a>00224 this-&gt;fd = fd;
242
- <a name="l00225"></a>00225 }
243
- <a name="l00226"></a>00226
244
- <a name="l00227"></a>00227 <span class="keyword">virtual</span> ~StandardSession() {
245
- <a name="l00228"></a>00228 closeStream();
246
- <a name="l00229"></a>00229 closeCallback();
247
- <a name="l00230"></a>00230 }
248
- <a name="l00231"></a>00231
249
- <a name="l00232"></a>00232 <span class="keyword">virtual</span> <span class="keywordtype">int</span> getStream()<span class="keyword"> const </span>{
250
- <a name="l00233"></a>00233 <span class="keywordflow">return</span> fd;
251
- <a name="l00234"></a>00234 }
252
- <a name="l00235"></a>00235
253
- <a name="l00236"></a>00236 <span class="keyword">virtual</span> <span class="keywordtype">void</span> shutdownReader() {
254
- <a name="l00237"></a>00237 <span class="keywordflow">if</span> (fd != -1) {
255
- <a name="l00238"></a>00238 <span class="keywordtype">int</span> ret = InterruptableCalls::shutdown(fd, SHUT_RD);
256
- <a name="l00239"></a>00239 <span class="keywordflow">if</span> (ret == -1) {
257
- <a name="l00240"></a>00240 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">"Cannot shutdown the writer stream"</span>,
258
- <a name="l00241"></a>00241 errno);
259
- <a name="l00242"></a>00242 }
260
- <a name="l00243"></a>00243 }
261
- <a name="l00244"></a>00244 }
262
- <a name="l00245"></a>00245
263
- <a name="l00246"></a>00246 <span class="keyword">virtual</span> <span class="keywordtype">void</span> shutdownWriter() {
264
- <a name="l00247"></a>00247 <span class="keywordflow">if</span> (fd != -1) {
265
- <a name="l00248"></a>00248 <span class="keywordtype">int</span> ret = InterruptableCalls::shutdown(fd, SHUT_WR);
266
- <a name="l00249"></a>00249 <span class="keywordflow">if</span> (ret == -1) {
267
- <a name="l00250"></a>00250 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">"Cannot shutdown the writer stream"</span>,
268
- <a name="l00251"></a>00251 errno);
269
- <a name="l00252"></a>00252 }
270
- <a name="l00253"></a>00253 }
271
- <a name="l00254"></a>00254 }
272
- <a name="l00255"></a>00255
273
- <a name="l00256"></a>00256 <span class="keyword">virtual</span> <span class="keywordtype">void</span> closeStream() {
274
- <a name="l00257"></a>00257 <span class="keywordflow">if</span> (fd != -1) {
275
- <a name="l00258"></a>00258 <span class="keywordtype">int</span> ret = InterruptableCalls::close(fd);
276
- <a name="l00259"></a>00259 <span class="keywordflow">if</span> (ret == -1) {
277
- <a name="l00260"></a>00260 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">"Cannot close the session stream"</span>,
278
- <a name="l00261"></a>00261 errno);
279
- <a name="l00262"></a>00262 }
280
- <a name="l00263"></a>00263 fd = -1;
281
- <a name="l00264"></a>00264 }
282
- <a name="l00265"></a>00265 }
283
- <a name="l00266"></a>00266
284
- <a name="l00267"></a>00267 <span class="keyword">virtual</span> <span class="keywordtype">void</span> discardStream() {
285
- <a name="l00268"></a>00268 fd = -1;
286
- <a name="l00269"></a>00269 }
287
- <a name="l00270"></a>00270
288
- <a name="l00271"></a>00271 <span class="keyword">virtual</span> pid_t <a class="code" href="classPassenger_1_1Application.html#94d2cce1c2c1d3441325f1498a22bf02" title="Returns the process ID of this application instance.">getPid</a>()<span class="keyword"> const </span>{
289
- <a name="l00272"></a>00272 <span class="keywordflow">return</span> pid;
290
- <a name="l00273"></a>00273 }
291
- <a name="l00274"></a>00274 };
292
- <a name="l00275"></a>00275
293
- <a name="l00276"></a>00276 <span class="keywordtype">string</span> appRoot;
294
- <a name="l00277"></a>00277 pid_t pid;
295
- <a name="l00278"></a>00278 <span class="keywordtype">string</span> listenSocketName;
296
- <a name="l00279"></a>00279 <span class="keywordtype">bool</span> usingAbstractNamespace;
297
- <a name="l00280"></a>00280 <span class="keywordtype">int</span> ownerPipe;
298
- <a name="l00281"></a>00281
299
- <a name="l00282"></a>00282 <span class="keyword">public</span>:<span class="comment"></span>
300
- <a name="l00283"></a>00283 <span class="comment"> /**</span>
301
- <a name="l00284"></a>00284 <span class="comment"> * Construct a new Application object.</span>
302
- <a name="l00285"></a>00285 <span class="comment"> *</span>
303
- <a name="l00286"></a>00286 <span class="comment"> * @param theAppRoot The application root of an application. In case of a Rails application,</span>
304
- <a name="l00287"></a>00287 <span class="comment"> * this is the folder that contains 'app/', 'public/', 'config/', etc.</span>
305
- <a name="l00288"></a>00288 <span class="comment"> * This must be a valid directory, but the path does not have to be absolute.</span>
306
- <a name="l00289"></a>00289 <span class="comment"> * @param pid The process ID of this application instance.</span>
307
- <a name="l00290"></a>00290 <span class="comment"> * @param listenSocketName The name of the listener socket of this application instance.</span>
308
- <a name="l00291"></a>00291 <span class="comment"> * @param usingAbstractNamespace Whether &lt;tt&gt;listenSocketName&lt;/tt&gt; refers to a Unix</span>
309
- <a name="l00292"></a>00292 <span class="comment"> * socket on the abstract namespace. Note that listenSocketName must not</span>
310
- <a name="l00293"></a>00293 <span class="comment"> * contain the leading null byte, even if it's an abstract namespace socket.</span>
311
- <a name="l00294"></a>00294 <span class="comment"> * @param ownerPipe The owner pipe of this application instance.</span>
312
- <a name="l00295"></a>00295 <span class="comment"> * @post getAppRoot() == theAppRoot &amp;&amp; getPid() == pid</span>
313
- <a name="l00296"></a>00296 <span class="comment"> */</span>
314
- <a name="l00297"></a><a class="code" href="classPassenger_1_1Application.html#163509167eef118470b72661ac8acd5d">00297</a> <a class="code" href="classPassenger_1_1Application.html#163509167eef118470b72661ac8acd5d" title="Construct a new Application object.">Application</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;theAppRoot, pid_t pid, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;listenSocketName,
315
- <a name="l00298"></a>00298 <span class="keywordtype">bool</span> usingAbstractNamespace, <span class="keywordtype">int</span> ownerPipe) {
316
- <a name="l00299"></a>00299 appRoot = theAppRoot;
317
- <a name="l00300"></a>00300 this-&gt;pid = pid;
318
- <a name="l00301"></a>00301 this-&gt;listenSocketName = listenSocketName;
319
- <a name="l00302"></a>00302 this-&gt;usingAbstractNamespace = usingAbstractNamespace;
320
- <a name="l00303"></a>00303 this-&gt;ownerPipe = ownerPipe;
321
- <a name="l00304"></a>00304 P_TRACE(3, <span class="stringliteral">"Application "</span> &lt;&lt; <span class="keyword">this</span> &lt;&lt; <span class="stringliteral">": created."</span>);
322
- <a name="l00305"></a>00305 }
323
- <a name="l00306"></a>00306
324
- <a name="l00307"></a>00307 <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1Application.html" title="Represents a single Ruby on Rails or Rack application instance.">Application</a>() {
325
- <a name="l00308"></a>00308 <span class="keywordtype">int</span> ret;
196
+ <a name="l00180"></a>00180 <span class="comment"> * Set the timeout value for reading data from the I/O stream.</span>
197
+ <a name="l00181"></a>00181 <span class="comment"> * If no data can be read within the timeout period, then the</span>
198
+ <a name="l00182"></a>00182 <span class="comment"> * read call will fail with error EAGAIN or EWOULDBLOCK.</span>
199
+ <a name="l00183"></a>00183 <span class="comment"> *</span>
200
+ <a name="l00184"></a>00184 <span class="comment"> * @param msec The timeout, in milliseconds. If 0 is given,</span>
201
+ <a name="l00185"></a>00185 <span class="comment"> * there will be no timeout.</span>
202
+ <a name="l00186"></a>00186 <span class="comment"> * @throws SystemException Cannot set the timeout.</span>
203
+ <a name="l00187"></a>00187 <span class="comment"> */</span>
204
+ <a name="l00188"></a>00188 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#17b4b6e4c47ec8941a099e229d2944f2" title="Set the timeout value for reading data from the I/O stream.">setReaderTimeout</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> msec) = 0;
205
+ <a name="l00189"></a>00189 <span class="comment"></span>
206
+ <a name="l00190"></a>00190 <span class="comment"> /**</span>
207
+ <a name="l00191"></a>00191 <span class="comment"> * Set the timeout value for writing data from the I/O stream.</span>
208
+ <a name="l00192"></a>00192 <span class="comment"> * If no data can be written within the timeout period, then the</span>
209
+ <a name="l00193"></a>00193 <span class="comment"> * write call will fail with error EAGAIN or EWOULDBLOCK.</span>
210
+ <a name="l00194"></a>00194 <span class="comment"> *</span>
211
+ <a name="l00195"></a>00195 <span class="comment"> * @param msec The timeout, in milliseconds. If 0 is given,</span>
212
+ <a name="l00196"></a>00196 <span class="comment"> * there will be no timeout.</span>
213
+ <a name="l00197"></a>00197 <span class="comment"> * @throws SystemException Cannot set the timeout.</span>
214
+ <a name="l00198"></a>00198 <span class="comment"> */</span>
215
+ <a name="l00199"></a>00199 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#4236abbdf69e10ded00c756de24433e9" title="Set the timeout value for writing data from the I/O stream.">setWriterTimeout</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> msec) = 0;
216
+ <a name="l00200"></a>00200 <span class="comment"></span>
217
+ <a name="l00201"></a>00201 <span class="comment"> /**</span>
218
+ <a name="l00202"></a>00202 <span class="comment"> * Indicate that we don't want to read data anymore from the I/O stream.</span>
219
+ <a name="l00203"></a>00203 <span class="comment"> * Calling this method after closeStream() is called will have no effect.</span>
220
+ <a name="l00204"></a>00204 <span class="comment"> *</span>
221
+ <a name="l00205"></a>00205 <span class="comment"> * @throws SystemException Something went wrong.</span>
222
+ <a name="l00206"></a>00206 <span class="comment"> * @throws boost::thread_interrupted</span>
223
+ <a name="l00207"></a>00207 <span class="comment"> */</span>
224
+ <a name="l00208"></a>00208 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#45ad442dc1f4e7b73782bb3395d9e97d" title="Indicate that we don&amp;#39;t want to read data anymore from the I/O stream.">shutdownReader</a>() = 0;
225
+ <a name="l00209"></a>00209 <span class="comment"></span>
226
+ <a name="l00210"></a>00210 <span class="comment"> /**</span>
227
+ <a name="l00211"></a>00211 <span class="comment"> * Indicate that we don't want to write data anymore to the I/O stream.</span>
228
+ <a name="l00212"></a>00212 <span class="comment"> * Calling this method after closeStream() is called will have no effect.</span>
229
+ <a name="l00213"></a>00213 <span class="comment"> *</span>
230
+ <a name="l00214"></a>00214 <span class="comment"> * @throws SystemException Something went wrong.</span>
231
+ <a name="l00215"></a>00215 <span class="comment"> * @throws boost::thread_interrupted</span>
232
+ <a name="l00216"></a>00216 <span class="comment"> */</span>
233
+ <a name="l00217"></a>00217 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#dff449398adb872c93a9572ae4b701fb" title="Indicate that we don&amp;#39;t want to write data anymore to the I/O stream.">shutdownWriter</a>() = 0;
234
+ <a name="l00218"></a>00218 <span class="comment"></span>
235
+ <a name="l00219"></a>00219 <span class="comment"> /**</span>
236
+ <a name="l00220"></a>00220 <span class="comment"> * Close the I/O stream.</span>
237
+ <a name="l00221"></a>00221 <span class="comment"> *</span>
238
+ <a name="l00222"></a>00222 <span class="comment"> * @throws SystemException Something went wrong.</span>
239
+ <a name="l00223"></a>00223 <span class="comment"> * @throws boost::thread_interrupted</span>
240
+ <a name="l00224"></a>00224 <span class="comment"> */</span>
241
+ <a name="l00225"></a>00225 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#ddfeda914b17749a70016f5eb384f8a9" title="Close the I/O stream.">closeStream</a>() = 0;
242
+ <a name="l00226"></a>00226 <span class="comment"></span>
243
+ <a name="l00227"></a>00227 <span class="comment"> /**</span>
244
+ <a name="l00228"></a>00228 <span class="comment"> * Discard the I/O stream's file descriptor, so that Session won't automatically</span>
245
+ <a name="l00229"></a>00229 <span class="comment"> * closed it upon Session's destruction.</span>
246
+ <a name="l00230"></a>00230 <span class="comment"> */</span>
247
+ <a name="l00231"></a>00231 <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1Application_1_1Session.html#7f9ad70e75d21130d914d2134061c757" title="Discard the I/O stream&amp;#39;s file descriptor, so that Session won&amp;#39;t automatically...">discardStream</a>() = 0;
248
+ <a name="l00232"></a>00232 <span class="comment"></span>
249
+ <a name="l00233"></a>00233 <span class="comment"> /**</span>
250
+ <a name="l00234"></a>00234 <span class="comment"> * Get the process ID of the application instance that belongs to this session.</span>
251
+ <a name="l00235"></a>00235 <span class="comment"> */</span>
252
+ <a name="l00236"></a>00236 <span class="keyword">virtual</span> pid_t <a class="code" href="classPassenger_1_1Application_1_1Session.html#2215bec32917c48d1a9f6386b88d018b" title="Get the process ID of the application instance that belongs to this session.">getPid</a>() <span class="keyword">const</span> = 0;
253
+ <a name="l00237"></a>00237 };
254
+ <a name="l00238"></a>00238
255
+ <a name="l00239"></a>00239 <span class="keyword">private</span>:<span class="comment"></span>
256
+ <a name="l00240"></a>00240 <span class="comment"> /**</span>
257
+ <a name="l00241"></a>00241 <span class="comment"> * A "standard" implementation of Session.</span>
258
+ <a name="l00242"></a>00242 <span class="comment"> */</span>
259
+ <a name="l00243"></a>00243 <span class="keyword">class </span>StandardSession: <span class="keyword">public</span> Session {
260
+ <a name="l00244"></a>00244 <span class="keyword">protected</span>:
261
+ <a name="l00245"></a>00245 function&lt;void()&gt; closeCallback;
262
+ <a name="l00246"></a>00246 <span class="keywordtype">int</span> fd;
263
+ <a name="l00247"></a>00247 pid_t pid;
264
+ <a name="l00248"></a>00248
265
+ <a name="l00249"></a>00249 <span class="keyword">public</span>:
266
+ <a name="l00250"></a>00250 StandardSession(pid_t pid,
267
+ <a name="l00251"></a>00251 <span class="keyword">const</span> function&lt;<span class="keywordtype">void</span>()&gt; &amp;closeCallback,
268
+ <a name="l00252"></a>00252 <span class="keywordtype">int</span> fd) {
269
+ <a name="l00253"></a>00253 this-&gt;pid = pid;
270
+ <a name="l00254"></a>00254 this-&gt;closeCallback = closeCallback;
271
+ <a name="l00255"></a>00255 this-&gt;fd = fd;
272
+ <a name="l00256"></a>00256 }
273
+ <a name="l00257"></a>00257
274
+ <a name="l00258"></a>00258 <span class="keyword">virtual</span> ~StandardSession() {
275
+ <a name="l00259"></a>00259 TRACE_POINT();
276
+ <a name="l00260"></a>00260 closeStream();
277
+ <a name="l00261"></a>00261 closeCallback();
278
+ <a name="l00262"></a>00262 }
279
+ <a name="l00263"></a>00263
280
+ <a name="l00264"></a>00264 <span class="keyword">virtual</span> <span class="keywordtype">int</span> getStream()<span class="keyword"> const </span>{
281
+ <a name="l00265"></a>00265 <span class="keywordflow">return</span> fd;
282
+ <a name="l00266"></a>00266 }
283
+ <a name="l00267"></a>00267
284
+ <a name="l00268"></a>00268 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setReaderTimeout(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> msec) {
285
+ <a name="l00269"></a>00269 MessageChannel(fd).setReadTimeout(msec);
286
+ <a name="l00270"></a>00270 }
287
+ <a name="l00271"></a>00271
288
+ <a name="l00272"></a>00272 <span class="keyword">virtual</span> <span class="keywordtype">void</span> setWriterTimeout(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> msec) {
289
+ <a name="l00273"></a>00273 MessageChannel(fd).setWriteTimeout(msec);
290
+ <a name="l00274"></a>00274 }
291
+ <a name="l00275"></a>00275
292
+ <a name="l00276"></a>00276 <span class="keyword">virtual</span> <span class="keywordtype">void</span> shutdownReader() {
293
+ <a name="l00277"></a>00277 TRACE_POINT();
294
+ <a name="l00278"></a>00278 <span class="keywordflow">if</span> (fd != -1) {
295
+ <a name="l00279"></a>00279 <span class="keywordtype">int</span> ret = syscalls::shutdown(fd, SHUT_RD);
296
+ <a name="l00280"></a>00280 <span class="keywordflow">if</span> (ret == -1) {
297
+ <a name="l00281"></a>00281 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">"Cannot shutdown the writer stream"</span>,
298
+ <a name="l00282"></a>00282 errno);
299
+ <a name="l00283"></a>00283 }
300
+ <a name="l00284"></a>00284 }
301
+ <a name="l00285"></a>00285 }
302
+ <a name="l00286"></a>00286
303
+ <a name="l00287"></a>00287 <span class="keyword">virtual</span> <span class="keywordtype">void</span> shutdownWriter() {
304
+ <a name="l00288"></a>00288 TRACE_POINT();
305
+ <a name="l00289"></a>00289 <span class="keywordflow">if</span> (fd != -1) {
306
+ <a name="l00290"></a>00290 <span class="keywordtype">int</span> ret = syscalls::shutdown(fd, SHUT_WR);
307
+ <a name="l00291"></a>00291 <span class="keywordflow">if</span> (ret == -1) {
308
+ <a name="l00292"></a>00292 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">"Cannot shutdown the writer stream"</span>,
309
+ <a name="l00293"></a>00293 errno);
310
+ <a name="l00294"></a>00294 }
311
+ <a name="l00295"></a>00295 }
312
+ <a name="l00296"></a>00296 }
313
+ <a name="l00297"></a>00297
314
+ <a name="l00298"></a>00298 <span class="keyword">virtual</span> <span class="keywordtype">void</span> closeStream() {
315
+ <a name="l00299"></a>00299 TRACE_POINT();
316
+ <a name="l00300"></a>00300 <span class="keywordflow">if</span> (fd != -1) {
317
+ <a name="l00301"></a>00301 <span class="keywordtype">int</span> ret = syscalls::close(fd);
318
+ <a name="l00302"></a>00302 <span class="keywordflow">if</span> (ret == -1) {
319
+ <a name="l00303"></a>00303 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">"Cannot close the session stream"</span>,
320
+ <a name="l00304"></a>00304 errno);
321
+ <a name="l00305"></a>00305 }
322
+ <a name="l00306"></a>00306 fd = -1;
323
+ <a name="l00307"></a>00307 }
324
+ <a name="l00308"></a>00308 }
326
325
  <a name="l00309"></a>00309
327
- <a name="l00310"></a>00310 <span class="keywordflow">if</span> (ownerPipe != -1) {
328
- <a name="l00311"></a>00311 <span class="keywordflow">do</span> {
329
- <a name="l00312"></a>00312 ret = close(ownerPipe);
330
- <a name="l00313"></a>00313 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
331
- <a name="l00314"></a>00314 }
332
- <a name="l00315"></a>00315 <span class="keywordflow">if</span> (!usingAbstractNamespace) {
333
- <a name="l00316"></a>00316 <span class="keywordflow">do</span> {
334
- <a name="l00317"></a>00317 ret = unlink(listenSocketName.c_str());
335
- <a name="l00318"></a>00318 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
336
- <a name="l00319"></a>00319 }
337
- <a name="l00320"></a>00320 P_TRACE(3, <span class="stringliteral">"Application "</span> &lt;&lt; <span class="keyword">this</span> &lt;&lt; <span class="stringliteral">": destroyed."</span>);
338
- <a name="l00321"></a>00321 }
339
- <a name="l00322"></a>00322 <span class="comment"></span>
340
- <a name="l00323"></a>00323 <span class="comment"> /**</span>
341
- <a name="l00324"></a>00324 <span class="comment"> * Returns the application root for this application. See the constructor</span>
342
- <a name="l00325"></a>00325 <span class="comment"> * for information about the application root.</span>
343
- <a name="l00326"></a>00326 <span class="comment"> */</span>
344
- <a name="l00327"></a><a class="code" href="classPassenger_1_1Application.html#0a0665852e7ebc8fb8ab0772fa90bc56">00327</a> <span class="keywordtype">string</span> <a class="code" href="classPassenger_1_1Application.html#0a0665852e7ebc8fb8ab0772fa90bc56" title="Returns the application root for this application.">getAppRoot</a>()<span class="keyword"> const </span>{
345
- <a name="l00328"></a>00328 <span class="keywordflow">return</span> appRoot;
346
- <a name="l00329"></a>00329 }
347
- <a name="l00330"></a>00330 <span class="comment"></span>
348
- <a name="l00331"></a>00331 <span class="comment"> /**</span>
349
- <a name="l00332"></a>00332 <span class="comment"> * Returns the process ID of this application instance.</span>
350
- <a name="l00333"></a>00333 <span class="comment"> */</span>
351
- <a name="l00334"></a><a class="code" href="classPassenger_1_1Application.html#94d2cce1c2c1d3441325f1498a22bf02">00334</a> pid_t <a class="code" href="classPassenger_1_1Application.html#94d2cce1c2c1d3441325f1498a22bf02" title="Returns the process ID of this application instance.">getPid</a>()<span class="keyword"> const </span>{
352
- <a name="l00335"></a>00335 <span class="keywordflow">return</span> pid;
353
- <a name="l00336"></a>00336 }
354
- <a name="l00337"></a>00337 <span class="comment"></span>
355
- <a name="l00338"></a>00338 <span class="comment"> /**</span>
356
- <a name="l00339"></a>00339 <span class="comment"> * Connect to this application instance with the purpose of sending</span>
357
- <a name="l00340"></a>00340 <span class="comment"> * a request to the application. Once connected, a new session will</span>
358
- <a name="l00341"></a>00341 <span class="comment"> * be opened. This session represents the life time of a single</span>
359
- <a name="l00342"></a>00342 <span class="comment"> * request/response pair, and can be used to send the request</span>
360
- <a name="l00343"></a>00343 <span class="comment"> * data to the application instance, as well as receiving the response</span>
361
- <a name="l00344"></a>00344 <span class="comment"> * data.</span>
362
- <a name="l00345"></a>00345 <span class="comment"> *</span>
363
- <a name="l00346"></a>00346 <span class="comment"> * The use of connect() is demonstrated in the following example.</span>
364
- <a name="l00347"></a>00347 <span class="comment"> * @code</span>
365
- <a name="l00348"></a>00348 <span class="comment"> * // Connect to the application and get the newly opened session.</span>
366
- <a name="l00349"></a>00349 <span class="comment"> * Application::SessionPtr session(app-&gt;connect("/home/webapps/foo"));</span>
367
- <a name="l00350"></a>00350 <span class="comment"> * </span>
368
- <a name="l00351"></a>00351 <span class="comment"> * // Send the request headers and request body data.</span>
369
- <a name="l00352"></a>00352 <span class="comment"> * session-&gt;sendHeaders(...);</span>
370
- <a name="l00353"></a>00353 <span class="comment"> * session-&gt;sendBodyBlock(...);</span>
371
- <a name="l00354"></a>00354 <span class="comment"> * // Done sending data, so we close the writer channel.</span>
372
- <a name="l00355"></a>00355 <span class="comment"> * session-&gt;closeWriter();</span>
373
- <a name="l00356"></a>00356 <span class="comment"> *</span>
374
- <a name="l00357"></a>00357 <span class="comment"> * // Now read the HTTP response.</span>
375
- <a name="l00358"></a>00358 <span class="comment"> * string responseData = readAllDataFromSocket(session-&gt;getReader());</span>
376
- <a name="l00359"></a>00359 <span class="comment"> * // Done reading data, so we close the reader channel.</span>
377
- <a name="l00360"></a>00360 <span class="comment"> * session-&gt;closeReader();</span>
378
- <a name="l00361"></a>00361 <span class="comment"> *</span>
379
- <a name="l00362"></a>00362 <span class="comment"> * // This session has now finished, so we close the session by resetting</span>
380
- <a name="l00363"></a>00363 <span class="comment"> * // the smart pointer to NULL (thereby destroying the Session object).</span>
381
- <a name="l00364"></a>00364 <span class="comment"> * session.reset();</span>
382
- <a name="l00365"></a>00365 <span class="comment"> *</span>
383
- <a name="l00366"></a>00366 <span class="comment"> * // We can connect to an Application multiple times. Just make sure</span>
384
- <a name="l00367"></a>00367 <span class="comment"> * // the previous session is closed.</span>
385
- <a name="l00368"></a>00368 <span class="comment"> * session = app-&gt;connect("/home/webapps/bar")</span>
386
- <a name="l00369"></a>00369 <span class="comment"> * @endcode</span>
387
- <a name="l00370"></a>00370 <span class="comment"> *</span>
388
- <a name="l00371"></a>00371 <span class="comment"> * Note that a RoR application instance can only process one</span>
389
- <a name="l00372"></a>00372 <span class="comment"> * request at the same time, and thus only one session at the same time.</span>
390
- <a name="l00373"></a>00373 <span class="comment"> * It's unspecified whether Rack applications can handle multiple simultanous sessions.</span>
391
- <a name="l00374"></a>00374 <span class="comment"> *</span>
392
- <a name="l00375"></a>00375 <span class="comment"> * You &lt;b&gt;must&lt;/b&gt; close a session when you no longer need if. If you</span>
393
- <a name="l00376"></a>00376 <span class="comment"> * call connect() without having properly closed a previous session,</span>
394
- <a name="l00377"></a>00377 <span class="comment"> * you might cause a deadlock because the application instance may be</span>
395
- <a name="l00378"></a>00378 <span class="comment"> * waiting for you to close the previous session.</span>
396
- <a name="l00379"></a>00379 <span class="comment"> *</span>
397
- <a name="l00380"></a>00380 <span class="comment"> * @return A smart pointer to a Session object, which represents the created session.</span>
398
- <a name="l00381"></a>00381 <span class="comment"> * @param closeCallback A function which will be called when the session has been closed.</span>
399
- <a name="l00382"></a>00382 <span class="comment"> * @post this-&gt;getSessions() == old-&gt;getSessions() + 1</span>
400
- <a name="l00383"></a>00383 <span class="comment"> * @throws SystemException Something went wrong during the connection process.</span>
401
- <a name="l00384"></a>00384 <span class="comment"> * @throws IOException Something went wrong during the connection process.</span>
402
- <a name="l00385"></a>00385 <span class="comment"> */</span>
403
- <a name="l00386"></a><a class="code" href="classPassenger_1_1Application.html#34636f796ff3924ad5ec142aaa581379">00386</a> <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">SessionPtr</a> <a class="code" href="classPassenger_1_1Application.html#34636f796ff3924ad5ec142aaa581379" title="Connect to this application instance with the purpose of sending a request to the...">connect</a>(<span class="keyword">const</span> function&lt;<span class="keywordtype">void</span>()&gt; &amp;closeCallback)<span class="keyword"> const </span>{
404
- <a name="l00387"></a>00387 <span class="keywordtype">int</span> fd, ret;
405
- <a name="l00388"></a>00388
406
- <a name="l00389"></a>00389 <span class="keywordflow">do</span> {
407
- <a name="l00390"></a>00390 fd = socket(PF_UNIX, SOCK_STREAM, 0);
408
- <a name="l00391"></a>00391 } <span class="keywordflow">while</span> (fd == -1 &amp;&amp; errno == EINTR);
409
- <a name="l00392"></a>00392 <span class="keywordflow">if</span> (fd == -1) {
410
- <a name="l00393"></a>00393 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">"Cannot create a new unconnected Unix socket"</span>, errno);
411
- <a name="l00394"></a>00394 }
412
- <a name="l00395"></a>00395
413
- <a name="l00396"></a>00396 <span class="keyword">struct </span>sockaddr_un addr;
414
- <a name="l00397"></a>00397 addr.sun_family = AF_UNIX;
415
- <a name="l00398"></a>00398 <span class="keywordflow">if</span> (usingAbstractNamespace) {
416
- <a name="l00399"></a>00399 strncpy(addr.sun_path + 1, listenSocketName.c_str(), <span class="keyword">sizeof</span>(addr.sun_path) - 1);
417
- <a name="l00400"></a>00400 addr.sun_path[0] = <span class="charliteral">'\0'</span>;
418
- <a name="l00401"></a>00401 } <span class="keywordflow">else</span> {
419
- <a name="l00402"></a>00402 strncpy(addr.sun_path, listenSocketName.c_str(), <span class="keyword">sizeof</span>(addr.sun_path));
420
- <a name="l00403"></a>00403 }
421
- <a name="l00404"></a>00404 addr.sun_path[<span class="keyword">sizeof</span>(addr.sun_path) - 1] = <span class="charliteral">'\0'</span>;
422
- <a name="l00405"></a>00405 <span class="keywordflow">do</span> {
423
- <a name="l00406"></a>00406 ret =<a class="code" href="classPassenger_1_1Application.html#34636f796ff3924ad5ec142aaa581379" title="Connect to this application instance with the purpose of sending a request to the..."> ::connect</a>(fd, (<span class="keyword">const</span> sockaddr *) &amp;addr, <span class="keyword">sizeof</span>(addr));
424
- <a name="l00407"></a>00407 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
425
- <a name="l00408"></a>00408 <span class="keywordflow">if</span> (ret == -1) {
426
- <a name="l00409"></a>00409 <span class="keywordtype">int</span> e = errno;
427
- <a name="l00410"></a>00410 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot connect to Unix socket '"</span>);
428
- <a name="l00411"></a>00411 message.append(listenSocketName);
429
- <a name="l00412"></a>00412 message.append(<span class="stringliteral">"' on the abstract namespace"</span>);
430
- <a name="l00413"></a>00413 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(message, e);
431
- <a name="l00414"></a>00414 }
432
- <a name="l00415"></a>00415
433
- <a name="l00416"></a>00416 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> StandardSession(pid, closeCallback, fd));
434
- <a name="l00417"></a>00417 }
435
- <a name="l00418"></a>00418 };
436
- <a name="l00419"></a>00419 <span class="comment"></span>
437
- <a name="l00420"></a>00420 <span class="comment">/** Convenient alias for Application smart pointer. */</span>
438
- <a name="l00421"></a><a class="code" href="namespacePassenger.html#6a15fd5e8765802a0b8b077e15297e18">00421</a> <span class="keyword">typedef</span> shared_ptr&lt;Application&gt; <a class="code" href="namespacePassenger.html#6a15fd5e8765802a0b8b077e15297e18" title="Convenient alias for Application smart pointer.">ApplicationPtr</a>;
439
- <a name="l00422"></a>00422
440
- <a name="l00423"></a>00423 } <span class="comment">// namespace Passenger</span>
441
- <a name="l00424"></a>00424
442
- <a name="l00425"></a>00425 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_APPLICATION_H_ */</span>
326
+ <a name="l00310"></a>00310 <span class="keyword">virtual</span> <span class="keywordtype">void</span> discardStream() {
327
+ <a name="l00311"></a>00311 fd = -1;
328
+ <a name="l00312"></a>00312 }
329
+ <a name="l00313"></a>00313
330
+ <a name="l00314"></a>00314 <span class="keyword">virtual</span> pid_t <a class="code" href="classPassenger_1_1Application.html#94d2cce1c2c1d3441325f1498a22bf02" title="Returns the process ID of this application instance.">getPid</a>()<span class="keyword"> const </span>{
331
+ <a name="l00315"></a>00315 <span class="keywordflow">return</span> pid;
332
+ <a name="l00316"></a>00316 }
333
+ <a name="l00317"></a>00317 };
334
+ <a name="l00318"></a>00318
335
+ <a name="l00319"></a>00319 <span class="keywordtype">string</span> appRoot;
336
+ <a name="l00320"></a>00320 pid_t pid;
337
+ <a name="l00321"></a>00321 <span class="keywordtype">string</span> listenSocketName;
338
+ <a name="l00322"></a>00322 <span class="keywordtype">string</span> listenSocketType;
339
+ <a name="l00323"></a>00323 <span class="keywordtype">int</span> ownerPipe;
340
+ <a name="l00324"></a>00324
341
+ <a name="l00325"></a>00325 <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">SessionPtr</a> connectToUnixServer(<span class="keyword">const</span> function&lt;<span class="keywordtype">void</span>()&gt; &amp;closeCallback)<span class="keyword"> const </span>{
342
+ <a name="l00326"></a>00326 TRACE_POINT();
343
+ <a name="l00327"></a>00327 <span class="keywordtype">int</span> fd, ret;
344
+ <a name="l00328"></a>00328
345
+ <a name="l00329"></a>00329 <span class="keywordflow">do</span> {
346
+ <a name="l00330"></a>00330 fd = socket(PF_UNIX, SOCK_STREAM, 0);
347
+ <a name="l00331"></a>00331 } <span class="keywordflow">while</span> (fd == -1 &amp;&amp; errno == EINTR);
348
+ <a name="l00332"></a>00332 <span class="keywordflow">if</span> (fd == -1) {
349
+ <a name="l00333"></a>00333 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">"Cannot create a new unconnected Unix socket"</span>, errno);
350
+ <a name="l00334"></a>00334 }
351
+ <a name="l00335"></a>00335
352
+ <a name="l00336"></a>00336 <span class="keyword">struct </span>sockaddr_un addr;
353
+ <a name="l00337"></a>00337 addr.sun_family = AF_UNIX;
354
+ <a name="l00338"></a>00338 strncpy(addr.sun_path, listenSocketName.c_str(), <span class="keyword">sizeof</span>(addr.sun_path));
355
+ <a name="l00339"></a>00339 addr.sun_path[<span class="keyword">sizeof</span>(addr.sun_path) - 1] = <span class="charliteral">'\0'</span>;
356
+ <a name="l00340"></a>00340 <span class="keywordflow">do</span> {
357
+ <a name="l00341"></a>00341 ret =<a class="code" href="classPassenger_1_1Application.html#34636f796ff3924ad5ec142aaa581379" title="Connect to this application instance with the purpose of sending a request to the..."> ::connect</a>(fd, (<span class="keyword">const</span> sockaddr *) &amp;addr, <span class="keyword">sizeof</span>(addr));
358
+ <a name="l00342"></a>00342 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
359
+ <a name="l00343"></a>00343 <span class="keywordflow">if</span> (ret == -1) {
360
+ <a name="l00344"></a>00344 <span class="keywordtype">int</span> e = errno;
361
+ <a name="l00345"></a>00345 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot connect to Unix socket '"</span>);
362
+ <a name="l00346"></a>00346 message.append(listenSocketName);
363
+ <a name="l00347"></a>00347 message.append(<span class="stringliteral">"'"</span>);
364
+ <a name="l00348"></a>00348 <span class="keywordflow">do</span> {
365
+ <a name="l00349"></a>00349 ret = close(fd);
366
+ <a name="l00350"></a>00350 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
367
+ <a name="l00351"></a>00351 <span class="keywordflow">throw</span> SystemException(message, e);
368
+ <a name="l00352"></a>00352 }
369
+ <a name="l00353"></a>00353
370
+ <a name="l00354"></a>00354 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> StandardSession(pid, closeCallback, fd));
371
+ <a name="l00355"></a>00355 }
372
+ <a name="l00356"></a>00356
373
+ <a name="l00357"></a>00357 <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">SessionPtr</a> connectToTcpServer(<span class="keyword">const</span> function&lt;<span class="keywordtype">void</span>()&gt; &amp;closeCallback)<span class="keyword"> const </span>{
374
+ <a name="l00358"></a>00358 TRACE_POINT();
375
+ <a name="l00359"></a>00359 <span class="keywordtype">int</span> fd, ret;
376
+ <a name="l00360"></a>00360 vector&lt;string&gt; args;
377
+ <a name="l00361"></a>00361
378
+ <a name="l00362"></a>00362 <a class="code" href="group__Support.html#g4b8320aedc6a164a535c920234e3d8bf" title="Split the given string using the given separator.">split</a>(listenSocketName, <span class="charliteral">':'</span>, args);
379
+ <a name="l00363"></a>00363 <span class="keywordflow">if</span> (args.size() != 2 || <a class="code" href="group__Support.html#g73b17b509ee44938a56bf16cbf82fb48" title="Converts the given string to an integer.">atoi</a>(args[1]) == 0) {
380
+ <a name="l00364"></a>00364 <span class="keywordflow">throw</span> IOException(<span class="stringliteral">"Invalid TCP/IP address '"</span> + listenSocketName + <span class="stringliteral">"'"</span>);
381
+ <a name="l00365"></a>00365 }
382
+ <a name="l00366"></a>00366
383
+ <a name="l00367"></a>00367 <span class="keyword">struct </span>addrinfo hints, *res;
384
+ <a name="l00368"></a>00368
385
+ <a name="l00369"></a>00369 memset(&amp;hints, 0, <span class="keyword">sizeof</span>(hints));
386
+ <a name="l00370"></a>00370 hints.ai_family = PF_INET;
387
+ <a name="l00371"></a>00371 hints.ai_socktype = SOCK_STREAM;
388
+ <a name="l00372"></a>00372 ret = getaddrinfo(args[0].c_str(), args[1].c_str(), &amp;hints, &amp;res);
389
+ <a name="l00373"></a>00373 <span class="keywordflow">if</span> (ret != 0) {
390
+ <a name="l00374"></a>00374 <span class="keywordtype">int</span> e = errno;
391
+ <a name="l00375"></a>00375 <span class="keywordflow">throw</span> IOException(<span class="stringliteral">"Cannot resolve address '"</span> + listenSocketName +
392
+ <a name="l00376"></a>00376 <span class="stringliteral">"': "</span> + gai_strerror(e));
393
+ <a name="l00377"></a>00377 }
394
+ <a name="l00378"></a>00378
395
+ <a name="l00379"></a>00379 <span class="keywordflow">do</span> {
396
+ <a name="l00380"></a>00380 fd = socket(PF_INET, SOCK_STREAM, 0);
397
+ <a name="l00381"></a>00381 } <span class="keywordflow">while</span> (fd == -1 &amp;&amp; errno == EINTR);
398
+ <a name="l00382"></a>00382 <span class="keywordflow">if</span> (fd == -1) {
399
+ <a name="l00383"></a>00383 freeaddrinfo(res);
400
+ <a name="l00384"></a>00384 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">"Cannot create a new unconnected TCP socket"</span>, errno);
401
+ <a name="l00385"></a>00385 }
402
+ <a name="l00386"></a>00386
403
+ <a name="l00387"></a>00387 <span class="keywordflow">do</span> {
404
+ <a name="l00388"></a>00388 ret =<a class="code" href="classPassenger_1_1Application.html#34636f796ff3924ad5ec142aaa581379" title="Connect to this application instance with the purpose of sending a request to the..."> ::connect</a>(fd, res-&gt;ai_addr, res-&gt;ai_addrlen);
405
+ <a name="l00389"></a>00389 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
406
+ <a name="l00390"></a>00390 freeaddrinfo(res);
407
+ <a name="l00391"></a>00391 <span class="keywordflow">if</span> (ret == -1) {
408
+ <a name="l00392"></a>00392 <span class="keywordtype">int</span> e = errno;
409
+ <a name="l00393"></a>00393 <span class="keywordtype">string</span> message(<span class="stringliteral">"Cannot connect to TCP server '"</span>);
410
+ <a name="l00394"></a>00394 message.append(listenSocketName);
411
+ <a name="l00395"></a>00395 message.append(<span class="stringliteral">"'"</span>);
412
+ <a name="l00396"></a>00396 <span class="keywordflow">do</span> {
413
+ <a name="l00397"></a>00397 ret = close(fd);
414
+ <a name="l00398"></a>00398 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
415
+ <a name="l00399"></a>00399 <span class="keywordflow">throw</span> SystemException(message, e);
416
+ <a name="l00400"></a>00400 }
417
+ <a name="l00401"></a>00401
418
+ <a name="l00402"></a>00402 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#g41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> StandardSession(pid, closeCallback, fd));
419
+ <a name="l00403"></a>00403 }
420
+ <a name="l00404"></a>00404
421
+ <a name="l00405"></a>00405 <span class="keyword">public</span>:<span class="comment"></span>
422
+ <a name="l00406"></a>00406 <span class="comment"> /**</span>
423
+ <a name="l00407"></a>00407 <span class="comment"> * Construct a new Application object.</span>
424
+ <a name="l00408"></a>00408 <span class="comment"> *</span>
425
+ <a name="l00409"></a>00409 <span class="comment"> * @param theAppRoot The application root of an application. In case of a Rails application,</span>
426
+ <a name="l00410"></a>00410 <span class="comment"> * this is the folder that contains 'app/', 'public/', 'config/', etc.</span>
427
+ <a name="l00411"></a>00411 <span class="comment"> * This must be a valid directory, but the path does not have to be absolute.</span>
428
+ <a name="l00412"></a>00412 <span class="comment"> * @param pid The process ID of this application instance.</span>
429
+ <a name="l00413"></a>00413 <span class="comment"> * @param listenSocketName The name of the listener socket of this application instance.</span>
430
+ <a name="l00414"></a>00414 <span class="comment"> * @param listenSocketType The type of the listener socket, e.g. "unix" for Unix</span>
431
+ <a name="l00415"></a>00415 <span class="comment"> * domain sockets.</span>
432
+ <a name="l00416"></a>00416 <span class="comment"> * @param ownerPipe The owner pipe of this application instance.</span>
433
+ <a name="l00417"></a>00417 <span class="comment"> * @post getAppRoot() == theAppRoot &amp;&amp; getPid() == pid</span>
434
+ <a name="l00418"></a>00418 <span class="comment"> */</span>
435
+ <a name="l00419"></a><a class="code" href="classPassenger_1_1Application.html#0ae83471a8c991b8cc8d460b44d237ea">00419</a> <a class="code" href="classPassenger_1_1Application.html#0ae83471a8c991b8cc8d460b44d237ea" title="Construct a new Application object.">Application</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;theAppRoot, pid_t pid, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;listenSocketName,
436
+ <a name="l00420"></a>00420 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;listenSocketType, <span class="keywordtype">int</span> ownerPipe) {
437
+ <a name="l00421"></a>00421 appRoot = theAppRoot;
438
+ <a name="l00422"></a>00422 this-&gt;pid = pid;
439
+ <a name="l00423"></a>00423 this-&gt;listenSocketName = listenSocketName;
440
+ <a name="l00424"></a>00424 this-&gt;listenSocketType = listenSocketType;
441
+ <a name="l00425"></a>00425 this-&gt;ownerPipe = ownerPipe;
442
+ <a name="l00426"></a>00426 P_TRACE(3, <span class="stringliteral">"Application "</span> &lt;&lt; <span class="keyword">this</span> &lt;&lt; <span class="stringliteral">": created."</span>);
443
+ <a name="l00427"></a>00427 }
444
+ <a name="l00428"></a>00428
445
+ <a name="l00429"></a>00429 <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1Application.html" title="Represents a single Ruby on Rails or Rack application instance.">Application</a>() {
446
+ <a name="l00430"></a>00430 TRACE_POINT();
447
+ <a name="l00431"></a>00431 <span class="keywordtype">int</span> ret;
448
+ <a name="l00432"></a>00432
449
+ <a name="l00433"></a>00433 <span class="keywordflow">if</span> (ownerPipe != -1) {
450
+ <a name="l00434"></a>00434 <span class="keywordflow">do</span> {
451
+ <a name="l00435"></a>00435 ret = close(ownerPipe);
452
+ <a name="l00436"></a>00436 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
453
+ <a name="l00437"></a>00437 }
454
+ <a name="l00438"></a>00438 <span class="keywordflow">if</span> (listenSocketType == <span class="stringliteral">"unix"</span>) {
455
+ <a name="l00439"></a>00439 <span class="keywordflow">do</span> {
456
+ <a name="l00440"></a>00440 ret = unlink(listenSocketName.c_str());
457
+ <a name="l00441"></a>00441 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
458
+ <a name="l00442"></a>00442 }
459
+ <a name="l00443"></a>00443 P_TRACE(3, <span class="stringliteral">"Application "</span> &lt;&lt; <span class="keyword">this</span> &lt;&lt; <span class="stringliteral">": destroyed."</span>);
460
+ <a name="l00444"></a>00444 }
461
+ <a name="l00445"></a>00445 <span class="comment"></span>
462
+ <a name="l00446"></a>00446 <span class="comment"> /**</span>
463
+ <a name="l00447"></a>00447 <span class="comment"> * Returns the application root for this application. See the constructor</span>
464
+ <a name="l00448"></a>00448 <span class="comment"> * for information about the application root.</span>
465
+ <a name="l00449"></a>00449 <span class="comment"> */</span>
466
+ <a name="l00450"></a><a class="code" href="classPassenger_1_1Application.html#0a0665852e7ebc8fb8ab0772fa90bc56">00450</a> <span class="keywordtype">string</span> <a class="code" href="classPassenger_1_1Application.html#0a0665852e7ebc8fb8ab0772fa90bc56" title="Returns the application root for this application.">getAppRoot</a>()<span class="keyword"> const </span>{
467
+ <a name="l00451"></a>00451 <span class="keywordflow">return</span> appRoot;
468
+ <a name="l00452"></a>00452 }
469
+ <a name="l00453"></a>00453 <span class="comment"></span>
470
+ <a name="l00454"></a>00454 <span class="comment"> /**</span>
471
+ <a name="l00455"></a>00455 <span class="comment"> * Returns the process ID of this application instance.</span>
472
+ <a name="l00456"></a>00456 <span class="comment"> */</span>
473
+ <a name="l00457"></a><a class="code" href="classPassenger_1_1Application.html#94d2cce1c2c1d3441325f1498a22bf02">00457</a> pid_t <a class="code" href="classPassenger_1_1Application.html#94d2cce1c2c1d3441325f1498a22bf02" title="Returns the process ID of this application instance.">getPid</a>()<span class="keyword"> const </span>{
474
+ <a name="l00458"></a>00458 <span class="keywordflow">return</span> pid;
475
+ <a name="l00459"></a>00459 }
476
+ <a name="l00460"></a>00460 <span class="comment"></span>
477
+ <a name="l00461"></a>00461 <span class="comment"> /**</span>
478
+ <a name="l00462"></a>00462 <span class="comment"> * Connect to this application instance with the purpose of sending</span>
479
+ <a name="l00463"></a>00463 <span class="comment"> * a request to the application. Once connected, a new session will</span>
480
+ <a name="l00464"></a>00464 <span class="comment"> * be opened. This session represents the life time of a single</span>
481
+ <a name="l00465"></a>00465 <span class="comment"> * request/response pair, and can be used to send the request</span>
482
+ <a name="l00466"></a>00466 <span class="comment"> * data to the application instance, as well as receiving the response</span>
483
+ <a name="l00467"></a>00467 <span class="comment"> * data.</span>
484
+ <a name="l00468"></a>00468 <span class="comment"> *</span>
485
+ <a name="l00469"></a>00469 <span class="comment"> * The use of connect() is demonstrated in the following example.</span>
486
+ <a name="l00470"></a>00470 <span class="comment"> * @code</span>
487
+ <a name="l00471"></a>00471 <span class="comment"> * // Connect to the application and get the newly opened session.</span>
488
+ <a name="l00472"></a>00472 <span class="comment"> * Application::SessionPtr session(app-&gt;connect("/home/webapps/foo"));</span>
489
+ <a name="l00473"></a>00473 <span class="comment"> * </span>
490
+ <a name="l00474"></a>00474 <span class="comment"> * // Send the request headers and request body data.</span>
491
+ <a name="l00475"></a>00475 <span class="comment"> * session-&gt;sendHeaders(...);</span>
492
+ <a name="l00476"></a>00476 <span class="comment"> * session-&gt;sendBodyBlock(...);</span>
493
+ <a name="l00477"></a>00477 <span class="comment"> * // Done sending data, so we close the writer channel.</span>
494
+ <a name="l00478"></a>00478 <span class="comment"> * session-&gt;closeWriter();</span>
495
+ <a name="l00479"></a>00479 <span class="comment"> *</span>
496
+ <a name="l00480"></a>00480 <span class="comment"> * // Now read the HTTP response.</span>
497
+ <a name="l00481"></a>00481 <span class="comment"> * string responseData = readAllDataFromSocket(session-&gt;getReader());</span>
498
+ <a name="l00482"></a>00482 <span class="comment"> * // Done reading data, so we close the reader channel.</span>
499
+ <a name="l00483"></a>00483 <span class="comment"> * session-&gt;closeReader();</span>
500
+ <a name="l00484"></a>00484 <span class="comment"> *</span>
501
+ <a name="l00485"></a>00485 <span class="comment"> * // This session has now finished, so we close the session by resetting</span>
502
+ <a name="l00486"></a>00486 <span class="comment"> * // the smart pointer to NULL (thereby destroying the Session object).</span>
503
+ <a name="l00487"></a>00487 <span class="comment"> * session.reset();</span>
504
+ <a name="l00488"></a>00488 <span class="comment"> *</span>
505
+ <a name="l00489"></a>00489 <span class="comment"> * // We can connect to an Application multiple times. Just make sure</span>
506
+ <a name="l00490"></a>00490 <span class="comment"> * // the previous session is closed.</span>
507
+ <a name="l00491"></a>00491 <span class="comment"> * session = app-&gt;connect("/home/webapps/bar")</span>
508
+ <a name="l00492"></a>00492 <span class="comment"> * @endcode</span>
509
+ <a name="l00493"></a>00493 <span class="comment"> *</span>
510
+ <a name="l00494"></a>00494 <span class="comment"> * Note that a RoR application instance can only process one</span>
511
+ <a name="l00495"></a>00495 <span class="comment"> * request at the same time, and thus only one session at the same time.</span>
512
+ <a name="l00496"></a>00496 <span class="comment"> * It's unspecified whether Rack applications can handle multiple simultanous sessions.</span>
513
+ <a name="l00497"></a>00497 <span class="comment"> *</span>
514
+ <a name="l00498"></a>00498 <span class="comment"> * You &lt;b&gt;must&lt;/b&gt; close a session when you no longer need if. If you</span>
515
+ <a name="l00499"></a>00499 <span class="comment"> * call connect() without having properly closed a previous session,</span>
516
+ <a name="l00500"></a>00500 <span class="comment"> * you might cause a deadlock because the application instance may be</span>
517
+ <a name="l00501"></a>00501 <span class="comment"> * waiting for you to close the previous session.</span>
518
+ <a name="l00502"></a>00502 <span class="comment"> *</span>
519
+ <a name="l00503"></a>00503 <span class="comment"> * @return A smart pointer to a Session object, which represents the created session.</span>
520
+ <a name="l00504"></a>00504 <span class="comment"> * @param closeCallback A function which will be called when the session has been closed.</span>
521
+ <a name="l00505"></a>00505 <span class="comment"> * @post this-&gt;getSessions() == old-&gt;getSessions() + 1</span>
522
+ <a name="l00506"></a>00506 <span class="comment"> * @throws SystemException Something went wrong during the connection process.</span>
523
+ <a name="l00507"></a>00507 <span class="comment"> * @throws IOException Something went wrong during the connection process.</span>
524
+ <a name="l00508"></a>00508 <span class="comment"> */</span>
525
+ <a name="l00509"></a><a class="code" href="classPassenger_1_1Application.html#34636f796ff3924ad5ec142aaa581379">00509</a> <a class="code" href="classPassenger_1_1Application.html#d14f673494991460b16246a527ad8ad9" title="Convenient alias for Session smart pointer.">SessionPtr</a> <a class="code" href="classPassenger_1_1Application.html#34636f796ff3924ad5ec142aaa581379" title="Connect to this application instance with the purpose of sending a request to the...">connect</a>(<span class="keyword">const</span> function&lt;<span class="keywordtype">void</span>()&gt; &amp;closeCallback)<span class="keyword"> const </span>{
526
+ <a name="l00510"></a>00510 TRACE_POINT();
527
+ <a name="l00511"></a>00511 <span class="keywordflow">if</span> (listenSocketType == <span class="stringliteral">"unix"</span>) {
528
+ <a name="l00512"></a>00512 <span class="keywordflow">return</span> connectToUnixServer(closeCallback);
529
+ <a name="l00513"></a>00513 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (listenSocketType == <span class="stringliteral">"tcp"</span>) {
530
+ <a name="l00514"></a>00514 <span class="keywordflow">return</span> connectToTcpServer(closeCallback);
531
+ <a name="l00515"></a>00515 } <span class="keywordflow">else</span> {
532
+ <a name="l00516"></a>00516 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1IOException.html" title="Represents an error that occured during an I/O operation.">IOException</a>(<span class="stringliteral">"Unsupported socket type '"</span> + listenSocketType + <span class="stringliteral">"'"</span>);
533
+ <a name="l00517"></a>00517 }
534
+ <a name="l00518"></a>00518 }
535
+ <a name="l00519"></a>00519 };
536
+ <a name="l00520"></a>00520 <span class="comment"></span>
537
+ <a name="l00521"></a>00521 <span class="comment">/** Convenient alias for Application smart pointer. */</span>
538
+ <a name="l00522"></a>00522 <span class="keyword">typedef</span> shared_ptr&lt;Application&gt; ApplicationPtr;
539
+ <a name="l00523"></a>00523
540
+ <a name="l00524"></a>00524 } <span class="comment">// namespace Passenger</span>
541
+ <a name="l00525"></a>00525
542
+ <a name="l00526"></a>00526 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_APPLICATION_H_ */</span>
443
543
  </pre></div></div>
444
- <hr size="1"><address style="text-align: right;"><small>Generated on Mon Dec 15 15:27:24 2008 for Passenger by&nbsp;
544
+ <hr size="1"><address style="text-align: right;"><small>Generated on Fri Mar 13 19:24:32 2009 for Passenger by&nbsp;
445
545
  <a href="http://www.doxygen.org/index.html">
446
546
  <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
447
547
  </body>