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
@@ -0,0 +1,130 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
+ <html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
3
+ <title>Passenger: FileChecker.h Source File</title>
4
+ <link href="doxygen.css" rel="stylesheet" type="text/css">
5
+ <link href="tabs.css" rel="stylesheet" type="text/css">
6
+ </head><body>
7
+ <!-- Generated by Doxygen 1.5.5 -->
8
+ <div class="navigation" id="top">
9
+ <div class="tabs">
10
+ <ul>
11
+ <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
12
+ <li><a href="modules.html"><span>Modules</span></a></li>
13
+ <li><a href="annotated.html"><span>Classes</span></a></li>
14
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
15
+ </ul>
16
+ </div>
17
+ <h1>FileChecker.h</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
18
+ <a name="l00002"></a>00002 <span class="comment"> * Phusion Passenger - http://www.modrails.com/</span>
19
+ <a name="l00003"></a>00003 <span class="comment"> * Copyright (C) 2009 Phusion</span>
20
+ <a name="l00004"></a>00004 <span class="comment"> *</span>
21
+ <a name="l00005"></a>00005 <span class="comment"> * Phusion Passenger is a trademark of Hongli Lai &amp; Ninh Bui.</span>
22
+ <a name="l00006"></a>00006 <span class="comment"> *</span>
23
+ <a name="l00007"></a>00007 <span class="comment"> * This program is free software; you can redistribute it and/or modify</span>
24
+ <a name="l00008"></a>00008 <span class="comment"> * it under the terms of the GNU General Public License as published by</span>
25
+ <a name="l00009"></a>00009 <span class="comment"> * the Free Software Foundation; version 2 of the License.</span>
26
+ <a name="l00010"></a>00010 <span class="comment"> *</span>
27
+ <a name="l00011"></a>00011 <span class="comment"> * This program is distributed in the hope that it will be useful,</span>
28
+ <a name="l00012"></a>00012 <span class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
29
+ <a name="l00013"></a>00013 <span class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
30
+ <a name="l00014"></a>00014 <span class="comment"> * GNU General Public License for more details.</span>
31
+ <a name="l00015"></a>00015 <span class="comment"> *</span>
32
+ <a name="l00016"></a>00016 <span class="comment"> * You should have received a copy of the GNU General Public License along</span>
33
+ <a name="l00017"></a>00017 <span class="comment"> * with this program; if not, write to the Free Software Foundation, Inc.,</span>
34
+ <a name="l00018"></a>00018 <span class="comment"> * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span>
35
+ <a name="l00019"></a>00019 <span class="comment"> */</span>
36
+ <a name="l00020"></a>00020 <span class="preprocessor">#ifndef _PASSENGER_FILE_CHECKER_H_</span>
37
+ <a name="l00021"></a>00021 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_FILE_CHECKER_H_</span>
38
+ <a name="l00022"></a>00022 <span class="preprocessor"></span>
39
+ <a name="l00023"></a>00023 <span class="preprocessor">#include &lt;string&gt;</span>
40
+ <a name="l00024"></a>00024
41
+ <a name="l00025"></a>00025 <span class="preprocessor">#include &lt;oxt/system_calls.hpp&gt;</span>
42
+ <a name="l00026"></a>00026
43
+ <a name="l00027"></a>00027 <span class="preprocessor">#include &lt;sys/stat.h&gt;</span>
44
+ <a name="l00028"></a>00028 <span class="preprocessor">#include &lt;errno.h&gt;</span>
45
+ <a name="l00029"></a>00029
46
+ <a name="l00030"></a>00030 <span class="preprocessor">#include "CachedFileStat.h"</span>
47
+ <a name="l00031"></a>00031 <span class="preprocessor">#include "SystemTime.h"</span>
48
+ <a name="l00032"></a>00032
49
+ <a name="l00033"></a>00033 <span class="keyword">namespace </span>Passenger {
50
+ <a name="l00034"></a>00034
51
+ <a name="l00035"></a>00035 <span class="keyword">using namespace </span>std;
52
+ <a name="l00036"></a>00036 <span class="keyword">using namespace </span>oxt;
53
+ <a name="l00037"></a>00037 <span class="comment"></span>
54
+ <a name="l00038"></a>00038 <span class="comment">/**</span>
55
+ <a name="l00039"></a>00039 <span class="comment"> * Utility class for checking for file changes. Example:</span>
56
+ <a name="l00040"></a>00040 <span class="comment"> *</span>
57
+ <a name="l00041"></a>00041 <span class="comment"> * @code</span>
58
+ <a name="l00042"></a>00042 <span class="comment"> * FileChecker checker("foo.txt");</span>
59
+ <a name="l00043"></a>00043 <span class="comment"> * checker.changed(); // false</span>
60
+ <a name="l00044"></a>00044 <span class="comment"> * writeToFile("foo.txt");</span>
61
+ <a name="l00045"></a>00045 <span class="comment"> * checker.changed(); // true</span>
62
+ <a name="l00046"></a>00046 <span class="comment"> * checker.changed(); // false</span>
63
+ <a name="l00047"></a>00047 <span class="comment"> * @endcode</span>
64
+ <a name="l00048"></a>00048 <span class="comment"> *</span>
65
+ <a name="l00049"></a>00049 <span class="comment"> * FileChecker uses stat() to retrieve file information. FileChecker also</span>
66
+ <a name="l00050"></a>00050 <span class="comment"> * supports throttling in order to limit the number of stat() calls. This</span>
67
+ <a name="l00051"></a>00051 <span class="comment"> * can improve performance on systems where disk I/O is a problem.</span>
68
+ <a name="l00052"></a>00052 <span class="comment"> */</span>
69
+ <a name="l00053"></a><a class="code" href="classPassenger_1_1FileChecker.html">00053</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1FileChecker.html" title="Utility class for checking for file changes.">FileChecker</a> {
70
+ <a name="l00054"></a>00054 <span class="keyword">private</span>:
71
+ <a name="l00055"></a>00055 CachedFileStat cstat;
72
+ <a name="l00056"></a>00056 time_t lastMtime;
73
+ <a name="l00057"></a>00057 time_t lastCtime;
74
+ <a name="l00058"></a>00058
75
+ <a name="l00059"></a>00059 <span class="keyword">public</span>:<span class="comment"></span>
76
+ <a name="l00060"></a>00060 <span class="comment"> /**</span>
77
+ <a name="l00061"></a>00061 <span class="comment"> * Create a FileChecker object.</span>
78
+ <a name="l00062"></a>00062 <span class="comment"> *</span>
79
+ <a name="l00063"></a>00063 <span class="comment"> * @param filename The filename to check for.</span>
80
+ <a name="l00064"></a>00064 <span class="comment"> */</span>
81
+ <a name="l00065"></a><a class="code" href="classPassenger_1_1FileChecker.html#64556bc7e06a32363dbd87451d459b71">00065</a> <a class="code" href="classPassenger_1_1FileChecker.html#64556bc7e06a32363dbd87451d459b71" title="Create a FileChecker object.">FileChecker</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;filename)
82
+ <a name="l00066"></a>00066 : cstat(filename)
83
+ <a name="l00067"></a>00067 {
84
+ <a name="l00068"></a>00068 lastMtime = 0;
85
+ <a name="l00069"></a>00069 lastCtime = 0;
86
+ <a name="l00070"></a>00070 <a class="code" href="classPassenger_1_1FileChecker.html#832ff27b4b3e5db84a9d986285e7c270" title="Checks whether the file&amp;#39;s timestamp has changed or has been created or removed...">changed</a>();
87
+ <a name="l00071"></a>00071 }
88
+ <a name="l00072"></a>00072 <span class="comment"></span>
89
+ <a name="l00073"></a>00073 <span class="comment"> /**</span>
90
+ <a name="l00074"></a>00074 <span class="comment"> * Checks whether the file's timestamp has changed or has been created</span>
91
+ <a name="l00075"></a>00075 <span class="comment"> * or removed since the last call to changed().</span>
92
+ <a name="l00076"></a>00076 <span class="comment"> *</span>
93
+ <a name="l00077"></a>00077 <span class="comment"> * @param throttleRate When set to a non-zero value, throttling will be</span>
94
+ <a name="l00078"></a>00078 <span class="comment"> * enabled. stat() will be called at most once per</span>
95
+ <a name="l00079"></a>00079 <span class="comment"> * throttleRate seconds.</span>
96
+ <a name="l00080"></a>00080 <span class="comment"> * @throws SystemException Something went wrong.</span>
97
+ <a name="l00081"></a>00081 <span class="comment"> * @throws boost::thread_interrupted</span>
98
+ <a name="l00082"></a>00082 <span class="comment"> */</span>
99
+ <a name="l00083"></a><a class="code" href="classPassenger_1_1FileChecker.html#832ff27b4b3e5db84a9d986285e7c270">00083</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1FileChecker.html#832ff27b4b3e5db84a9d986285e7c270" title="Checks whether the file&amp;#39;s timestamp has changed or has been created or removed...">changed</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> throttleRate = 0) {
100
+ <a name="l00084"></a>00084 <span class="keywordtype">int</span> ret;
101
+ <a name="l00085"></a>00085 time_t ctime, mtime;
102
+ <a name="l00086"></a>00086 <span class="keywordtype">bool</span> result;
103
+ <a name="l00087"></a>00087
104
+ <a name="l00088"></a>00088 <span class="keywordflow">do</span> {
105
+ <a name="l00089"></a>00089 ret = cstat.refresh(throttleRate);
106
+ <a name="l00090"></a>00090 } <span class="keywordflow">while</span> (ret == -1 &amp;&amp; errno == EINTR);
107
+ <a name="l00091"></a>00091
108
+ <a name="l00092"></a>00092 <span class="keywordflow">if</span> (ret == -1) {
109
+ <a name="l00093"></a>00093 ctime = 0;
110
+ <a name="l00094"></a>00094 mtime = 0;
111
+ <a name="l00095"></a>00095 } <span class="keywordflow">else</span> {
112
+ <a name="l00096"></a>00096 ctime = cstat.info.st_ctime;
113
+ <a name="l00097"></a>00097 mtime = cstat.info.st_mtime;
114
+ <a name="l00098"></a>00098 }
115
+ <a name="l00099"></a>00099 result = lastMtime != mtime || lastCtime != ctime;
116
+ <a name="l00100"></a>00100 lastMtime = mtime;
117
+ <a name="l00101"></a>00101 lastCtime = ctime;
118
+ <a name="l00102"></a>00102 <span class="keywordflow">return</span> result;
119
+ <a name="l00103"></a>00103 }
120
+ <a name="l00104"></a>00104 };
121
+ <a name="l00105"></a>00105
122
+ <a name="l00106"></a>00106 } <span class="comment">// namespace Passenger</span>
123
+ <a name="l00107"></a>00107
124
+ <a name="l00108"></a>00108 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_FILE_CHECKER_H_ */</span>
125
+ </pre></div></div>
126
+ <hr size="1"><address style="text-align: right;"><small>Generated on Fri Mar 13 19:24:32 2009 for Passenger by&nbsp;
127
+ <a href="http://www.doxygen.org/index.html">
128
+ <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
129
+ </body>
130
+ </html>
@@ -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>
@@ -48,7 +47,7 @@
48
47
  <a name="l00031"></a>00031 <span class="comment"> * @ingroup Core</span>
49
48
  <a name="l00032"></a>00032 <span class="comment"> */</span>
50
49
  <a name="l00033"></a>00033
51
- <a name="l00034"></a>00034 <span class="keyword">extern</span> <span class="keywordtype">void</span> <a class="code" href="group__Hooks.html#g9d8409a5d1bee7cbe4568fac5a5ae4b3" title="Apache hook registration function.">passenger_register_hooks</a>(apr_pool_t *p);
50
+ <a name="l00034"></a>00034 <span class="keyword">extern</span> <span class="keywordtype">void</span> passenger_register_hooks(apr_pool_t *p);
52
51
  <a name="l00035"></a>00035
53
52
  <a name="l00036"></a>00036 <span class="preprocessor">#ifdef __cplusplus</span>
54
53
  <a name="l00037"></a>00037 <span class="preprocessor"></span>}
@@ -56,7 +55,7 @@
56
55
  <a name="l00039"></a>00039 <span class="preprocessor"></span>
57
56
  <a name="l00040"></a>00040 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_HOOKS_H_ */</span>
58
57
  </pre></div></div>
59
- <hr size="1"><address style="text-align: right;"><small>Generated on Mon Dec 15 15:27:24 2008 for Passenger by&nbsp;
58
+ <hr size="1"><address style="text-align: right;"><small>Generated on Fri Mar 13 19:24:32 2009 for Passenger by&nbsp;
60
59
  <a href="http://www.doxygen.org/index.html">
61
60
  <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
62
61
  </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>
@@ -41,95 +40,99 @@
41
40
  <a name="l00024"></a>00024 <span class="preprocessor">#include &lt;sys/time.h&gt;</span>
42
41
  <a name="l00025"></a>00025 <span class="preprocessor">#include &lt;unistd.h&gt;</span>
43
42
  <a name="l00026"></a>00026 <span class="preprocessor">#include &lt;ostream&gt;</span>
44
- <a name="l00027"></a>00027 <span class="preprocessor">#include &lt;ctime&gt;</span>
45
- <a name="l00028"></a>00028
46
- <a name="l00029"></a>00029 <span class="keyword">namespace </span>Passenger {
47
- <a name="l00030"></a>00030
48
- <a name="l00031"></a>00031 <span class="keyword">using namespace </span>std;
49
- <a name="l00032"></a>00032
50
- <a name="l00033"></a>00033 <span class="keyword">extern</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> _logLevel;
51
- <a name="l00034"></a>00034 <span class="keyword">extern</span> ostream *_logStream;
52
- <a name="l00035"></a>00035 <span class="keyword">extern</span> ostream *_debugStream;
53
- <a name="l00036"></a>00036
54
- <a name="l00037"></a>00037 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getLogLevel();
55
- <a name="l00038"></a>00038 <span class="keywordtype">void</span> setLogLevel(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> value);
56
- <a name="l00039"></a>00039 <span class="keywordtype">void</span> setDebugFile(<span class="keyword">const</span> <span class="keywordtype">char</span> *logFile = NULL);
57
- <a name="l00040"></a>00040 <span class="comment"></span>
58
- <a name="l00041"></a>00041 <span class="comment">/**</span>
59
- <a name="l00042"></a>00042 <span class="comment"> * Write the given expression to the log stream.</span>
60
- <a name="l00043"></a>00043 <span class="comment"> */</span>
61
- <a name="l00044"></a>00044 <span class="preprocessor">#define P_LOG(expr) \</span>
62
- <a name="l00045"></a>00045 <span class="preprocessor"> do { \</span>
63
- <a name="l00046"></a>00046 <span class="preprocessor"> if (Passenger::_logStream != 0) { \</span>
64
- <a name="l00047"></a>00047 <span class="preprocessor"> time_t the_time = time(NULL); \</span>
65
- <a name="l00048"></a>00048 <span class="preprocessor"> struct tm *the_tm = localtime(&amp;the_time); \</span>
66
- <a name="l00049"></a>00049 <span class="preprocessor"> char datetime_buf[60]; \</span>
67
- <a name="l00050"></a>00050 <span class="preprocessor"> struct timeval tv; \</span>
68
- <a name="l00051"></a>00051 <span class="preprocessor"> strftime(datetime_buf, sizeof(datetime_buf), "%x %H:%M:%S", the_tm); \</span>
69
- <a name="l00052"></a>00052 <span class="preprocessor"> gettimeofday(&amp;tv, NULL); \</span>
70
- <a name="l00053"></a>00053 <span class="preprocessor"> *Passenger::_logStream &lt;&lt; \</span>
71
- <a name="l00054"></a>00054 <span class="preprocessor"> "[ pid=" &lt;&lt; getpid() &lt;&lt; " file=" &lt;&lt; __FILE__ &lt;&lt; ":" &lt;&lt; __LINE__ &lt;&lt; \</span>
72
- <a name="l00055"></a>00055 <span class="preprocessor"> " time=" &lt;&lt; datetime_buf &lt;&lt; "." &lt;&lt; (tv.tv_usec / 1000) &lt;&lt; " ]:" &lt;&lt; \</span>
73
- <a name="l00056"></a>00056 <span class="preprocessor"> "\n " &lt;&lt; expr &lt;&lt; std::endl; \</span>
74
- <a name="l00057"></a>00057 <span class="preprocessor"> } \</span>
75
- <a name="l00058"></a>00058 <span class="preprocessor"> } while (false)</span>
76
- <a name="l00059"></a>00059 <span class="preprocessor"></span><span class="comment"></span>
77
- <a name="l00060"></a>00060 <span class="comment">/**</span>
78
- <a name="l00061"></a>00061 <span class="comment"> * Write the given expression, which represents a warning,</span>
79
- <a name="l00062"></a>00062 <span class="comment"> * to the log stream.</span>
80
- <a name="l00063"></a>00063 <span class="comment"> */</span>
81
- <a name="l00064"></a>00064 <span class="preprocessor">#define P_WARN(expr) P_LOG(expr)</span>
82
- <a name="l00065"></a>00065 <span class="preprocessor"></span><span class="comment"></span>
83
- <a name="l00066"></a>00066 <span class="comment">/**</span>
84
- <a name="l00067"></a>00067 <span class="comment"> * Write the given expression, which represents an error,</span>
85
- <a name="l00068"></a>00068 <span class="comment"> * to the log stream.</span>
86
- <a name="l00069"></a>00069 <span class="comment"> */</span>
87
- <a name="l00070"></a>00070 <span class="preprocessor">#define P_ERROR(expr) P_LOG(expr)</span>
88
- <a name="l00071"></a>00071 <span class="preprocessor"></span><span class="comment"></span>
89
- <a name="l00072"></a>00072 <span class="comment">/**</span>
90
- <a name="l00073"></a>00073 <span class="comment"> * Write the given expression, which represents a debugging message,</span>
91
- <a name="l00074"></a>00074 <span class="comment"> * to the log stream.</span>
92
- <a name="l00075"></a>00075 <span class="comment"> */</span>
93
- <a name="l00076"></a>00076 <span class="preprocessor">#define P_DEBUG(expr) P_TRACE(1, expr)</span>
94
- <a name="l00077"></a>00077 <span class="preprocessor"></span>
95
- <a name="l00078"></a>00078 <span class="preprocessor">#ifdef PASSENGER_DEBUG</span>
96
- <a name="l00079"></a>00079 <span class="preprocessor"></span><span class="preprocessor"> #define P_TRACE(level, expr) \</span>
97
- <a name="l00080"></a>00080 <span class="preprocessor"> do { \</span>
98
- <a name="l00081"></a>00081 <span class="preprocessor"> if (Passenger::_logLevel &gt;= level) { \</span>
99
- <a name="l00082"></a>00082 <span class="preprocessor"> if (Passenger::_debugStream != 0) { \</span>
100
- <a name="l00083"></a>00083 <span class="preprocessor"> time_t the_time = time(NULL); \</span>
101
- <a name="l00084"></a>00084 <span class="preprocessor"> struct tm *the_tm = localtime(&amp;the_time); \</span>
102
- <a name="l00085"></a>00085 <span class="preprocessor"> char datetime_buf[60]; \</span>
103
- <a name="l00086"></a>00086 <span class="preprocessor"> struct timeval tv; \</span>
104
- <a name="l00087"></a>00087 <span class="preprocessor"> strftime(datetime_buf, sizeof(datetime_buf), "%x %H:%M:%S", the_tm); \</span>
105
- <a name="l00088"></a>00088 <span class="preprocessor"> gettimeofday(&amp;tv, NULL); \</span>
106
- <a name="l00089"></a>00089 <span class="preprocessor"> *Passenger::_debugStream &lt;&lt; \</span>
107
- <a name="l00090"></a>00090 <span class="preprocessor"> "[ pid=" &lt;&lt; getpid() &lt;&lt; " file=" &lt;&lt; __FILE__ &lt;&lt; ":" &lt;&lt; __LINE__ &lt;&lt; \</span>
108
- <a name="l00091"></a>00091 <span class="preprocessor"> " time=" &lt;&lt; datetime_buf &lt;&lt; "." &lt;&lt; (tv.tv_usec / 1000) &lt;&lt; " ]:" &lt;&lt; \</span>
109
- <a name="l00092"></a>00092 <span class="preprocessor"> "\n " &lt;&lt; expr &lt;&lt; std::endl; \</span>
110
- <a name="l00093"></a>00093 <span class="preprocessor"> } \</span>
111
- <a name="l00094"></a>00094 <span class="preprocessor"> } \</span>
112
- <a name="l00095"></a>00095 <span class="preprocessor"> } while (false)</span>
113
- <a name="l00096"></a>00096 <span class="preprocessor"></span>
114
- <a name="l00097"></a>00097 <span class="preprocessor"> #define P_ASSERT(expr, result_if_failed, message) \</span>
115
- <a name="l00098"></a>00098 <span class="preprocessor"> do { \</span>
116
- <a name="l00099"></a>00099 <span class="preprocessor"> if (!(expr)) { \</span>
117
- <a name="l00100"></a>00100 <span class="preprocessor"> P_ERROR("Assertion failed: " &lt;&lt; message); \</span>
118
- <a name="l00101"></a>00101 <span class="preprocessor"> return result_if_failed; \</span>
119
- <a name="l00102"></a>00102 <span class="preprocessor"> } \</span>
120
- <a name="l00103"></a>00103 <span class="preprocessor"> } while (false)</span>
121
- <a name="l00104"></a>00104 <span class="preprocessor"></span><span class="preprocessor">#else</span>
122
- <a name="l00105"></a>00105 <span class="preprocessor"></span><span class="preprocessor"> #define P_TRACE(level, expr) do { </span><span class="comment">/* nothing */</span> } while (false)
123
- <a name="l00106"></a>00106
124
- <a name="l00107"></a>00107 <span class="preprocessor"> #define P_ASSERT(expr, result_if_failed, message) do { </span><span class="comment">/* nothing */</span> } while (false)
125
- <a name="l00108"></a>00108 <span class="preprocessor">#endif</span>
126
- <a name="l00109"></a>00109 <span class="preprocessor"></span>
127
- <a name="l00110"></a>00110 } <span class="comment">// namespace Passenger</span>
128
- <a name="l00111"></a>00111
129
- <a name="l00112"></a>00112 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_LOGGING_H_ */</span>
130
- <a name="l00113"></a>00113
43
+ <a name="l00027"></a>00027 <span class="preprocessor">#include &lt;sstream&gt;</span>
44
+ <a name="l00028"></a>00028 <span class="preprocessor">#include &lt;ctime&gt;</span>
45
+ <a name="l00029"></a>00029
46
+ <a name="l00030"></a>00030 <span class="keyword">namespace </span>Passenger {
47
+ <a name="l00031"></a>00031
48
+ <a name="l00032"></a>00032 <span class="keyword">using namespace </span>std;
49
+ <a name="l00033"></a>00033
50
+ <a name="l00034"></a>00034 <span class="keyword">extern</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> _logLevel;
51
+ <a name="l00035"></a>00035 <span class="keyword">extern</span> ostream *_logStream;
52
+ <a name="l00036"></a>00036 <span class="keyword">extern</span> ostream *_debugStream;
53
+ <a name="l00037"></a>00037
54
+ <a name="l00038"></a>00038 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getLogLevel();
55
+ <a name="l00039"></a>00039 <span class="keywordtype">void</span> setLogLevel(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> value);
56
+ <a name="l00040"></a>00040 <span class="keywordtype">void</span> setDebugFile(<span class="keyword">const</span> <span class="keywordtype">char</span> *logFile = NULL);
57
+ <a name="l00041"></a>00041 <span class="comment"></span>
58
+ <a name="l00042"></a>00042 <span class="comment">/**</span>
59
+ <a name="l00043"></a>00043 <span class="comment"> * Write the given expression to the given stream.</span>
60
+ <a name="l00044"></a>00044 <span class="comment"> *</span>
61
+ <a name="l00045"></a>00045 <span class="comment"> * @param expr The expression to write.</span>
62
+ <a name="l00046"></a>00046 <span class="comment"> * @param stream A pointer to an object that accepts the '&lt;&lt;' operator.</span>
63
+ <a name="l00047"></a>00047 <span class="comment"> */</span>
64
+ <a name="l00048"></a>00048 <span class="preprocessor">#define P_LOG_TO(expr, stream) \</span>
65
+ <a name="l00049"></a>00049 <span class="preprocessor"> do { \</span>
66
+ <a name="l00050"></a>00050 <span class="preprocessor"> if (stream != 0) { \</span>
67
+ <a name="l00051"></a>00051 <span class="preprocessor"> time_t the_time; \</span>
68
+ <a name="l00052"></a>00052 <span class="preprocessor"> struct tm *the_tm; \</span>
69
+ <a name="l00053"></a>00053 <span class="preprocessor"> char datetime_buf[60]; \</span>
70
+ <a name="l00054"></a>00054 <span class="preprocessor"> struct timeval tv; \</span>
71
+ <a name="l00055"></a>00055 <span class="preprocessor"> std::stringstream sstream; \</span>
72
+ <a name="l00056"></a>00056 <span class="preprocessor"> \</span>
73
+ <a name="l00057"></a>00057 <span class="preprocessor"> the_time = time(NULL); \</span>
74
+ <a name="l00058"></a>00058 <span class="preprocessor"> the_tm = localtime(&amp;the_time); \</span>
75
+ <a name="l00059"></a>00059 <span class="preprocessor"> strftime(datetime_buf, sizeof(datetime_buf), "%F %H:%M:%S", the_tm); \</span>
76
+ <a name="l00060"></a>00060 <span class="preprocessor"> gettimeofday(&amp;tv, NULL); \</span>
77
+ <a name="l00061"></a>00061 <span class="preprocessor"> sstream &lt;&lt; \</span>
78
+ <a name="l00062"></a>00062 <span class="preprocessor"> "[ pid=" &lt;&lt; getpid() &lt;&lt; " file=" &lt;&lt; __FILE__ &lt;&lt; ":" &lt;&lt; __LINE__ &lt;&lt; \</span>
79
+ <a name="l00063"></a>00063 <span class="preprocessor"> " time=" &lt;&lt; datetime_buf &lt;&lt; "." &lt;&lt; (tv.tv_usec / 1000) &lt;&lt; " ]:" &lt;&lt; \</span>
80
+ <a name="l00064"></a>00064 <span class="preprocessor"> "\n " &lt;&lt; expr &lt;&lt; std::endl; \</span>
81
+ <a name="l00065"></a>00065 <span class="preprocessor"> *stream &lt;&lt; sstream.str(); \</span>
82
+ <a name="l00066"></a>00066 <span class="preprocessor"> stream-&gt;flush(); \</span>
83
+ <a name="l00067"></a>00067 <span class="preprocessor"> } \</span>
84
+ <a name="l00068"></a>00068 <span class="preprocessor"> } while (false)</span>
85
+ <a name="l00069"></a>00069 <span class="preprocessor"></span><span class="comment"></span>
86
+ <a name="l00070"></a>00070 <span class="comment">/**</span>
87
+ <a name="l00071"></a>00071 <span class="comment"> * Write the given expression to the log stream.</span>
88
+ <a name="l00072"></a>00072 <span class="comment"> */</span>
89
+ <a name="l00073"></a>00073 <span class="preprocessor">#define P_LOG(expr) P_LOG_TO(expr, Passenger::_logStream)</span>
90
+ <a name="l00074"></a>00074 <span class="preprocessor"></span><span class="comment"></span>
91
+ <a name="l00075"></a>00075 <span class="comment">/**</span>
92
+ <a name="l00076"></a>00076 <span class="comment"> * Write the given expression, which represents a warning,</span>
93
+ <a name="l00077"></a>00077 <span class="comment"> * to the log stream.</span>
94
+ <a name="l00078"></a>00078 <span class="comment"> */</span>
95
+ <a name="l00079"></a>00079 <span class="preprocessor">#define P_WARN(expr) P_LOG(expr)</span>
96
+ <a name="l00080"></a>00080 <span class="preprocessor"></span><span class="comment"></span>
97
+ <a name="l00081"></a>00081 <span class="comment">/**</span>
98
+ <a name="l00082"></a>00082 <span class="comment"> * Write the given expression, which represents an error,</span>
99
+ <a name="l00083"></a>00083 <span class="comment"> * to the log stream.</span>
100
+ <a name="l00084"></a>00084 <span class="comment"> */</span>
101
+ <a name="l00085"></a>00085 <span class="preprocessor">#define P_ERROR(expr) P_LOG(expr)</span>
102
+ <a name="l00086"></a>00086 <span class="preprocessor"></span><span class="comment"></span>
103
+ <a name="l00087"></a>00087 <span class="comment">/**</span>
104
+ <a name="l00088"></a>00088 <span class="comment"> * Write the given expression, which represents a debugging message,</span>
105
+ <a name="l00089"></a>00089 <span class="comment"> * to the log stream.</span>
106
+ <a name="l00090"></a>00090 <span class="comment"> */</span>
107
+ <a name="l00091"></a>00091 <span class="preprocessor">#define P_DEBUG(expr) P_TRACE(1, expr)</span>
108
+ <a name="l00092"></a>00092 <span class="preprocessor"></span>
109
+ <a name="l00093"></a>00093 <span class="preprocessor">#ifdef PASSENGER_DEBUG</span>
110
+ <a name="l00094"></a>00094 <span class="preprocessor"></span><span class="preprocessor"> #define P_TRACE(level, expr) \</span>
111
+ <a name="l00095"></a>00095 <span class="preprocessor"> do { \</span>
112
+ <a name="l00096"></a>00096 <span class="preprocessor"> if (Passenger::_logLevel &gt;= level) { \</span>
113
+ <a name="l00097"></a>00097 <span class="preprocessor"> P_LOG_TO(expr, Passenger::_debugStream); \</span>
114
+ <a name="l00098"></a>00098 <span class="preprocessor"> } \</span>
115
+ <a name="l00099"></a>00099 <span class="preprocessor"> } while (false)</span>
116
+ <a name="l00100"></a>00100 <span class="preprocessor"></span>
117
+ <a name="l00101"></a>00101 <span class="preprocessor"> #define P_ASSERT(expr, result_if_failed, message) \</span>
118
+ <a name="l00102"></a>00102 <span class="preprocessor"> do { \</span>
119
+ <a name="l00103"></a>00103 <span class="preprocessor"> if (!(expr)) { \</span>
120
+ <a name="l00104"></a>00104 <span class="preprocessor"> P_ERROR("Assertion failed: " &lt;&lt; message); \</span>
121
+ <a name="l00105"></a>00105 <span class="preprocessor"> return result_if_failed; \</span>
122
+ <a name="l00106"></a>00106 <span class="preprocessor"> } \</span>
123
+ <a name="l00107"></a>00107 <span class="preprocessor"> } while (false)</span>
124
+ <a name="l00108"></a>00108 <span class="preprocessor"></span><span class="preprocessor">#else</span>
125
+ <a name="l00109"></a>00109 <span class="preprocessor"></span><span class="preprocessor"> #define P_TRACE(level, expr) do { </span><span class="comment">/* nothing */</span> } while (false)
126
+ <a name="l00110"></a>00110
127
+ <a name="l00111"></a>00111 <span class="preprocessor"> #define P_ASSERT(expr, result_if_failed, message) do { </span><span class="comment">/* nothing */</span> } while (false)
128
+ <a name="l00112"></a>00112 <span class="preprocessor">#endif</span>
129
+ <a name="l00113"></a>00113 <span class="preprocessor"></span>
130
+ <a name="l00114"></a>00114 } <span class="comment">// namespace Passenger</span>
131
+ <a name="l00115"></a>00115
132
+ <a name="l00116"></a>00116 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_LOGGING_H_ */</span>
133
+ <a name="l00117"></a>00117
131
134
  </pre></div></div>
132
- <hr size="1"><address style="text-align: right;"><small>Generated on Mon Dec 15 15:27:24 2008 for Passenger by&nbsp;
135
+ <hr size="1"><address style="text-align: right;"><small>Generated on Fri Mar 13 19:24:32 2009 for Passenger by&nbsp;
133
136
  <a href="http://www.doxygen.org/index.html">
134
137
  <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
135
138
  </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>
@@ -37,487 +36,596 @@
37
36
  <a name="l00020"></a>00020 <span class="preprocessor">#ifndef _PASSENGER_MESSAGE_CHANNEL_H_</span>
38
37
  <a name="l00021"></a>00021 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_MESSAGE_CHANNEL_H_</span>
39
38
  <a name="l00022"></a>00022 <span class="preprocessor"></span>
40
- <a name="l00023"></a>00023 <span class="preprocessor">#include &lt;algorithm&gt;</span>
41
- <a name="l00024"></a>00024 <span class="preprocessor">#include &lt;string&gt;</span>
42
- <a name="l00025"></a>00025 <span class="preprocessor">#include &lt;list&gt;</span>
43
- <a name="l00026"></a>00026 <span class="preprocessor">#include &lt;vector&gt;</span>
44
- <a name="l00027"></a>00027
45
- <a name="l00028"></a>00028 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
46
- <a name="l00029"></a>00029 <span class="preprocessor">#include &lt;sys/socket.h&gt;</span>
47
- <a name="l00030"></a>00030 <span class="preprocessor">#include &lt;arpa/inet.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;unistd.h&gt;</span>
50
- <a name="l00033"></a>00033 <span class="preprocessor">#include &lt;cstdarg&gt;</span>
51
- <a name="l00034"></a>00034
52
- <a name="l00035"></a>00035 <span class="preprocessor">#include "System.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 "Utils.h"</span>
55
- <a name="l00038"></a>00038
56
- <a name="l00039"></a>00039 <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="comment"></span>
60
- <a name="l00043"></a>00043 <span class="comment">/**</span>
61
- <a name="l00044"></a>00044 <span class="comment"> * Convenience class for I/O operations on file descriptors.</span>
62
- <a name="l00045"></a>00045 <span class="comment"> *</span>
63
- <a name="l00046"></a>00046 <span class="comment"> * This class provides convenience methods for:</span>
64
- <a name="l00047"></a>00047 <span class="comment"> * - sending and receiving raw data over a file descriptor.</span>
65
- <a name="l00048"></a>00048 <span class="comment"> * - sending and receiving messages over a file descriptor.</span>
66
- <a name="l00049"></a>00049 <span class="comment"> * - file descriptor passing over a Unix socket.</span>
67
- <a name="l00050"></a>00050 <span class="comment"> * All of these methods use exceptions for error reporting.</span>
68
- <a name="l00051"></a>00051 <span class="comment"> *</span>
69
- <a name="l00052"></a>00052 <span class="comment"> * There are two kinds of messages:</span>
70
- <a name="l00053"></a>00053 <span class="comment"> * - Array messages. These are just a list of strings, and the message</span>
71
- <a name="l00054"></a>00054 <span class="comment"> * itself has a specific length. The contained strings may not</span>
72
- <a name="l00055"></a>00055 <span class="comment"> * contain NUL characters (&lt;tt&gt;'\\0'&lt;/tt&gt;). Note that an array message</span>
73
- <a name="l00056"></a>00056 <span class="comment"> * must have at least one element.</span>
74
- <a name="l00057"></a>00057 <span class="comment"> * - Scalar messages. These are byte strings which may contain arbitrary</span>
75
- <a name="l00058"></a>00058 <span class="comment"> * binary data. Scalar messages also have a specific length.</span>
76
- <a name="l00059"></a>00059 <span class="comment"> * The protocol is designed to be low overhead, easy to implement and</span>
77
- <a name="l00060"></a>00060 <span class="comment"> * easy to parse.</span>
78
- <a name="l00061"></a>00061 <span class="comment"> *</span>
79
- <a name="l00062"></a>00062 <span class="comment"> * MessageChannel is to be wrapped around a file descriptor. For example:</span>
80
- <a name="l00063"></a>00063 <span class="comment"> * @code</span>
81
- <a name="l00064"></a>00064 <span class="comment"> * int p[2];</span>
82
- <a name="l00065"></a>00065 <span class="comment"> * pipe(p);</span>
83
- <a name="l00066"></a>00066 <span class="comment"> * MessageChannel channel1(p[0]);</span>
84
- <a name="l00067"></a>00067 <span class="comment"> * MessageChannel channel2(p[1]);</span>
85
- <a name="l00068"></a>00068 <span class="comment"> * </span>
86
- <a name="l00069"></a>00069 <span class="comment"> * // Send an array message.</span>
87
- <a name="l00070"></a>00070 <span class="comment"> * channel2.write("hello", "world !!", NULL);</span>
88
- <a name="l00071"></a>00071 <span class="comment"> * list&lt;string&gt; args;</span>
89
- <a name="l00072"></a>00072 <span class="comment"> * channel1.read(args); // args now contains { "hello", "world !!" }</span>
90
- <a name="l00073"></a>00073 <span class="comment"> *</span>
91
- <a name="l00074"></a>00074 <span class="comment"> * // Send a scalar message.</span>
92
- <a name="l00075"></a>00075 <span class="comment"> * channel2.writeScalar("some long string which can contain arbitrary binary data");</span>
93
- <a name="l00076"></a>00076 <span class="comment"> * string str;</span>
94
- <a name="l00077"></a>00077 <span class="comment"> * channel1.readScalar(str);</span>
95
- <a name="l00078"></a>00078 <span class="comment"> * @endcode</span>
96
- <a name="l00079"></a>00079 <span class="comment"> *</span>
97
- <a name="l00080"></a>00080 <span class="comment"> * The life time of a MessageChannel is independent from that of the</span>
98
- <a name="l00081"></a>00081 <span class="comment"> * wrapped file descriptor. If a MessageChannel object is destroyed,</span>
99
- <a name="l00082"></a>00082 <span class="comment"> * the file descriptor is not automatically closed. Call close()</span>
100
- <a name="l00083"></a>00083 <span class="comment"> * if you want to close the file descriptor.</span>
101
- <a name="l00084"></a>00084 <span class="comment"> *</span>
102
- <a name="l00085"></a>00085 <span class="comment"> * @note I/O operations are not buffered.</span>
103
- <a name="l00086"></a>00086 <span class="comment"> * @note Be careful with mixing the sending/receiving of array messages,</span>
104
- <a name="l00087"></a>00087 <span class="comment"> * scalar messages and file descriptors. If you send a collection of any</span>
105
- <a name="l00088"></a>00088 <span class="comment"> * of these in a specific order, then the receiving side must receive them</span>
106
- <a name="l00089"></a>00089 <span class="comment"> * in the exact some order. So suppose you first send a message, then a</span>
107
- <a name="l00090"></a>00090 <span class="comment"> * file descriptor, then a scalar, then the receiving side must first</span>
108
- <a name="l00091"></a>00091 <span class="comment"> * receive a message, then a file descriptor, then a scalar. If the</span>
109
- <a name="l00092"></a>00092 <span class="comment"> * receiving side does things in the wrong order then bad things will</span>
110
- <a name="l00093"></a>00093 <span class="comment"> * happen.</span>
111
- <a name="l00094"></a>00094 <span class="comment"> * @note MessageChannel is not thread-safe, but is reentrant.</span>
112
- <a name="l00095"></a>00095 <span class="comment"> *</span>
113
- <a name="l00096"></a>00096 <span class="comment"> * @ingroup Support</span>
114
- <a name="l00097"></a>00097 <span class="comment"> */</span>
115
- <a name="l00098"></a><a class="code" href="classPassenger_1_1MessageChannel.html">00098</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> {
116
- <a name="l00099"></a>00099 <span class="keyword">private</span>:
117
- <a name="l00100"></a>00100 <span class="keyword">const</span> <span class="keyword">static</span> <span class="keywordtype">char</span> DELIMITER = <span class="charliteral">'\0'</span>;
118
- <a name="l00101"></a>00101 <span class="keywordtype">int</span> fd;
119
- <a name="l00102"></a>00102
120
- <a name="l00103"></a>00103 <span class="keyword">public</span>:<span class="comment"></span>
121
- <a name="l00104"></a>00104 <span class="comment"> /**</span>
122
- <a name="l00105"></a>00105 <span class="comment"> * Construct a new MessageChannel with no underlying file descriptor.</span>
123
- <a name="l00106"></a>00106 <span class="comment"> * Thus the resulting MessageChannel object will not be usable.</span>
124
- <a name="l00107"></a>00107 <span class="comment"> * This constructor exists to allow one to declare an "empty"</span>
125
- <a name="l00108"></a>00108 <span class="comment"> * MessageChannel variable which is to be initialized later.</span>
126
- <a name="l00109"></a>00109 <span class="comment"> */</span>
127
- <a name="l00110"></a><a class="code" href="classPassenger_1_1MessageChannel.html#73e7c9a8e421d29558838176aff02ca4">00110</a> <a class="code" href="classPassenger_1_1MessageChannel.html#73e7c9a8e421d29558838176aff02ca4" title="Construct a new MessageChannel with no underlying file descriptor.">MessageChannel</a>() {
128
- <a name="l00111"></a>00111 this-&gt;fd = -1;
129
- <a name="l00112"></a>00112 }
130
- <a name="l00113"></a>00113 <span class="comment"></span>
131
- <a name="l00114"></a>00114 <span class="comment"> /**</span>
132
- <a name="l00115"></a>00115 <span class="comment"> * Construct a new MessageChannel with the given file descriptor.</span>
133
- <a name="l00116"></a>00116 <span class="comment"> */</span>
134
- <a name="l00117"></a><a class="code" href="classPassenger_1_1MessageChannel.html#486b6e74c4d0973eefbcfde65f898ca7">00117</a> <a class="code" href="classPassenger_1_1MessageChannel.html#73e7c9a8e421d29558838176aff02ca4" title="Construct a new MessageChannel with no underlying file descriptor.">MessageChannel</a>(<span class="keywordtype">int</span> fd) {
135
- <a name="l00118"></a>00118 this-&gt;fd = fd;
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"> * Close the underlying file descriptor. If this method is called multiple</span>
140
- <a name="l00123"></a>00123 <span class="comment"> * times, the file descriptor will only be closed the first time.</span>
141
- <a name="l00124"></a>00124 <span class="comment"> *</span>
142
- <a name="l00125"></a>00125 <span class="comment"> * @throw SystemException</span>
143
- <a name="l00126"></a>00126 <span class="comment"> * @throw boost::thread_interrupted</span>
39
+ <a name="l00023"></a>00023 <span class="preprocessor">#include &lt;oxt/system_calls.hpp&gt;</span>
40
+ <a name="l00024"></a>00024
41
+ <a name="l00025"></a>00025 <span class="preprocessor">#include &lt;algorithm&gt;</span>
42
+ <a name="l00026"></a>00026 <span class="preprocessor">#include &lt;string&gt;</span>
43
+ <a name="l00027"></a>00027 <span class="preprocessor">#include &lt;list&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;arpa/inet.h&gt;</span>
49
+ <a name="l00033"></a>00033 <span class="preprocessor">#include &lt;errno.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;cstdarg&gt;</span>
52
+ <a name="l00036"></a>00036 <span class="preprocessor">#ifdef __OpenBSD__</span>
53
+ <a name="l00037"></a>00037 <span class="preprocessor"></span> <span class="comment">// OpenBSD needs this for 'struct iovec'. Apparently it isn't</span>
54
+ <a name="l00038"></a>00038 <span class="comment">// always included by unistd.h and sys/types.h.</span>
55
+ <a name="l00039"></a>00039 <span class="preprocessor"> #include &lt;sys/uio.h&gt;</span>
56
+ <a name="l00040"></a>00040 <span class="preprocessor">#endif</span>
57
+ <a name="l00041"></a>00041 <span class="preprocessor"></span><span class="preprocessor">#if !APR_HAVE_IOVEC</span>
58
+ <a name="l00042"></a>00042 <span class="preprocessor"></span> <span class="comment">// We don't want apr_want.h to redefine 'struct iovec'.</span>
59
+ <a name="l00043"></a>00043 <span class="comment">// http://tinyurl.com/b6aatw</span>
60
+ <a name="l00044"></a>00044 <span class="preprocessor"> #undef APR_HAVE_IOVEC</span>
61
+ <a name="l00045"></a>00045 <span class="preprocessor"></span><span class="preprocessor"> #define APR_HAVE_IOVEC 1</span>
62
+ <a name="l00046"></a>00046 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
63
+ <a name="l00047"></a>00047 <span class="preprocessor"></span>
64
+ <a name="l00048"></a>00048 <span class="preprocessor">#include "Exceptions.h"</span>
65
+ <a name="l00049"></a>00049 <span class="preprocessor">#include "Utils.h"</span>
66
+ <a name="l00050"></a>00050
67
+ <a name="l00051"></a>00051 <span class="keyword">namespace </span>Passenger {
68
+ <a name="l00052"></a>00052
69
+ <a name="l00053"></a>00053 <span class="keyword">using namespace </span>std;
70
+ <a name="l00054"></a>00054 <span class="keyword">using namespace </span>oxt;
71
+ <a name="l00055"></a>00055 <span class="comment"></span>
72
+ <a name="l00056"></a>00056 <span class="comment">/**</span>
73
+ <a name="l00057"></a>00057 <span class="comment"> * Convenience class for I/O operations on file descriptors.</span>
74
+ <a name="l00058"></a>00058 <span class="comment"> *</span>
75
+ <a name="l00059"></a>00059 <span class="comment"> * This class provides convenience methods for:</span>
76
+ <a name="l00060"></a>00060 <span class="comment"> * - sending and receiving raw data over a file descriptor.</span>
77
+ <a name="l00061"></a>00061 <span class="comment"> * - sending and receiving messages over a file descriptor.</span>
78
+ <a name="l00062"></a>00062 <span class="comment"> * - file descriptor passing over a Unix socket.</span>
79
+ <a name="l00063"></a>00063 <span class="comment"> * All of these methods use exceptions for error reporting.</span>
80
+ <a name="l00064"></a>00064 <span class="comment"> *</span>
81
+ <a name="l00065"></a>00065 <span class="comment"> * There are two kinds of messages:</span>
82
+ <a name="l00066"></a>00066 <span class="comment"> * - Array messages. These are just a list of strings, and the message</span>
83
+ <a name="l00067"></a>00067 <span class="comment"> * itself has a specific length. The contained strings may not</span>
84
+ <a name="l00068"></a>00068 <span class="comment"> * contain NUL characters (&lt;tt&gt;'\\0'&lt;/tt&gt;). Note that an array message</span>
85
+ <a name="l00069"></a>00069 <span class="comment"> * must have at least one element.</span>
86
+ <a name="l00070"></a>00070 <span class="comment"> * - Scalar messages. These are byte strings which may contain arbitrary</span>
87
+ <a name="l00071"></a>00071 <span class="comment"> * binary data. Scalar messages also have a specific length.</span>
88
+ <a name="l00072"></a>00072 <span class="comment"> * The protocol is designed to be low overhead, easy to implement and</span>
89
+ <a name="l00073"></a>00073 <span class="comment"> * easy to parse.</span>
90
+ <a name="l00074"></a>00074 <span class="comment"> *</span>
91
+ <a name="l00075"></a>00075 <span class="comment"> * MessageChannel is to be wrapped around a file descriptor. For example:</span>
92
+ <a name="l00076"></a>00076 <span class="comment"> * @code</span>
93
+ <a name="l00077"></a>00077 <span class="comment"> * int p[2];</span>
94
+ <a name="l00078"></a>00078 <span class="comment"> * pipe(p);</span>
95
+ <a name="l00079"></a>00079 <span class="comment"> * MessageChannel channel1(p[0]);</span>
96
+ <a name="l00080"></a>00080 <span class="comment"> * MessageChannel channel2(p[1]);</span>
97
+ <a name="l00081"></a>00081 <span class="comment"> * </span>
98
+ <a name="l00082"></a>00082 <span class="comment"> * // Send an array message.</span>
99
+ <a name="l00083"></a>00083 <span class="comment"> * channel2.write("hello", "world !!", NULL);</span>
100
+ <a name="l00084"></a>00084 <span class="comment"> * list&lt;string&gt; args;</span>
101
+ <a name="l00085"></a>00085 <span class="comment"> * channel1.read(args); // args now contains { "hello", "world !!" }</span>
102
+ <a name="l00086"></a>00086 <span class="comment"> *</span>
103
+ <a name="l00087"></a>00087 <span class="comment"> * // Send a scalar message.</span>
104
+ <a name="l00088"></a>00088 <span class="comment"> * channel2.writeScalar("some long string which can contain arbitrary binary data");</span>
105
+ <a name="l00089"></a>00089 <span class="comment"> * string str;</span>
106
+ <a name="l00090"></a>00090 <span class="comment"> * channel1.readScalar(str);</span>
107
+ <a name="l00091"></a>00091 <span class="comment"> * @endcode</span>
108
+ <a name="l00092"></a>00092 <span class="comment"> *</span>
109
+ <a name="l00093"></a>00093 <span class="comment"> * The life time of a MessageChannel is independent from that of the</span>
110
+ <a name="l00094"></a>00094 <span class="comment"> * wrapped file descriptor. If a MessageChannel object is destroyed,</span>
111
+ <a name="l00095"></a>00095 <span class="comment"> * the file descriptor is not automatically closed. Call close()</span>
112
+ <a name="l00096"></a>00096 <span class="comment"> * if you want to close the file descriptor.</span>
113
+ <a name="l00097"></a>00097 <span class="comment"> *</span>
114
+ <a name="l00098"></a>00098 <span class="comment"> * @note I/O operations are not buffered.</span>
115
+ <a name="l00099"></a>00099 <span class="comment"> * @note Be careful with mixing the sending/receiving of array messages,</span>
116
+ <a name="l00100"></a>00100 <span class="comment"> * scalar messages and file descriptors. If you send a collection of any</span>
117
+ <a name="l00101"></a>00101 <span class="comment"> * of these in a specific order, then the receiving side must receive them</span>
118
+ <a name="l00102"></a>00102 <span class="comment"> * in the exact some order. So suppose you first send a message, then a</span>
119
+ <a name="l00103"></a>00103 <span class="comment"> * file descriptor, then a scalar, then the receiving side must first</span>
120
+ <a name="l00104"></a>00104 <span class="comment"> * receive a message, then a file descriptor, then a scalar. If the</span>
121
+ <a name="l00105"></a>00105 <span class="comment"> * receiving side does things in the wrong order then bad things will</span>
122
+ <a name="l00106"></a>00106 <span class="comment"> * happen.</span>
123
+ <a name="l00107"></a>00107 <span class="comment"> * @note MessageChannel is not thread-safe, but is reentrant.</span>
124
+ <a name="l00108"></a>00108 <span class="comment"> *</span>
125
+ <a name="l00109"></a>00109 <span class="comment"> * @ingroup Support</span>
126
+ <a name="l00110"></a>00110 <span class="comment"> */</span>
127
+ <a name="l00111"></a><a class="code" href="classPassenger_1_1MessageChannel.html">00111</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1MessageChannel.html" title="Convenience class for I/O operations on file descriptors.">MessageChannel</a> {
128
+ <a name="l00112"></a>00112 <span class="keyword">private</span>:
129
+ <a name="l00113"></a>00113 <span class="keyword">const</span> <span class="keyword">static</span> <span class="keywordtype">char</span> DELIMITER = <span class="charliteral">'\0'</span>;
130
+ <a name="l00114"></a>00114 <span class="keywordtype">int</span> fd;
131
+ <a name="l00115"></a>00115
132
+ <a name="l00116"></a>00116 <span class="preprocessor"> #ifdef __OpenBSD__</span>
133
+ <a name="l00117"></a>00117 <span class="preprocessor"></span> <span class="keyword">typedef</span> u_int32_t uint32_t;
134
+ <a name="l00118"></a>00118 <span class="keyword">typedef</span> u_int16_t uint16_t;
135
+ <a name="l00119"></a>00119 <span class="preprocessor"> #endif</span>
136
+ <a name="l00120"></a>00120 <span class="preprocessor"></span>
137
+ <a name="l00121"></a>00121 <span class="keyword">public</span>:<span class="comment"></span>
138
+ <a name="l00122"></a>00122 <span class="comment"> /**</span>
139
+ <a name="l00123"></a>00123 <span class="comment"> * Construct a new MessageChannel with no underlying file descriptor.</span>
140
+ <a name="l00124"></a>00124 <span class="comment"> * Thus the resulting MessageChannel object will not be usable.</span>
141
+ <a name="l00125"></a>00125 <span class="comment"> * This constructor exists to allow one to declare an "empty"</span>
142
+ <a name="l00126"></a>00126 <span class="comment"> * MessageChannel variable which is to be initialized later.</span>
144
143
  <a name="l00127"></a>00127 <span class="comment"> */</span>
145
- <a name="l00128"></a><a class="code" href="classPassenger_1_1MessageChannel.html#06309e208fc5e10642a2e9bbe0f351eb">00128</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#06309e208fc5e10642a2e9bbe0f351eb" title="Close the underlying file descriptor.">close</a>() {
146
- <a name="l00129"></a>00129 <span class="keywordflow">if</span> (fd != -1) {
147
- <a name="l00130"></a>00130 <span class="keywordtype">int</span> ret = InterruptableCalls::close(fd);
148
- <a name="l00131"></a>00131 <span class="keywordflow">if</span> (ret == -1) {
149
- <a name="l00132"></a>00132 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">"Cannot close file descriptor"</span>, errno);
150
- <a name="l00133"></a>00133 }
151
- <a name="l00134"></a>00134 fd = -1;
152
- <a name="l00135"></a>00135 }
153
- <a name="l00136"></a>00136 }
154
- <a name="l00137"></a>00137 <span class="comment"></span>
155
- <a name="l00138"></a>00138 <span class="comment"> /**</span>
156
- <a name="l00139"></a>00139 <span class="comment"> * Send an array message, which consists of the given elements, over the underlying</span>
157
- <a name="l00140"></a>00140 <span class="comment"> * file descriptor.</span>
158
- <a name="l00141"></a>00141 <span class="comment"> *</span>
159
- <a name="l00142"></a>00142 <span class="comment"> * @param args The message elements.</span>
160
- <a name="l00143"></a>00143 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
161
- <a name="l00144"></a>00144 <span class="comment"> * @throws boost::thread_interrupted</span>
162
- <a name="l00145"></a>00145 <span class="comment"> * @pre None of the message elements may contain a NUL character (&lt;tt&gt;'\\0'&lt;/tt&gt;).</span>
163
- <a name="l00146"></a>00146 <span class="comment"> * @see read(), write(const char *, ...)</span>
164
- <a name="l00147"></a>00147 <span class="comment"> */</span>
165
- <a name="l00148"></a><a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a">00148</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="keyword">const</span> list&lt;string&gt; &amp;args) {
166
- <a name="l00149"></a>00149 list&lt;string&gt;::const_iterator it;
167
- <a name="l00150"></a>00150 <span class="keywordtype">string</span> data;
168
- <a name="l00151"></a>00151 uint16_t dataSize = 0;
169
- <a name="l00152"></a>00152
170
- <a name="l00153"></a>00153 <span class="keywordflow">for</span> (it = args.begin(); it != args.end(); it++) {
171
- <a name="l00154"></a>00154 dataSize += it-&gt;size() + 1;
172
- <a name="l00155"></a>00155 }
173
- <a name="l00156"></a>00156 data.reserve(dataSize + <span class="keyword">sizeof</span>(dataSize));
174
- <a name="l00157"></a>00157 dataSize = htons(dataSize);
175
- <a name="l00158"></a>00158 data.append((<span class="keyword">const</span> <span class="keywordtype">char</span> *) &amp;dataSize, <span class="keyword">sizeof</span>(dataSize));
176
- <a name="l00159"></a>00159 <span class="keywordflow">for</span> (it = args.begin(); it != args.end(); it++) {
177
- <a name="l00160"></a>00160 data.append(*it);
178
- <a name="l00161"></a>00161 data.append(1, DELIMITER);
179
- <a name="l00162"></a>00162 }
180
- <a name="l00163"></a>00163
181
- <a name="l00164"></a>00164 <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(data);
182
- <a name="l00165"></a>00165 }
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"> * Send an array message, which consists of the given strings, over the underlying</span>
186
- <a name="l00169"></a>00169 <span class="comment"> * file descriptor.</span>
187
- <a name="l00170"></a>00170 <span class="comment"> *</span>
188
- <a name="l00171"></a>00171 <span class="comment"> * @param name The first element of the message to send.</span>
189
- <a name="l00172"></a>00172 <span class="comment"> * @param ... Other elements of the message. These *must* be strings, i.e. of type char*.</span>
190
- <a name="l00173"></a>00173 <span class="comment"> * It is also required to terminate this list with a NULL.</span>
191
- <a name="l00174"></a>00174 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
192
- <a name="l00175"></a>00175 <span class="comment"> * @throws boost::thread_interrupted</span>
193
- <a name="l00176"></a>00176 <span class="comment"> * @pre None of the message elements may contain a NUL character (&lt;tt&gt;'\\0'&lt;/tt&gt;).</span>
194
- <a name="l00177"></a>00177 <span class="comment"> * @see read(), write(const list&lt;string&gt; &amp;)</span>
195
- <a name="l00178"></a>00178 <span class="comment"> */</span>
196
- <a name="l00179"></a><a class="code" href="classPassenger_1_1MessageChannel.html#12cce3364023eacbe4fe09006cf3d38d">00179</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, ...) {
197
- <a name="l00180"></a>00180 list&lt;string&gt; args;
198
- <a name="l00181"></a>00181 args.push_back(name);
199
- <a name="l00182"></a>00182
200
- <a name="l00183"></a>00183 va_list ap;
201
- <a name="l00184"></a>00184 va_start(ap, name);
202
- <a name="l00185"></a>00185 <span class="keywordflow">while</span> (<span class="keyword">true</span>) {
203
- <a name="l00186"></a>00186 <span class="keyword">const</span> <span class="keywordtype">char</span> *arg = va_arg(ap, <span class="keyword">const</span> <span class="keywordtype">char</span> *);
204
- <a name="l00187"></a>00187 <span class="keywordflow">if</span> (arg == NULL) {
205
- <a name="l00188"></a>00188 <span class="keywordflow">break</span>;
206
- <a name="l00189"></a>00189 } <span class="keywordflow">else</span> {
207
- <a name="l00190"></a>00190 args.push_back(arg);
208
- <a name="l00191"></a>00191 }
209
- <a name="l00192"></a>00192 }
210
- <a name="l00193"></a>00193 va_end(ap);
211
- <a name="l00194"></a>00194 <a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(args);
212
- <a name="l00195"></a>00195 }
213
- <a name="l00196"></a>00196 <span class="comment"></span>
214
- <a name="l00197"></a>00197 <span class="comment"> /**</span>
215
- <a name="l00198"></a>00198 <span class="comment"> * Send a scalar message over the underlying file descriptor.</span>
216
- <a name="l00199"></a>00199 <span class="comment"> *</span>
217
- <a name="l00200"></a>00200 <span class="comment"> * @param str The scalar message's content.</span>
218
- <a name="l00201"></a>00201 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
219
- <a name="l00202"></a>00202 <span class="comment"> * @throws boost::thread_interrupted</span>
220
- <a name="l00203"></a>00203 <span class="comment"> * @see readScalar(), writeScalar(const char *, unsigned int)</span>
221
- <a name="l00204"></a>00204 <span class="comment"> */</span>
222
- <a name="l00205"></a><a class="code" href="classPassenger_1_1MessageChannel.html#44e01a783c48abadeea0d915b9893bfb">00205</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#44e01a783c48abadeea0d915b9893bfb" title="Send a scalar message over the underlying file descriptor.">writeScalar</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;str) {
223
- <a name="l00206"></a>00206 <a class="code" href="classPassenger_1_1MessageChannel.html#44e01a783c48abadeea0d915b9893bfb" title="Send a scalar message over the underlying file descriptor.">writeScalar</a>(str.c_str(), str.size());
224
- <a name="l00207"></a>00207 }
225
- <a name="l00208"></a>00208 <span class="comment"></span>
226
- <a name="l00209"></a>00209 <span class="comment"> /**</span>
227
- <a name="l00210"></a>00210 <span class="comment"> * Send a scalar message over the underlying file descriptor.</span>
228
- <a name="l00211"></a>00211 <span class="comment"> *</span>
229
- <a name="l00212"></a>00212 <span class="comment"> * @param data The scalar message's content.</span>
230
- <a name="l00213"></a>00213 <span class="comment"> * @param size The number of bytes in &lt;tt&gt;data&lt;/tt&gt;.</span>
231
- <a name="l00214"></a>00214 <span class="comment"> * @pre &lt;tt&gt;data != NULL&lt;/tt&gt;</span>
232
- <a name="l00215"></a>00215 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
233
- <a name="l00216"></a>00216 <span class="comment"> * @throws boost::thread_interrupted</span>
234
- <a name="l00217"></a>00217 <span class="comment"> * @see readScalar(), writeScalar(const string &amp;)</span>
235
- <a name="l00218"></a>00218 <span class="comment"> */</span>
236
- <a name="l00219"></a><a class="code" href="classPassenger_1_1MessageChannel.html#80977020ef895f3ea790c5d28a333dda">00219</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#44e01a783c48abadeea0d915b9893bfb" title="Send a scalar message over the underlying file descriptor.">writeScalar</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *data, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
237
- <a name="l00220"></a>00220 uint32_t l = htonl(size);
238
- <a name="l00221"></a>00221 <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>((<span class="keyword">const</span> <span class="keywordtype">char</span> *) &amp;l, <span class="keyword">sizeof</span>(uint32_t));
239
- <a name="l00222"></a>00222 <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(data, size);
240
- <a name="l00223"></a>00223 }
241
- <a name="l00224"></a>00224 <span class="comment"></span>
242
- <a name="l00225"></a>00225 <span class="comment"> /**</span>
243
- <a name="l00226"></a>00226 <span class="comment"> * Send a block of data over the underlying file descriptor.</span>
244
- <a name="l00227"></a>00227 <span class="comment"> * This method blocks until everything is sent.</span>
245
- <a name="l00228"></a>00228 <span class="comment"> *</span>
246
- <a name="l00229"></a>00229 <span class="comment"> * @param data The data to send.</span>
247
- <a name="l00230"></a>00230 <span class="comment"> * @param size The number of bytes in &lt;tt&gt;data&lt;/tt&gt;.</span>
248
- <a name="l00231"></a>00231 <span class="comment"> * @pre &lt;tt&gt;data != NULL&lt;/tt&gt;</span>
249
- <a name="l00232"></a>00232 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
250
- <a name="l00233"></a>00233 <span class="comment"> * @throws boost::thread_interrupted</span>
251
- <a name="l00234"></a>00234 <span class="comment"> * @see readRaw()</span>
252
- <a name="l00235"></a>00235 <span class="comment"> */</span>
253
- <a name="l00236"></a><a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef">00236</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *data, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
254
- <a name="l00237"></a>00237 ssize_t ret;
255
- <a name="l00238"></a>00238 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> written = 0;
256
- <a name="l00239"></a>00239 <span class="keywordflow">do</span> {
257
- <a name="l00240"></a>00240 ret = InterruptableCalls::write(fd, data + written, size - written);
258
- <a name="l00241"></a>00241 <span class="keywordflow">if</span> (ret == -1) {
259
- <a name="l00242"></a>00242 <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">"write() failed"</span>, errno);
260
- <a name="l00243"></a>00243 } <span class="keywordflow">else</span> {
261
- <a name="l00244"></a>00244 written += ret;
262
- <a name="l00245"></a>00245 }
263
- <a name="l00246"></a>00246 } <span class="keywordflow">while</span> (written &lt; size);
264
- <a name="l00247"></a>00247 }
265
- <a name="l00248"></a>00248 <span class="comment"></span>
266
- <a name="l00249"></a>00249 <span class="comment"> /**</span>
267
- <a name="l00250"></a>00250 <span class="comment"> * Send a block of data over the underlying file descriptor.</span>
268
- <a name="l00251"></a>00251 <span class="comment"> * This method blocks until everything is sent.</span>
269
- <a name="l00252"></a>00252 <span class="comment"> *</span>
270
- <a name="l00253"></a>00253 <span class="comment"> * @param data The data to send.</span>
271
- <a name="l00254"></a>00254 <span class="comment"> * @pre &lt;tt&gt;data != NULL&lt;/tt&gt;</span>
272
- <a name="l00255"></a>00255 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
273
- <a name="l00256"></a>00256 <span class="comment"> * @throws boost::thread_interrupted</span>
274
- <a name="l00257"></a>00257 <span class="comment"> */</span>
275
- <a name="l00258"></a><a class="code" href="classPassenger_1_1MessageChannel.html#cfa38f4f0e22ec16350b8cc159e8e364">00258</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;data) {
276
- <a name="l00259"></a>00259 <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(data.c_str(), data.size());
277
- <a name="l00260"></a>00260 }
278
- <a name="l00261"></a>00261 <span class="comment"></span>
279
- <a name="l00262"></a>00262 <span class="comment"> /**</span>
280
- <a name="l00263"></a>00263 <span class="comment"> * Pass a file descriptor. This only works if the underlying file</span>
281
- <a name="l00264"></a>00264 <span class="comment"> * descriptor is a Unix socket.</span>
282
- <a name="l00265"></a>00265 <span class="comment"> *</span>
283
- <a name="l00266"></a>00266 <span class="comment"> * @param fileDescriptor The file descriptor to pass.</span>
284
- <a name="l00267"></a>00267 <span class="comment"> * @throws SystemException Something went wrong during file descriptor passing.</span>
285
- <a name="l00268"></a>00268 <span class="comment"> * @throws boost::thread_interrupted</span>
286
- <a name="l00269"></a>00269 <span class="comment"> * @pre &lt;tt&gt;fileDescriptor &gt;= 0&lt;/tt&gt;</span>
287
- <a name="l00270"></a>00270 <span class="comment"> * @see readFileDescriptor()</span>
288
- <a name="l00271"></a>00271 <span class="comment"> */</span>
289
- <a name="l00272"></a><a class="code" href="classPassenger_1_1MessageChannel.html#73e3f3cda384c085a2af0e820ccd3e98">00272</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#73e3f3cda384c085a2af0e820ccd3e98" title="Pass a file descriptor.">writeFileDescriptor</a>(<span class="keywordtype">int</span> fileDescriptor) {
290
- <a name="l00273"></a>00273 <span class="keyword">struct </span>msghdr msg;
291
- <a name="l00274"></a>00274 <span class="keyword">struct </span>iovec vec;
292
- <a name="l00275"></a>00275 <span class="keywordtype">char</span> dummy[1];
293
- <a name="l00276"></a>00276 <span class="preprocessor"> #ifdef __APPLE__</span>
294
- <a name="l00277"></a>00277 <span class="preprocessor"></span> <span class="keyword">struct </span>{
295
- <a name="l00278"></a>00278 <span class="keyword">struct </span>cmsghdr header;
296
- <a name="l00279"></a>00279 <span class="keywordtype">int</span> fd;
297
- <a name="l00280"></a>00280 } control_data;
298
- <a name="l00281"></a>00281 <span class="preprocessor"> #else</span>
299
- <a name="l00282"></a>00282 <span class="preprocessor"></span> <span class="keywordtype">char</span> control_data[CMSG_SPACE(<span class="keyword">sizeof</span>(<span class="keywordtype">int</span>))];
300
- <a name="l00283"></a>00283 <span class="preprocessor"> #endif</span>
301
- <a name="l00284"></a>00284 <span class="preprocessor"></span> <span class="keyword">struct </span>cmsghdr *control_header;
302
- <a name="l00285"></a>00285 <span class="keywordtype">int</span> ret;
303
- <a name="l00286"></a>00286
304
- <a name="l00287"></a>00287 msg.msg_name = NULL;
305
- <a name="l00288"></a>00288 msg.msg_namelen = 0;
306
- <a name="l00289"></a>00289
307
- <a name="l00290"></a>00290 <span class="comment">/* Linux and Solaris require msg_iov to be non-NULL. */</span>
308
- <a name="l00291"></a>00291 dummy[0] = <span class="charliteral">'\0'</span>;
309
- <a name="l00292"></a>00292 vec.iov_base = dummy;
310
- <a name="l00293"></a>00293 vec.iov_len = <span class="keyword">sizeof</span>(dummy);
311
- <a name="l00294"></a>00294 msg.msg_iov = &amp;vec;
312
- <a name="l00295"></a>00295 msg.msg_iovlen = 1;
313
- <a name="l00296"></a>00296
314
- <a name="l00297"></a>00297 msg.msg_control = (caddr_t) &amp;control_data;
315
- <a name="l00298"></a>00298 msg.msg_controllen = <span class="keyword">sizeof</span>(control_data);
316
- <a name="l00299"></a>00299 msg.msg_flags = 0;
317
- <a name="l00300"></a>00300
318
- <a name="l00301"></a>00301 control_header = CMSG_FIRSTHDR(&amp;msg);
319
- <a name="l00302"></a>00302 control_header-&gt;cmsg_level = SOL_SOCKET;
320
- <a name="l00303"></a>00303 control_header-&gt;cmsg_type = SCM_RIGHTS;
321
- <a name="l00304"></a>00304 <span class="preprocessor"> #ifdef __APPLE__</span>
322
- <a name="l00305"></a>00305 <span class="preprocessor"></span> control_header-&gt;cmsg_len = <span class="keyword">sizeof</span>(control_data);
323
- <a name="l00306"></a>00306 control_data.fd = fileDescriptor;
324
- <a name="l00307"></a>00307 <span class="preprocessor"> #else</span>
325
- <a name="l00308"></a>00308 <span class="preprocessor"></span> control_header-&gt;cmsg_len = CMSG_LEN(<span class="keyword">sizeof</span>(<span class="keywordtype">int</span>));
326
- <a name="l00309"></a>00309 memcpy(CMSG_DATA(control_header), &amp;fileDescriptor, <span class="keyword">sizeof</span>(<span class="keywordtype">int</span>));
327
- <a name="l00310"></a>00310 <span class="preprocessor"> #endif</span>
328
- <a name="l00311"></a>00311 <span class="preprocessor"></span>
329
- <a name="l00312"></a>00312 ret = InterruptableCalls::sendmsg(fd, &amp;msg, 0);
330
- <a name="l00313"></a>00313 <span class="keywordflow">if</span> (ret == -1) {
331
- <a name="l00314"></a>00314 <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 send file descriptor with sendmsg()"</span>, errno);
332
- <a name="l00315"></a>00315 }
333
- <a name="l00316"></a>00316 }
334
- <a name="l00317"></a>00317 <span class="comment"></span>
335
- <a name="l00318"></a>00318 <span class="comment"> /**</span>
336
- <a name="l00319"></a>00319 <span class="comment"> * Read an array message from the underlying file descriptor.</span>
337
- <a name="l00320"></a>00320 <span class="comment"> *</span>
338
- <a name="l00321"></a>00321 <span class="comment"> * @param args The message will be put in this variable.</span>
339
- <a name="l00322"></a>00322 <span class="comment"> * @return Whether end-of-file has been reached. If so, then the contents</span>
340
- <a name="l00323"></a>00323 <span class="comment"> * of &lt;tt&gt;args&lt;/tt&gt; will be undefined.</span>
341
- <a name="l00324"></a>00324 <span class="comment"> * @throws SystemException If an error occured while receiving the message.</span>
342
- <a name="l00325"></a>00325 <span class="comment"> * @throws boost::thread_interrupted</span>
343
- <a name="l00326"></a>00326 <span class="comment"> * @see write()</span>
344
- <a name="l00327"></a>00327 <span class="comment"> */</span>
345
- <a name="l00328"></a><a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e">00328</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(vector&lt;string&gt; &amp;args) {
346
- <a name="l00329"></a>00329 uint16_t size;
347
- <a name="l00330"></a>00330 <span class="keywordtype">int</span> ret;
348
- <a name="l00331"></a>00331 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> alreadyRead = 0;
349
- <a name="l00332"></a>00332
350
- <a name="l00333"></a>00333 <span class="keywordflow">do</span> {
351
- <a name="l00334"></a>00334 ret = InterruptableCalls::read(fd, (<span class="keywordtype">char</span> *) &amp;size + alreadyRead, <span class="keyword">sizeof</span>(size) - alreadyRead);
352
- <a name="l00335"></a>00335 <span class="keywordflow">if</span> (ret == -1) {
353
- <a name="l00336"></a>00336 <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">"read() failed"</span>, errno);
354
- <a name="l00337"></a>00337 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ret == 0) {
355
- <a name="l00338"></a>00338 <span class="keywordflow">return</span> <span class="keyword">false</span>;
356
- <a name="l00339"></a>00339 }
357
- <a name="l00340"></a>00340 alreadyRead += ret;
358
- <a name="l00341"></a>00341 } <span class="keywordflow">while</span> (alreadyRead &lt; <span class="keyword">sizeof</span>(size));
359
- <a name="l00342"></a>00342 size = ntohs(size);
360
- <a name="l00343"></a>00343
361
- <a name="l00344"></a>00344 <span class="keywordtype">string</span> buffer;
362
- <a name="l00345"></a>00345 args.clear();
363
- <a name="l00346"></a>00346 buffer.reserve(size);
364
- <a name="l00347"></a>00347 <span class="keywordflow">while</span> (buffer.size() &lt; size) {
365
- <a name="l00348"></a>00348 <span class="keywordtype">char</span> tmp[1024 * 8];
366
- <a name="l00349"></a>00349 ret = InterruptableCalls::read(fd, tmp, min(size - buffer.size(), <span class="keyword">sizeof</span>(tmp)));
367
- <a name="l00350"></a>00350 <span class="keywordflow">if</span> (ret == -1) {
368
- <a name="l00351"></a>00351 <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">"read() failed"</span>, errno);
369
- <a name="l00352"></a>00352 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ret == 0) {
370
- <a name="l00353"></a>00353 <span class="keywordflow">return</span> <span class="keyword">false</span>;
371
- <a name="l00354"></a>00354 }
372
- <a name="l00355"></a>00355 buffer.append(tmp, ret);
373
- <a name="l00356"></a>00356 }
374
- <a name="l00357"></a>00357
375
- <a name="l00358"></a>00358 <span class="keywordflow">if</span> (!buffer.empty()) {
376
- <a name="l00359"></a>00359 string::size_type start = 0, pos;
377
- <a name="l00360"></a>00360 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;const_buffer(buffer);
378
- <a name="l00361"></a>00361 <span class="keywordflow">while</span> ((pos = const_buffer.find(<span class="charliteral">'\0'</span>, start)) != string::npos) {
379
- <a name="l00362"></a>00362 args.push_back(const_buffer.substr(start, pos - start));
380
- <a name="l00363"></a>00363 start = pos + 1;
381
- <a name="l00364"></a>00364 }
144
+ <a name="l00128"></a><a class="code" href="classPassenger_1_1MessageChannel.html#73e7c9a8e421d29558838176aff02ca4">00128</a> <a class="code" href="classPassenger_1_1MessageChannel.html#73e7c9a8e421d29558838176aff02ca4" title="Construct a new MessageChannel with no underlying file descriptor.">MessageChannel</a>() {
145
+ <a name="l00129"></a>00129 this-&gt;fd = -1;
146
+ <a name="l00130"></a>00130 }
147
+ <a name="l00131"></a>00131 <span class="comment"></span>
148
+ <a name="l00132"></a>00132 <span class="comment"> /**</span>
149
+ <a name="l00133"></a>00133 <span class="comment"> * Construct a new MessageChannel with the given file descriptor.</span>
150
+ <a name="l00134"></a>00134 <span class="comment"> */</span>
151
+ <a name="l00135"></a><a class="code" href="classPassenger_1_1MessageChannel.html#486b6e74c4d0973eefbcfde65f898ca7">00135</a> <a class="code" href="classPassenger_1_1MessageChannel.html#73e7c9a8e421d29558838176aff02ca4" title="Construct a new MessageChannel with no underlying file descriptor.">MessageChannel</a>(<span class="keywordtype">int</span> fd) {
152
+ <a name="l00136"></a>00136 this-&gt;fd = fd;
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"> * Close the underlying file descriptor. If this method is called multiple</span>
157
+ <a name="l00141"></a>00141 <span class="comment"> * times, the file descriptor will only be closed the first time.</span>
158
+ <a name="l00142"></a>00142 <span class="comment"> *</span>
159
+ <a name="l00143"></a>00143 <span class="comment"> * @throw SystemException</span>
160
+ <a name="l00144"></a>00144 <span class="comment"> * @throw boost::thread_interrupted</span>
161
+ <a name="l00145"></a>00145 <span class="comment"> */</span>
162
+ <a name="l00146"></a><a class="code" href="classPassenger_1_1MessageChannel.html#06309e208fc5e10642a2e9bbe0f351eb">00146</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#06309e208fc5e10642a2e9bbe0f351eb" title="Close the underlying file descriptor.">close</a>() {
163
+ <a name="l00147"></a>00147 <span class="keywordflow">if</span> (fd != -1) {
164
+ <a name="l00148"></a>00148 <span class="keywordtype">int</span> ret = syscalls::close(fd);
165
+ <a name="l00149"></a>00149 <span class="keywordflow">if</span> (ret == -1) {
166
+ <a name="l00150"></a>00150 <span class="keywordflow">throw</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a>(<span class="stringliteral">"Cannot close file descriptor"</span>, errno);
167
+ <a name="l00151"></a>00151 }
168
+ <a name="l00152"></a>00152 fd = -1;
169
+ <a name="l00153"></a>00153 }
170
+ <a name="l00154"></a>00154 }
171
+ <a name="l00155"></a>00155 <span class="comment"></span>
172
+ <a name="l00156"></a>00156 <span class="comment"> /**</span>
173
+ <a name="l00157"></a>00157 <span class="comment"> * Send an array message, which consists of the given elements, over the underlying</span>
174
+ <a name="l00158"></a>00158 <span class="comment"> * file descriptor.</span>
175
+ <a name="l00159"></a>00159 <span class="comment"> *</span>
176
+ <a name="l00160"></a>00160 <span class="comment"> * @param args An object which contains the message elements. This object must</span>
177
+ <a name="l00161"></a>00161 <span class="comment"> * support STL-style iteration, and each iterator must have an</span>
178
+ <a name="l00162"></a>00162 <span class="comment"> * std::string as value. Use the StringArrayType and</span>
179
+ <a name="l00163"></a>00163 <span class="comment"> * StringArrayConstIteratorType template parameters to specify the exact type names.</span>
180
+ <a name="l00164"></a>00164 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
181
+ <a name="l00165"></a>00165 <span class="comment"> * @throws boost::thread_interrupted</span>
182
+ <a name="l00166"></a>00166 <span class="comment"> * @pre None of the message elements may contain a NUL character (&lt;tt&gt;'\\0'&lt;/tt&gt;).</span>
183
+ <a name="l00167"></a>00167 <span class="comment"> * @see read(), write(const char *, ...)</span>
184
+ <a name="l00168"></a>00168 <span class="comment"> */</span>
185
+ <a name="l00169"></a>00169 <span class="keyword">template</span>&lt;<span class="keyword">typename</span> StringArrayType, <span class="keyword">typename</span> StringArrayConstIteratorType&gt;
186
+ <a name="l00170"></a><a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d">00170</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="keyword">const</span> StringArrayType &amp;args) {
187
+ <a name="l00171"></a>00171 StringArrayConstIteratorType it;
188
+ <a name="l00172"></a>00172 <span class="keywordtype">string</span> data;
189
+ <a name="l00173"></a>00173 uint16_t dataSize = 0;
190
+ <a name="l00174"></a>00174
191
+ <a name="l00175"></a>00175 <span class="keywordflow">for</span> (it = args.begin(); it != args.end(); it++) {
192
+ <a name="l00176"></a>00176 dataSize += it-&gt;size() + 1;
193
+ <a name="l00177"></a>00177 }
194
+ <a name="l00178"></a>00178 data.reserve(dataSize + <span class="keyword">sizeof</span>(dataSize));
195
+ <a name="l00179"></a>00179 dataSize = htons(dataSize);
196
+ <a name="l00180"></a>00180 data.append((<span class="keyword">const</span> <span class="keywordtype">char</span> *) &amp;dataSize, <span class="keyword">sizeof</span>(dataSize));
197
+ <a name="l00181"></a>00181 <span class="keywordflow">for</span> (it = args.begin(); it != args.end(); it++) {
198
+ <a name="l00182"></a>00182 data.append(*it);
199
+ <a name="l00183"></a>00183 data.append(1, DELIMITER);
200
+ <a name="l00184"></a>00184 }
201
+ <a name="l00185"></a>00185
202
+ <a name="l00186"></a>00186 <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(data);
203
+ <a name="l00187"></a>00187 }
204
+ <a name="l00188"></a>00188 <span class="comment"></span>
205
+ <a name="l00189"></a>00189 <span class="comment"> /**</span>
206
+ <a name="l00190"></a>00190 <span class="comment"> * Send an array message, which consists of the given elements, over the underlying</span>
207
+ <a name="l00191"></a>00191 <span class="comment"> * file descriptor.</span>
208
+ <a name="l00192"></a>00192 <span class="comment"> *</span>
209
+ <a name="l00193"></a>00193 <span class="comment"> * @param args The message elements.</span>
210
+ <a name="l00194"></a>00194 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
211
+ <a name="l00195"></a>00195 <span class="comment"> * @throws boost::thread_interrupted</span>
212
+ <a name="l00196"></a>00196 <span class="comment"> * @pre None of the message elements may contain a NUL character (&lt;tt&gt;'\\0'&lt;/tt&gt;).</span>
213
+ <a name="l00197"></a>00197 <span class="comment"> * @see read(), write(const char *, ...)</span>
214
+ <a name="l00198"></a>00198 <span class="comment"> */</span>
215
+ <a name="l00199"></a><a class="code" href="classPassenger_1_1MessageChannel.html#9ad7a978cf8409e01ab2f0a2b6be5a0a">00199</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="keyword">const</span> list&lt;string&gt; &amp;args) {
216
+ <a name="l00200"></a>00200 write&lt;list&lt;string&gt;, list&lt;string&gt;::const_iterator&gt;(args);
217
+ <a name="l00201"></a>00201 }
218
+ <a name="l00202"></a>00202 <span class="comment"></span>
219
+ <a name="l00203"></a>00203 <span class="comment"> /**</span>
220
+ <a name="l00204"></a>00204 <span class="comment"> * Send an array message, which consists of the given elements, over the underlying</span>
221
+ <a name="l00205"></a>00205 <span class="comment"> * file descriptor.</span>
222
+ <a name="l00206"></a>00206 <span class="comment"> *</span>
223
+ <a name="l00207"></a>00207 <span class="comment"> * @param args The message elements.</span>
224
+ <a name="l00208"></a>00208 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
225
+ <a name="l00209"></a>00209 <span class="comment"> * @throws boost::thread_interrupted</span>
226
+ <a name="l00210"></a>00210 <span class="comment"> * @pre None of the message elements may contain a NUL character (&lt;tt&gt;'\\0'&lt;/tt&gt;).</span>
227
+ <a name="l00211"></a>00211 <span class="comment"> * @see read(), write(const char *, ...)</span>
228
+ <a name="l00212"></a>00212 <span class="comment"> */</span>
229
+ <a name="l00213"></a><a class="code" href="classPassenger_1_1MessageChannel.html#6a9bc5d72715cb7ba0e437c8851ef487">00213</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="keyword">const</span> vector&lt;string&gt; &amp;args) {
230
+ <a name="l00214"></a>00214 write&lt;vector&lt;string&gt;, vector&lt;string&gt;::const_iterator&gt;(args);
231
+ <a name="l00215"></a>00215 }
232
+ <a name="l00216"></a>00216 <span class="comment"></span>
233
+ <a name="l00217"></a>00217 <span class="comment"> /**</span>
234
+ <a name="l00218"></a>00218 <span class="comment"> * Send an array message, which consists of the given strings, over the underlying</span>
235
+ <a name="l00219"></a>00219 <span class="comment"> * file descriptor.</span>
236
+ <a name="l00220"></a>00220 <span class="comment"> *</span>
237
+ <a name="l00221"></a>00221 <span class="comment"> * @param name The first element of the message to send.</span>
238
+ <a name="l00222"></a>00222 <span class="comment"> * @param ... Other elements of the message. These *must* be strings, i.e. of type char*.</span>
239
+ <a name="l00223"></a>00223 <span class="comment"> * It is also required to terminate this list with a NULL.</span>
240
+ <a name="l00224"></a>00224 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
241
+ <a name="l00225"></a>00225 <span class="comment"> * @throws boost::thread_interrupted</span>
242
+ <a name="l00226"></a>00226 <span class="comment"> * @pre None of the message elements may contain a NUL character (&lt;tt&gt;'\\0'&lt;/tt&gt;).</span>
243
+ <a name="l00227"></a>00227 <span class="comment"> * @see read(), write(const list&lt;string&gt; &amp;)</span>
244
+ <a name="l00228"></a>00228 <span class="comment"> */</span>
245
+ <a name="l00229"></a><a class="code" href="classPassenger_1_1MessageChannel.html#12cce3364023eacbe4fe09006cf3d38d">00229</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, ...) {
246
+ <a name="l00230"></a>00230 list&lt;string&gt; args;
247
+ <a name="l00231"></a>00231 args.push_back(name);
248
+ <a name="l00232"></a>00232
249
+ <a name="l00233"></a>00233 va_list ap;
250
+ <a name="l00234"></a>00234 va_start(ap, name);
251
+ <a name="l00235"></a>00235 <span class="keywordflow">while</span> (<span class="keyword">true</span>) {
252
+ <a name="l00236"></a>00236 <span class="keyword">const</span> <span class="keywordtype">char</span> *arg = va_arg(ap, <span class="keyword">const</span> <span class="keywordtype">char</span> *);
253
+ <a name="l00237"></a>00237 <span class="keywordflow">if</span> (arg == NULL) {
254
+ <a name="l00238"></a>00238 <span class="keywordflow">break</span>;
255
+ <a name="l00239"></a>00239 } <span class="keywordflow">else</span> {
256
+ <a name="l00240"></a>00240 args.push_back(arg);
257
+ <a name="l00241"></a>00241 }
258
+ <a name="l00242"></a>00242 }
259
+ <a name="l00243"></a>00243 va_end(ap);
260
+ <a name="l00244"></a>00244 <a class="code" href="classPassenger_1_1MessageChannel.html#150f68bc47e060dcc6ca35bee047914d" title="Send an array message, which consists of the given elements, over the underlying...">write</a>(args);
261
+ <a name="l00245"></a>00245 }
262
+ <a name="l00246"></a>00246 <span class="comment"></span>
263
+ <a name="l00247"></a>00247 <span class="comment"> /**</span>
264
+ <a name="l00248"></a>00248 <span class="comment"> * Send a scalar message over the underlying file descriptor.</span>
265
+ <a name="l00249"></a>00249 <span class="comment"> *</span>
266
+ <a name="l00250"></a>00250 <span class="comment"> * @param str The scalar message's content.</span>
267
+ <a name="l00251"></a>00251 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
268
+ <a name="l00252"></a>00252 <span class="comment"> * @throws boost::thread_interrupted</span>
269
+ <a name="l00253"></a>00253 <span class="comment"> * @see readScalar(), writeScalar(const char *, unsigned int)</span>
270
+ <a name="l00254"></a>00254 <span class="comment"> */</span>
271
+ <a name="l00255"></a><a class="code" href="classPassenger_1_1MessageChannel.html#44e01a783c48abadeea0d915b9893bfb">00255</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#44e01a783c48abadeea0d915b9893bfb" title="Send a scalar message over the underlying file descriptor.">writeScalar</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;str) {
272
+ <a name="l00256"></a>00256 <a class="code" href="classPassenger_1_1MessageChannel.html#44e01a783c48abadeea0d915b9893bfb" title="Send a scalar message over the underlying file descriptor.">writeScalar</a>(str.c_str(), str.size());
273
+ <a name="l00257"></a>00257 }
274
+ <a name="l00258"></a>00258 <span class="comment"></span>
275
+ <a name="l00259"></a>00259 <span class="comment"> /**</span>
276
+ <a name="l00260"></a>00260 <span class="comment"> * Send a scalar message over the underlying file descriptor.</span>
277
+ <a name="l00261"></a>00261 <span class="comment"> *</span>
278
+ <a name="l00262"></a>00262 <span class="comment"> * @param data The scalar message's content.</span>
279
+ <a name="l00263"></a>00263 <span class="comment"> * @param size The number of bytes in &lt;tt&gt;data&lt;/tt&gt;.</span>
280
+ <a name="l00264"></a>00264 <span class="comment"> * @pre &lt;tt&gt;data != NULL&lt;/tt&gt;</span>
281
+ <a name="l00265"></a>00265 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
282
+ <a name="l00266"></a>00266 <span class="comment"> * @throws boost::thread_interrupted</span>
283
+ <a name="l00267"></a>00267 <span class="comment"> * @see readScalar(), writeScalar(const string &amp;)</span>
284
+ <a name="l00268"></a>00268 <span class="comment"> */</span>
285
+ <a name="l00269"></a><a class="code" href="classPassenger_1_1MessageChannel.html#80977020ef895f3ea790c5d28a333dda">00269</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#44e01a783c48abadeea0d915b9893bfb" title="Send a scalar message over the underlying file descriptor.">writeScalar</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *data, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
286
+ <a name="l00270"></a>00270 uint32_t l = htonl(size);
287
+ <a name="l00271"></a>00271 <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>((<span class="keyword">const</span> <span class="keywordtype">char</span> *) &amp;l, <span class="keyword">sizeof</span>(uint32_t));
288
+ <a name="l00272"></a>00272 <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(data, size);
289
+ <a name="l00273"></a>00273 }
290
+ <a name="l00274"></a>00274 <span class="comment"></span>
291
+ <a name="l00275"></a>00275 <span class="comment"> /**</span>
292
+ <a name="l00276"></a>00276 <span class="comment"> * Send a block of data over the underlying file descriptor.</span>
293
+ <a name="l00277"></a>00277 <span class="comment"> * This method blocks until everything is sent.</span>
294
+ <a name="l00278"></a>00278 <span class="comment"> *</span>
295
+ <a name="l00279"></a>00279 <span class="comment"> * @param data The data to send.</span>
296
+ <a name="l00280"></a>00280 <span class="comment"> * @param size The number of bytes in &lt;tt&gt;data&lt;/tt&gt;.</span>
297
+ <a name="l00281"></a>00281 <span class="comment"> * @pre &lt;tt&gt;data != NULL&lt;/tt&gt;</span>
298
+ <a name="l00282"></a>00282 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
299
+ <a name="l00283"></a>00283 <span class="comment"> * @throws boost::thread_interrupted</span>
300
+ <a name="l00284"></a>00284 <span class="comment"> * @see readRaw()</span>
301
+ <a name="l00285"></a>00285 <span class="comment"> */</span>
302
+ <a name="l00286"></a><a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef">00286</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *data, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
303
+ <a name="l00287"></a>00287 ssize_t ret;
304
+ <a name="l00288"></a>00288 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> written = 0;
305
+ <a name="l00289"></a>00289 <span class="keywordflow">do</span> {
306
+ <a name="l00290"></a>00290 ret = syscalls::write(fd, data + written, size - written);
307
+ <a name="l00291"></a>00291 <span class="keywordflow">if</span> (ret == -1) {
308
+ <a name="l00292"></a>00292 <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">"write() failed"</span>, errno);
309
+ <a name="l00293"></a>00293 } <span class="keywordflow">else</span> {
310
+ <a name="l00294"></a>00294 written += ret;
311
+ <a name="l00295"></a>00295 }
312
+ <a name="l00296"></a>00296 } <span class="keywordflow">while</span> (written &lt; size);
313
+ <a name="l00297"></a>00297 }
314
+ <a name="l00298"></a>00298 <span class="comment"></span>
315
+ <a name="l00299"></a>00299 <span class="comment"> /**</span>
316
+ <a name="l00300"></a>00300 <span class="comment"> * Send a block of data over the underlying file descriptor.</span>
317
+ <a name="l00301"></a>00301 <span class="comment"> * This method blocks until everything is sent.</span>
318
+ <a name="l00302"></a>00302 <span class="comment"> *</span>
319
+ <a name="l00303"></a>00303 <span class="comment"> * @param data The data to send.</span>
320
+ <a name="l00304"></a>00304 <span class="comment"> * @pre &lt;tt&gt;data != NULL&lt;/tt&gt;</span>
321
+ <a name="l00305"></a>00305 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
322
+ <a name="l00306"></a>00306 <span class="comment"> * @throws boost::thread_interrupted</span>
323
+ <a name="l00307"></a>00307 <span class="comment"> */</span>
324
+ <a name="l00308"></a><a class="code" href="classPassenger_1_1MessageChannel.html#cfa38f4f0e22ec16350b8cc159e8e364">00308</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;data) {
325
+ <a name="l00309"></a>00309 <a class="code" href="classPassenger_1_1MessageChannel.html#069314e4c7e1fe8c8ab36e16d2cc5fef" title="Send a block of data over the underlying file descriptor.">writeRaw</a>(data.c_str(), data.size());
326
+ <a name="l00310"></a>00310 }
327
+ <a name="l00311"></a>00311 <span class="comment"></span>
328
+ <a name="l00312"></a>00312 <span class="comment"> /**</span>
329
+ <a name="l00313"></a>00313 <span class="comment"> * Pass a file descriptor. This only works if the underlying file</span>
330
+ <a name="l00314"></a>00314 <span class="comment"> * descriptor is a Unix socket.</span>
331
+ <a name="l00315"></a>00315 <span class="comment"> *</span>
332
+ <a name="l00316"></a>00316 <span class="comment"> * @param fileDescriptor The file descriptor to pass.</span>
333
+ <a name="l00317"></a>00317 <span class="comment"> * @throws SystemException Something went wrong during file descriptor passing.</span>
334
+ <a name="l00318"></a>00318 <span class="comment"> * @throws boost::thread_interrupted</span>
335
+ <a name="l00319"></a>00319 <span class="comment"> * @pre &lt;tt&gt;fileDescriptor &gt;= 0&lt;/tt&gt;</span>
336
+ <a name="l00320"></a>00320 <span class="comment"> * @see readFileDescriptor()</span>
337
+ <a name="l00321"></a>00321 <span class="comment"> */</span>
338
+ <a name="l00322"></a><a class="code" href="classPassenger_1_1MessageChannel.html#73e3f3cda384c085a2af0e820ccd3e98">00322</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#73e3f3cda384c085a2af0e820ccd3e98" title="Pass a file descriptor.">writeFileDescriptor</a>(<span class="keywordtype">int</span> fileDescriptor) {
339
+ <a name="l00323"></a>00323 <span class="keyword">struct </span>msghdr msg;
340
+ <a name="l00324"></a>00324 <span class="keyword">struct </span>iovec vec;
341
+ <a name="l00325"></a>00325 <span class="keywordtype">char</span> dummy[1];
342
+ <a name="l00326"></a>00326 <span class="preprocessor"> #if defined(__APPLE__) || defined(__SOLARIS__)</span>
343
+ <a name="l00327"></a>00327 <span class="preprocessor"></span> <span class="keyword">struct </span>{
344
+ <a name="l00328"></a>00328 <span class="keyword">struct </span>cmsghdr header;
345
+ <a name="l00329"></a>00329 <span class="keywordtype">int</span> fd;
346
+ <a name="l00330"></a>00330 } control_data;
347
+ <a name="l00331"></a>00331 <span class="preprocessor"> #else</span>
348
+ <a name="l00332"></a>00332 <span class="preprocessor"></span> <span class="keywordtype">char</span> control_data[CMSG_SPACE(<span class="keyword">sizeof</span>(<span class="keywordtype">int</span>))];
349
+ <a name="l00333"></a>00333 <span class="preprocessor"> #endif</span>
350
+ <a name="l00334"></a>00334 <span class="preprocessor"></span> <span class="keyword">struct </span>cmsghdr *control_header;
351
+ <a name="l00335"></a>00335 <span class="keywordtype">int</span> ret;
352
+ <a name="l00336"></a>00336
353
+ <a name="l00337"></a>00337 msg.msg_name = NULL;
354
+ <a name="l00338"></a>00338 msg.msg_namelen = 0;
355
+ <a name="l00339"></a>00339
356
+ <a name="l00340"></a>00340 <span class="comment">/* Linux and Solaris require msg_iov to be non-NULL. */</span>
357
+ <a name="l00341"></a>00341 dummy[0] = <span class="charliteral">'\0'</span>;
358
+ <a name="l00342"></a>00342 vec.iov_base = dummy;
359
+ <a name="l00343"></a>00343 vec.iov_len = <span class="keyword">sizeof</span>(dummy);
360
+ <a name="l00344"></a>00344 msg.msg_iov = &amp;vec;
361
+ <a name="l00345"></a>00345 msg.msg_iovlen = 1;
362
+ <a name="l00346"></a>00346
363
+ <a name="l00347"></a>00347 msg.msg_control = (caddr_t) &amp;control_data;
364
+ <a name="l00348"></a>00348 msg.msg_controllen = <span class="keyword">sizeof</span>(control_data);
365
+ <a name="l00349"></a>00349 msg.msg_flags = 0;
366
+ <a name="l00350"></a>00350
367
+ <a name="l00351"></a>00351 control_header = CMSG_FIRSTHDR(&amp;msg);
368
+ <a name="l00352"></a>00352 control_header-&gt;cmsg_level = SOL_SOCKET;
369
+ <a name="l00353"></a>00353 control_header-&gt;cmsg_type = SCM_RIGHTS;
370
+ <a name="l00354"></a>00354 <span class="preprocessor"> #if defined(__APPLE__) || defined(__SOLARIS__)</span>
371
+ <a name="l00355"></a>00355 <span class="preprocessor"></span> control_header-&gt;cmsg_len = <span class="keyword">sizeof</span>(control_data);
372
+ <a name="l00356"></a>00356 control_data.fd = fileDescriptor;
373
+ <a name="l00357"></a>00357 <span class="preprocessor"> #else</span>
374
+ <a name="l00358"></a>00358 <span class="preprocessor"></span> control_header-&gt;cmsg_len = CMSG_LEN(<span class="keyword">sizeof</span>(<span class="keywordtype">int</span>));
375
+ <a name="l00359"></a>00359 memcpy(CMSG_DATA(control_header), &amp;fileDescriptor, <span class="keyword">sizeof</span>(<span class="keywordtype">int</span>));
376
+ <a name="l00360"></a>00360 <span class="preprocessor"> #endif</span>
377
+ <a name="l00361"></a>00361 <span class="preprocessor"></span>
378
+ <a name="l00362"></a>00362 ret = syscalls::sendmsg(fd, &amp;msg, 0);
379
+ <a name="l00363"></a>00363 <span class="keywordflow">if</span> (ret == -1) {
380
+ <a name="l00364"></a>00364 <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 send file descriptor with sendmsg()"</span>, errno);
382
381
  <a name="l00365"></a>00365 }
383
- <a name="l00366"></a>00366 <span class="keywordflow">return</span> <span class="keyword">true</span>;
384
- <a name="l00367"></a>00367 }
385
- <a name="l00368"></a>00368 <span class="comment"></span>
386
- <a name="l00369"></a>00369 <span class="comment"> /**</span>
387
- <a name="l00370"></a>00370 <span class="comment"> * Read a scalar message from the underlying file descriptor.</span>
388
- <a name="l00371"></a>00371 <span class="comment"> *</span>
389
- <a name="l00372"></a>00372 <span class="comment"> * @param output The message will be put in here.</span>
390
- <a name="l00373"></a>00373 <span class="comment"> * @returns Whether end-of-file was reached during reading.</span>
391
- <a name="l00374"></a>00374 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
382
+ <a name="l00366"></a>00366 }
383
+ <a name="l00367"></a>00367 <span class="comment"></span>
384
+ <a name="l00368"></a>00368 <span class="comment"> /**</span>
385
+ <a name="l00369"></a>00369 <span class="comment"> * Read an array message from the underlying file descriptor.</span>
386
+ <a name="l00370"></a>00370 <span class="comment"> *</span>
387
+ <a name="l00371"></a>00371 <span class="comment"> * @param args The message will be put in this variable.</span>
388
+ <a name="l00372"></a>00372 <span class="comment"> * @return Whether end-of-file has been reached. If so, then the contents</span>
389
+ <a name="l00373"></a>00373 <span class="comment"> * of &lt;tt&gt;args&lt;/tt&gt; will be undefined.</span>
390
+ <a name="l00374"></a>00374 <span class="comment"> * @throws SystemException If an error occured while receiving the message.</span>
392
391
  <a name="l00375"></a>00375 <span class="comment"> * @throws boost::thread_interrupted</span>
393
- <a name="l00376"></a>00376 <span class="comment"> * @see writeScalar()</span>
392
+ <a name="l00376"></a>00376 <span class="comment"> * @see write()</span>
394
393
  <a name="l00377"></a>00377 <span class="comment"> */</span>
395
- <a name="l00378"></a><a class="code" href="classPassenger_1_1MessageChannel.html#4ce6a0e751b5e3563bee583c231569bc">00378</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1MessageChannel.html#4ce6a0e751b5e3563bee583c231569bc" title="Read a scalar message from the underlying file descriptor.">readScalar</a>(<span class="keywordtype">string</span> &amp;output) {
396
- <a name="l00379"></a>00379 uint32_t size;
397
- <a name="l00380"></a>00380 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> remaining;
398
- <a name="l00381"></a>00381
399
- <a name="l00382"></a>00382 <span class="keywordflow">if</span> (!<a class="code" href="classPassenger_1_1MessageChannel.html#cd1d1bd1cc787784c8b54f5471fff479" title="Read exactly size bytes of data from the underlying file descriptor, and put the...">readRaw</a>(&amp;size, <span class="keyword">sizeof</span>(uint32_t))) {
400
- <a name="l00383"></a>00383 <span class="keywordflow">return</span> <span class="keyword">false</span>;
401
- <a name="l00384"></a>00384 }
402
- <a name="l00385"></a>00385 size = ntohl(size);
403
- <a name="l00386"></a>00386
404
- <a name="l00387"></a>00387 output.clear();
405
- <a name="l00388"></a>00388 output.reserve(size);
406
- <a name="l00389"></a>00389 remaining = size;
407
- <a name="l00390"></a>00390 <span class="keywordflow">while</span> (remaining &gt; 0) {
408
- <a name="l00391"></a>00391 <span class="keywordtype">char</span> buf[1024 * 32];
409
- <a name="l00392"></a>00392 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockSize = min((<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>) <span class="keyword">sizeof</span>(buf), remaining);
410
- <a name="l00393"></a>00393
411
- <a name="l00394"></a>00394 <span class="keywordflow">if</span> (!<a class="code" href="classPassenger_1_1MessageChannel.html#cd1d1bd1cc787784c8b54f5471fff479" title="Read exactly size bytes of data from the underlying file descriptor, and put the...">readRaw</a>(buf, blockSize)) {
412
- <a name="l00395"></a>00395 <span class="keywordflow">return</span> <span class="keyword">false</span>;
413
- <a name="l00396"></a>00396 }
414
- <a name="l00397"></a>00397 output.append(buf, blockSize);
415
- <a name="l00398"></a>00398 remaining -= blockSize;
416
- <a name="l00399"></a>00399 }
417
- <a name="l00400"></a>00400 <span class="keywordflow">return</span> <span class="keyword">true</span>;
418
- <a name="l00401"></a>00401 }
419
- <a name="l00402"></a>00402 <span class="comment"></span>
420
- <a name="l00403"></a>00403 <span class="comment"> /**</span>
421
- <a name="l00404"></a>00404 <span class="comment"> * Read exactly &lt;tt&gt;size&lt;/tt&gt; bytes of data from the underlying file descriptor,</span>
422
- <a name="l00405"></a>00405 <span class="comment"> * and put the result in &lt;tt&gt;buf&lt;/tt&gt;. If end-of-file has been reached, or if</span>
423
- <a name="l00406"></a>00406 <span class="comment"> * end-of-file was encountered before &lt;tt&gt;size&lt;/tt&gt; bytes have been read, then</span>
424
- <a name="l00407"></a>00407 <span class="comment"> * &lt;tt&gt;false&lt;/tt&gt; will be returned. Otherwise (i.e. if the read was successful),</span>
425
- <a name="l00408"></a>00408 <span class="comment"> * &lt;tt&gt;true&lt;/tt&gt; will be returned.</span>
426
- <a name="l00409"></a>00409 <span class="comment"> *</span>
427
- <a name="l00410"></a>00410 <span class="comment"> * @param buf The buffer to place the read data in. This buffer must be at least</span>
428
- <a name="l00411"></a>00411 <span class="comment"> * &lt;tt&gt;size&lt;/tt&gt; bytes long.</span>
429
- <a name="l00412"></a>00412 <span class="comment"> * @param size The number of bytes to read.</span>
430
- <a name="l00413"></a>00413 <span class="comment"> * @return Whether reading was successful or whether EOF was reached.</span>
431
- <a name="l00414"></a>00414 <span class="comment"> * @pre buf != NULL</span>
432
- <a name="l00415"></a>00415 <span class="comment"> * @throws SystemException Something went wrong during reading.</span>
433
- <a name="l00416"></a>00416 <span class="comment"> * @throws boost::thread_interrupted</span>
434
- <a name="l00417"></a>00417 <span class="comment"> * @see writeRaw()</span>
435
- <a name="l00418"></a>00418 <span class="comment"> */</span>
436
- <a name="l00419"></a><a class="code" href="classPassenger_1_1MessageChannel.html#cd1d1bd1cc787784c8b54f5471fff479">00419</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1MessageChannel.html#cd1d1bd1cc787784c8b54f5471fff479" title="Read exactly size bytes of data from the underlying file descriptor, and put the...">readRaw</a>(<span class="keywordtype">void</span> *buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
437
- <a name="l00420"></a>00420 ssize_t ret;
438
- <a name="l00421"></a>00421 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> alreadyRead = 0;
439
- <a name="l00422"></a>00422
440
- <a name="l00423"></a>00423 <span class="keywordflow">while</span> (alreadyRead &lt; size) {
441
- <a name="l00424"></a>00424 ret = InterruptableCalls::read(fd, (<span class="keywordtype">char</span> *) buf + alreadyRead, size - alreadyRead);
442
- <a name="l00425"></a>00425 <span class="keywordflow">if</span> (ret == -1) {
443
- <a name="l00426"></a>00426 <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">"read() failed"</span>, errno);
444
- <a name="l00427"></a>00427 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ret == 0) {
445
- <a name="l00428"></a>00428 <span class="keywordflow">return</span> <span class="keyword">false</span>;
446
- <a name="l00429"></a>00429 } <span class="keywordflow">else</span> {
447
- <a name="l00430"></a>00430 alreadyRead += ret;
448
- <a name="l00431"></a>00431 }
449
- <a name="l00432"></a>00432 }
450
- <a name="l00433"></a>00433 <span class="keywordflow">return</span> <span class="keyword">true</span>;
451
- <a name="l00434"></a>00434 }
452
- <a name="l00435"></a>00435 <span class="comment"></span>
453
- <a name="l00436"></a>00436 <span class="comment"> /**</span>
454
- <a name="l00437"></a>00437 <span class="comment"> * Receive a file descriptor, which had been passed over the underlying</span>
455
- <a name="l00438"></a>00438 <span class="comment"> * file descriptor.</span>
456
- <a name="l00439"></a>00439 <span class="comment"> *</span>
457
- <a name="l00440"></a>00440 <span class="comment"> * @return The passed file descriptor.</span>
458
- <a name="l00441"></a>00441 <span class="comment"> * @throws SystemException If something went wrong during the</span>
459
- <a name="l00442"></a>00442 <span class="comment"> * receiving of a file descriptor. Perhaps the underlying</span>
460
- <a name="l00443"></a>00443 <span class="comment"> * file descriptor isn't a Unix socket.</span>
461
- <a name="l00444"></a>00444 <span class="comment"> * @throws IOException Whatever was received doesn't seem to be a</span>
462
- <a name="l00445"></a>00445 <span class="comment"> * file descriptor.</span>
463
- <a name="l00446"></a>00446 <span class="comment"> * @throws boost::thread_interrupted</span>
464
- <a name="l00447"></a>00447 <span class="comment"> */</span>
465
- <a name="l00448"></a><a class="code" href="classPassenger_1_1MessageChannel.html#1561b7e4a0f4d39ea431f456e5655488">00448</a> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1MessageChannel.html#1561b7e4a0f4d39ea431f456e5655488" title="Receive a file descriptor, which had been passed over the underlying file descriptor...">readFileDescriptor</a>() {
466
- <a name="l00449"></a>00449 <span class="keyword">struct </span>msghdr msg;
467
- <a name="l00450"></a>00450 <span class="keyword">struct </span>iovec vec;
468
- <a name="l00451"></a>00451 <span class="keywordtype">char</span> dummy[1];
469
- <a name="l00452"></a>00452 <span class="preprocessor"> #ifdef __APPLE__</span>
470
- <a name="l00453"></a>00453 <span class="preprocessor"></span> <span class="comment">// File descriptor passing macros (CMSG_*) seem to be broken</span>
471
- <a name="l00454"></a>00454 <span class="comment">// on 64-bit MacOS X. This structure works around the problem.</span>
472
- <a name="l00455"></a>00455 <span class="keyword">struct </span>{
473
- <a name="l00456"></a>00456 <span class="keyword">struct </span>cmsghdr header;
474
- <a name="l00457"></a>00457 <span class="keywordtype">int</span> fd;
475
- <a name="l00458"></a>00458 } control_data;
476
- <a name="l00459"></a>00459 <span class="preprocessor"> #define EXPECTED_CMSG_LEN sizeof(control_data)</span>
477
- <a name="l00460"></a>00460 <span class="preprocessor"></span><span class="preprocessor"> #else</span>
478
- <a name="l00461"></a>00461 <span class="preprocessor"></span> <span class="keywordtype">char</span> control_data[CMSG_SPACE(<span class="keyword">sizeof</span>(<span class="keywordtype">int</span>))];
479
- <a name="l00462"></a>00462 <span class="preprocessor"> #define EXPECTED_CMSG_LEN CMSG_LEN(sizeof(int))</span>
480
- <a name="l00463"></a>00463 <span class="preprocessor"></span><span class="preprocessor"> #endif</span>
481
- <a name="l00464"></a>00464 <span class="preprocessor"></span> <span class="keyword">struct </span>cmsghdr *control_header;
482
- <a name="l00465"></a>00465 <span class="keywordtype">int</span> ret;
483
- <a name="l00466"></a>00466
484
- <a name="l00467"></a>00467 msg.msg_name = NULL;
485
- <a name="l00468"></a>00468 msg.msg_namelen = 0;
486
- <a name="l00469"></a>00469
487
- <a name="l00470"></a>00470 dummy[0] = <span class="charliteral">'\0'</span>;
488
- <a name="l00471"></a>00471 vec.iov_base = dummy;
489
- <a name="l00472"></a>00472 vec.iov_len = <span class="keyword">sizeof</span>(dummy);
490
- <a name="l00473"></a>00473 msg.msg_iov = &amp;vec;
491
- <a name="l00474"></a>00474 msg.msg_iovlen = 1;
492
- <a name="l00475"></a>00475
493
- <a name="l00476"></a>00476 msg.msg_control = (caddr_t) &amp;control_data;
494
- <a name="l00477"></a>00477 msg.msg_controllen = <span class="keyword">sizeof</span>(control_data);
495
- <a name="l00478"></a>00478 msg.msg_flags = 0;
496
- <a name="l00479"></a>00479
497
- <a name="l00480"></a>00480 ret = InterruptableCalls::recvmsg(fd, &amp;msg, 0);
498
- <a name="l00481"></a>00481 <span class="keywordflow">if</span> (ret == -1) {
499
- <a name="l00482"></a>00482 <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 read file descriptor with recvmsg()"</span>, errno);
500
- <a name="l00483"></a>00483 }
501
- <a name="l00484"></a>00484
502
- <a name="l00485"></a>00485 control_header = CMSG_FIRSTHDR(&amp;msg);
503
- <a name="l00486"></a>00486 <span class="keywordflow">if</span> (control_header-&gt;cmsg_len != EXPECTED_CMSG_LEN
504
- <a name="l00487"></a>00487 || control_header-&gt;cmsg_level != SOL_SOCKET
505
- <a name="l00488"></a>00488 || control_header-&gt;cmsg_type != SCM_RIGHTS) {
506
- <a name="l00489"></a>00489 <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">"No valid file descriptor received."</span>);
507
- <a name="l00490"></a>00490 }
508
- <a name="l00491"></a>00491 <span class="preprocessor"> #ifdef __APPLE__</span>
509
- <a name="l00492"></a>00492 <span class="preprocessor"></span> <span class="keywordflow">return</span> control_data.fd;
510
- <a name="l00493"></a>00493 <span class="preprocessor"> #else</span>
511
- <a name="l00494"></a>00494 <span class="preprocessor"></span> <span class="keywordflow">return</span> *((<span class="keywordtype">int</span> *) CMSG_DATA(control_header));
512
- <a name="l00495"></a>00495 <span class="preprocessor"> #endif</span>
513
- <a name="l00496"></a>00496 <span class="preprocessor"></span> }
514
- <a name="l00497"></a>00497 };
515
- <a name="l00498"></a>00498
516
- <a name="l00499"></a>00499 } <span class="comment">// namespace Passenger</span>
517
- <a name="l00500"></a>00500
518
- <a name="l00501"></a>00501 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_MESSAGE_CHANNEL_H_ */</span>
394
+ <a name="l00378"></a><a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e">00378</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1MessageChannel.html#129659b60d1a663337873d2af944431e" title="Read an array message from the underlying file descriptor.">read</a>(vector&lt;string&gt; &amp;args) {
395
+ <a name="l00379"></a>00379 uint16_t size;
396
+ <a name="l00380"></a>00380 <span class="keywordtype">int</span> ret;
397
+ <a name="l00381"></a>00381 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> alreadyRead = 0;
398
+ <a name="l00382"></a>00382
399
+ <a name="l00383"></a>00383 <span class="keywordflow">do</span> {
400
+ <a name="l00384"></a>00384 ret = syscalls::read(fd, (<span class="keywordtype">char</span> *) &amp;size + alreadyRead, <span class="keyword">sizeof</span>(size) - alreadyRead);
401
+ <a name="l00385"></a>00385 <span class="keywordflow">if</span> (ret == -1) {
402
+ <a name="l00386"></a>00386 <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">"read() failed"</span>, errno);
403
+ <a name="l00387"></a>00387 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ret == 0) {
404
+ <a name="l00388"></a>00388 <span class="keywordflow">return</span> <span class="keyword">false</span>;
405
+ <a name="l00389"></a>00389 }
406
+ <a name="l00390"></a>00390 alreadyRead += ret;
407
+ <a name="l00391"></a>00391 } <span class="keywordflow">while</span> (alreadyRead &lt; <span class="keyword">sizeof</span>(size));
408
+ <a name="l00392"></a>00392 size = ntohs(size);
409
+ <a name="l00393"></a>00393
410
+ <a name="l00394"></a>00394 <span class="keywordtype">string</span> buffer;
411
+ <a name="l00395"></a>00395 args.clear();
412
+ <a name="l00396"></a>00396 buffer.reserve(size);
413
+ <a name="l00397"></a>00397 <span class="keywordflow">while</span> (buffer.size() &lt; size) {
414
+ <a name="l00398"></a>00398 <span class="keywordtype">char</span> tmp[1024 * 8];
415
+ <a name="l00399"></a>00399 ret = syscalls::read(fd, tmp, min(size - buffer.size(), <span class="keyword">sizeof</span>(tmp)));
416
+ <a name="l00400"></a>00400 <span class="keywordflow">if</span> (ret == -1) {
417
+ <a name="l00401"></a>00401 <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">"read() failed"</span>, errno);
418
+ <a name="l00402"></a>00402 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ret == 0) {
419
+ <a name="l00403"></a>00403 <span class="keywordflow">return</span> <span class="keyword">false</span>;
420
+ <a name="l00404"></a>00404 }
421
+ <a name="l00405"></a>00405 buffer.append(tmp, ret);
422
+ <a name="l00406"></a>00406 }
423
+ <a name="l00407"></a>00407
424
+ <a name="l00408"></a>00408 <span class="keywordflow">if</span> (!buffer.empty()) {
425
+ <a name="l00409"></a>00409 string::size_type start = 0, pos;
426
+ <a name="l00410"></a>00410 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;const_buffer(buffer);
427
+ <a name="l00411"></a>00411 <span class="keywordflow">while</span> ((pos = const_buffer.find(<span class="charliteral">'\0'</span>, start)) != string::npos) {
428
+ <a name="l00412"></a>00412 args.push_back(const_buffer.substr(start, pos - start));
429
+ <a name="l00413"></a>00413 start = pos + 1;
430
+ <a name="l00414"></a>00414 }
431
+ <a name="l00415"></a>00415 }
432
+ <a name="l00416"></a>00416 <span class="keywordflow">return</span> <span class="keyword">true</span>;
433
+ <a name="l00417"></a>00417 }
434
+ <a name="l00418"></a>00418 <span class="comment"></span>
435
+ <a name="l00419"></a>00419 <span class="comment"> /**</span>
436
+ <a name="l00420"></a>00420 <span class="comment"> * Read a scalar message from the underlying file descriptor.</span>
437
+ <a name="l00421"></a>00421 <span class="comment"> *</span>
438
+ <a name="l00422"></a>00422 <span class="comment"> * @param output The message will be put in here.</span>
439
+ <a name="l00423"></a>00423 <span class="comment"> * @returns Whether end-of-file was reached during reading.</span>
440
+ <a name="l00424"></a>00424 <span class="comment"> * @throws SystemException An error occured while writing the data to the file descriptor.</span>
441
+ <a name="l00425"></a>00425 <span class="comment"> * @throws boost::thread_interrupted</span>
442
+ <a name="l00426"></a>00426 <span class="comment"> * @see writeScalar()</span>
443
+ <a name="l00427"></a>00427 <span class="comment"> */</span>
444
+ <a name="l00428"></a><a class="code" href="classPassenger_1_1MessageChannel.html#4ce6a0e751b5e3563bee583c231569bc">00428</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1MessageChannel.html#4ce6a0e751b5e3563bee583c231569bc" title="Read a scalar message from the underlying file descriptor.">readScalar</a>(<span class="keywordtype">string</span> &amp;output) {
445
+ <a name="l00429"></a>00429 uint32_t size;
446
+ <a name="l00430"></a>00430 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> remaining;
447
+ <a name="l00431"></a>00431
448
+ <a name="l00432"></a>00432 <span class="keywordflow">if</span> (!<a class="code" href="classPassenger_1_1MessageChannel.html#cd1d1bd1cc787784c8b54f5471fff479" title="Read exactly size bytes of data from the underlying file descriptor, and put the...">readRaw</a>(&amp;size, <span class="keyword">sizeof</span>(uint32_t))) {
449
+ <a name="l00433"></a>00433 <span class="keywordflow">return</span> <span class="keyword">false</span>;
450
+ <a name="l00434"></a>00434 }
451
+ <a name="l00435"></a>00435 size = ntohl(size);
452
+ <a name="l00436"></a>00436
453
+ <a name="l00437"></a>00437 output.clear();
454
+ <a name="l00438"></a>00438 output.reserve(size);
455
+ <a name="l00439"></a>00439 remaining = size;
456
+ <a name="l00440"></a>00440 <span class="keywordflow">while</span> (remaining &gt; 0) {
457
+ <a name="l00441"></a>00441 <span class="keywordtype">char</span> buf[1024 * 32];
458
+ <a name="l00442"></a>00442 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockSize = min((<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>) <span class="keyword">sizeof</span>(buf), remaining);
459
+ <a name="l00443"></a>00443
460
+ <a name="l00444"></a>00444 <span class="keywordflow">if</span> (!<a class="code" href="classPassenger_1_1MessageChannel.html#cd1d1bd1cc787784c8b54f5471fff479" title="Read exactly size bytes of data from the underlying file descriptor, and put the...">readRaw</a>(buf, blockSize)) {
461
+ <a name="l00445"></a>00445 <span class="keywordflow">return</span> <span class="keyword">false</span>;
462
+ <a name="l00446"></a>00446 }
463
+ <a name="l00447"></a>00447 output.append(buf, blockSize);
464
+ <a name="l00448"></a>00448 remaining -= blockSize;
465
+ <a name="l00449"></a>00449 }
466
+ <a name="l00450"></a>00450 <span class="keywordflow">return</span> <span class="keyword">true</span>;
467
+ <a name="l00451"></a>00451 }
468
+ <a name="l00452"></a>00452 <span class="comment"></span>
469
+ <a name="l00453"></a>00453 <span class="comment"> /**</span>
470
+ <a name="l00454"></a>00454 <span class="comment"> * Read exactly &lt;tt&gt;size&lt;/tt&gt; bytes of data from the underlying file descriptor,</span>
471
+ <a name="l00455"></a>00455 <span class="comment"> * and put the result in &lt;tt&gt;buf&lt;/tt&gt;. If end-of-file has been reached, or if</span>
472
+ <a name="l00456"></a>00456 <span class="comment"> * end-of-file was encountered before &lt;tt&gt;size&lt;/tt&gt; bytes have been read, then</span>
473
+ <a name="l00457"></a>00457 <span class="comment"> * &lt;tt&gt;false&lt;/tt&gt; will be returned. Otherwise (i.e. if the read was successful),</span>
474
+ <a name="l00458"></a>00458 <span class="comment"> * &lt;tt&gt;true&lt;/tt&gt; will be returned.</span>
475
+ <a name="l00459"></a>00459 <span class="comment"> *</span>
476
+ <a name="l00460"></a>00460 <span class="comment"> * @param buf The buffer to place the read data in. This buffer must be at least</span>
477
+ <a name="l00461"></a>00461 <span class="comment"> * &lt;tt&gt;size&lt;/tt&gt; bytes long.</span>
478
+ <a name="l00462"></a>00462 <span class="comment"> * @param size The number of bytes to read.</span>
479
+ <a name="l00463"></a>00463 <span class="comment"> * @return Whether reading was successful or whether EOF was reached.</span>
480
+ <a name="l00464"></a>00464 <span class="comment"> * @pre buf != NULL</span>
481
+ <a name="l00465"></a>00465 <span class="comment"> * @throws SystemException Something went wrong during reading.</span>
482
+ <a name="l00466"></a>00466 <span class="comment"> * @throws boost::thread_interrupted</span>
483
+ <a name="l00467"></a>00467 <span class="comment"> * @see writeRaw()</span>
484
+ <a name="l00468"></a>00468 <span class="comment"> */</span>
485
+ <a name="l00469"></a><a class="code" href="classPassenger_1_1MessageChannel.html#cd1d1bd1cc787784c8b54f5471fff479">00469</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1MessageChannel.html#cd1d1bd1cc787784c8b54f5471fff479" title="Read exactly size bytes of data from the underlying file descriptor, and put the...">readRaw</a>(<span class="keywordtype">void</span> *buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
486
+ <a name="l00470"></a>00470 ssize_t ret;
487
+ <a name="l00471"></a>00471 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> alreadyRead = 0;
488
+ <a name="l00472"></a>00472
489
+ <a name="l00473"></a>00473 <span class="keywordflow">while</span> (alreadyRead &lt; size) {
490
+ <a name="l00474"></a>00474 ret = syscalls::read(fd, (<span class="keywordtype">char</span> *) buf + alreadyRead, size - alreadyRead);
491
+ <a name="l00475"></a>00475 <span class="keywordflow">if</span> (ret == -1) {
492
+ <a name="l00476"></a>00476 <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">"read() failed"</span>, errno);
493
+ <a name="l00477"></a>00477 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ret == 0) {
494
+ <a name="l00478"></a>00478 <span class="keywordflow">return</span> <span class="keyword">false</span>;
495
+ <a name="l00479"></a>00479 } <span class="keywordflow">else</span> {
496
+ <a name="l00480"></a>00480 alreadyRead += ret;
497
+ <a name="l00481"></a>00481 }
498
+ <a name="l00482"></a>00482 }
499
+ <a name="l00483"></a>00483 <span class="keywordflow">return</span> <span class="keyword">true</span>;
500
+ <a name="l00484"></a>00484 }
501
+ <a name="l00485"></a>00485 <span class="comment"></span>
502
+ <a name="l00486"></a>00486 <span class="comment"> /**</span>
503
+ <a name="l00487"></a>00487 <span class="comment"> * Receive a file descriptor, which had been passed over the underlying</span>
504
+ <a name="l00488"></a>00488 <span class="comment"> * file descriptor.</span>
505
+ <a name="l00489"></a>00489 <span class="comment"> *</span>
506
+ <a name="l00490"></a>00490 <span class="comment"> * @return The passed file descriptor.</span>
507
+ <a name="l00491"></a>00491 <span class="comment"> * @throws SystemException If something went wrong during the</span>
508
+ <a name="l00492"></a>00492 <span class="comment"> * receiving of a file descriptor. Perhaps the underlying</span>
509
+ <a name="l00493"></a>00493 <span class="comment"> * file descriptor isn't a Unix socket.</span>
510
+ <a name="l00494"></a>00494 <span class="comment"> * @throws IOException Whatever was received doesn't seem to be a</span>
511
+ <a name="l00495"></a>00495 <span class="comment"> * file descriptor.</span>
512
+ <a name="l00496"></a>00496 <span class="comment"> * @throws boost::thread_interrupted</span>
513
+ <a name="l00497"></a>00497 <span class="comment"> */</span>
514
+ <a name="l00498"></a><a class="code" href="classPassenger_1_1MessageChannel.html#1561b7e4a0f4d39ea431f456e5655488">00498</a> <span class="keywordtype">int</span> <a class="code" href="classPassenger_1_1MessageChannel.html#1561b7e4a0f4d39ea431f456e5655488" title="Receive a file descriptor, which had been passed over the underlying file descriptor...">readFileDescriptor</a>() {
515
+ <a name="l00499"></a>00499 <span class="keyword">struct </span>msghdr msg;
516
+ <a name="l00500"></a>00500 <span class="keyword">struct </span>iovec vec;
517
+ <a name="l00501"></a>00501 <span class="keywordtype">char</span> dummy[1];
518
+ <a name="l00502"></a>00502 <span class="preprocessor"> #if defined(__APPLE__) || defined(__SOLARIS__)</span>
519
+ <a name="l00503"></a>00503 <span class="preprocessor"></span> <span class="comment">// File descriptor passing macros (CMSG_*) seem to be broken</span>
520
+ <a name="l00504"></a>00504 <span class="comment">// on 64-bit MacOS X. This structure works around the problem.</span>
521
+ <a name="l00505"></a>00505 <span class="keyword">struct </span>{
522
+ <a name="l00506"></a>00506 <span class="keyword">struct </span>cmsghdr header;
523
+ <a name="l00507"></a>00507 <span class="keywordtype">int</span> fd;
524
+ <a name="l00508"></a>00508 } control_data;
525
+ <a name="l00509"></a>00509 <span class="preprocessor"> #define EXPECTED_CMSG_LEN sizeof(control_data)</span>
526
+ <a name="l00510"></a>00510 <span class="preprocessor"></span><span class="preprocessor"> #else</span>
527
+ <a name="l00511"></a>00511 <span class="preprocessor"></span> <span class="keywordtype">char</span> control_data[CMSG_SPACE(<span class="keyword">sizeof</span>(<span class="keywordtype">int</span>))];
528
+ <a name="l00512"></a>00512 <span class="preprocessor"> #define EXPECTED_CMSG_LEN CMSG_LEN(sizeof(int))</span>
529
+ <a name="l00513"></a>00513 <span class="preprocessor"></span><span class="preprocessor"> #endif</span>
530
+ <a name="l00514"></a>00514 <span class="preprocessor"></span> <span class="keyword">struct </span>cmsghdr *control_header;
531
+ <a name="l00515"></a>00515 <span class="keywordtype">int</span> ret;
532
+ <a name="l00516"></a>00516
533
+ <a name="l00517"></a>00517 msg.msg_name = NULL;
534
+ <a name="l00518"></a>00518 msg.msg_namelen = 0;
535
+ <a name="l00519"></a>00519
536
+ <a name="l00520"></a>00520 dummy[0] = <span class="charliteral">'\0'</span>;
537
+ <a name="l00521"></a>00521 vec.iov_base = dummy;
538
+ <a name="l00522"></a>00522 vec.iov_len = <span class="keyword">sizeof</span>(dummy);
539
+ <a name="l00523"></a>00523 msg.msg_iov = &amp;vec;
540
+ <a name="l00524"></a>00524 msg.msg_iovlen = 1;
541
+ <a name="l00525"></a>00525
542
+ <a name="l00526"></a>00526 msg.msg_control = (caddr_t) &amp;control_data;
543
+ <a name="l00527"></a>00527 msg.msg_controllen = <span class="keyword">sizeof</span>(control_data);
544
+ <a name="l00528"></a>00528 msg.msg_flags = 0;
545
+ <a name="l00529"></a>00529
546
+ <a name="l00530"></a>00530 ret = syscalls::recvmsg(fd, &amp;msg, 0);
547
+ <a name="l00531"></a>00531 <span class="keywordflow">if</span> (ret == -1) {
548
+ <a name="l00532"></a>00532 <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 read file descriptor with recvmsg()"</span>, errno);
549
+ <a name="l00533"></a>00533 }
550
+ <a name="l00534"></a>00534
551
+ <a name="l00535"></a>00535 control_header = CMSG_FIRSTHDR(&amp;msg);
552
+ <a name="l00536"></a>00536 <span class="keywordflow">if</span> (control_header-&gt;cmsg_len != EXPECTED_CMSG_LEN
553
+ <a name="l00537"></a>00537 || control_header-&gt;cmsg_level != SOL_SOCKET
554
+ <a name="l00538"></a>00538 || control_header-&gt;cmsg_type != SCM_RIGHTS) {
555
+ <a name="l00539"></a>00539 <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">"No valid file descriptor received."</span>);
556
+ <a name="l00540"></a>00540 }
557
+ <a name="l00541"></a>00541 <span class="preprocessor"> #if defined(__APPLE__) || defined(__SOLARIS__)</span>
558
+ <a name="l00542"></a>00542 <span class="preprocessor"></span> <span class="keywordflow">return</span> control_data.fd;
559
+ <a name="l00543"></a>00543 <span class="preprocessor"> #else</span>
560
+ <a name="l00544"></a>00544 <span class="preprocessor"></span> <span class="keywordflow">return</span> *((<span class="keywordtype">int</span> *) CMSG_DATA(control_header));
561
+ <a name="l00545"></a>00545 <span class="preprocessor"> #endif</span>
562
+ <a name="l00546"></a>00546 <span class="preprocessor"></span> }
563
+ <a name="l00547"></a>00547 <span class="comment"></span>
564
+ <a name="l00548"></a>00548 <span class="comment"> /**</span>
565
+ <a name="l00549"></a>00549 <span class="comment"> * Set the timeout value for reading data from this channel.</span>
566
+ <a name="l00550"></a>00550 <span class="comment"> * If no data can be read within the timeout period, then a</span>
567
+ <a name="l00551"></a>00551 <span class="comment"> * SystemException will be thrown by one of the read methods,</span>
568
+ <a name="l00552"></a>00552 <span class="comment"> * with error code EAGAIN or EWOULDBLOCK.</span>
569
+ <a name="l00553"></a>00553 <span class="comment"> *</span>
570
+ <a name="l00554"></a>00554 <span class="comment"> * @param msec The timeout, in milliseconds. If 0 is given,</span>
571
+ <a name="l00555"></a>00555 <span class="comment"> * there will be no timeout.</span>
572
+ <a name="l00556"></a>00556 <span class="comment"> * @throws SystemException Cannot set the timeout.</span>
573
+ <a name="l00557"></a>00557 <span class="comment"> */</span>
574
+ <a name="l00558"></a><a class="code" href="classPassenger_1_1MessageChannel.html#eb69bffbbb148c9bc8662e20b416c4e2">00558</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#eb69bffbbb148c9bc8662e20b416c4e2" title="Set the timeout value for reading data from this channel.">setReadTimeout</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> msec) {
575
+ <a name="l00559"></a>00559 <span class="comment">// See the comment for setWriteTimeout().</span>
576
+ <a name="l00560"></a>00560 <span class="keyword">struct </span>timeval tv;
577
+ <a name="l00561"></a>00561 <span class="keywordtype">int</span> ret;
578
+ <a name="l00562"></a>00562
579
+ <a name="l00563"></a>00563 tv.tv_sec = msec / 1000;
580
+ <a name="l00564"></a>00564 tv.tv_usec = msec % 1000 * 1000;
581
+ <a name="l00565"></a>00565 ret = syscalls::setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,
582
+ <a name="l00566"></a>00566 &amp;tv, <span class="keyword">sizeof</span>(tv));
583
+ <a name="l00567"></a>00567 <span class="preprocessor"> #ifndef __SOLARIS__</span>
584
+ <a name="l00568"></a>00568 <span class="preprocessor"></span> <span class="comment">// SO_RCVTIMEO is unimplemented and retuns an error on Solaris</span>
585
+ <a name="l00569"></a>00569 <span class="comment">// 9 and 10 SPARC. Seems to work okay without it.</span>
586
+ <a name="l00570"></a>00570 <span class="keywordflow">if</span> (ret == -1) {
587
+ <a name="l00571"></a>00571 <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 set read timeout for socket"</span>, errno);
588
+ <a name="l00572"></a>00572 }
589
+ <a name="l00573"></a>00573 <span class="preprocessor"> #endif</span>
590
+ <a name="l00574"></a>00574 <span class="preprocessor"></span> }
591
+ <a name="l00575"></a>00575 <span class="comment"></span>
592
+ <a name="l00576"></a>00576 <span class="comment"> /**</span>
593
+ <a name="l00577"></a>00577 <span class="comment"> * Set the timeout value for writing data to this channel.</span>
594
+ <a name="l00578"></a>00578 <span class="comment"> * If no data can be written within the timeout period, then a</span>
595
+ <a name="l00579"></a>00579 <span class="comment"> * SystemException will be thrown, with error code EAGAIN or</span>
596
+ <a name="l00580"></a>00580 <span class="comment"> * EWOULDBLOCK.</span>
597
+ <a name="l00581"></a>00581 <span class="comment"> *</span>
598
+ <a name="l00582"></a>00582 <span class="comment"> * @param msec The timeout, in milliseconds. If 0 is given,</span>
599
+ <a name="l00583"></a>00583 <span class="comment"> * there will be no timeout.</span>
600
+ <a name="l00584"></a>00584 <span class="comment"> * @throws SystemException Cannot set the timeout.</span>
601
+ <a name="l00585"></a>00585 <span class="comment"> */</span>
602
+ <a name="l00586"></a><a class="code" href="classPassenger_1_1MessageChannel.html#77c5d7c47f387cf43992ebeb14e3c6c7">00586</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1MessageChannel.html#77c5d7c47f387cf43992ebeb14e3c6c7" title="Set the timeout value for writing data to this channel.">setWriteTimeout</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> msec) {
603
+ <a name="l00587"></a>00587 <span class="comment">// People say that SO_RCVTIMEO/SO_SNDTIMEO are unreliable and</span>
604
+ <a name="l00588"></a>00588 <span class="comment">// not well-implemented on all platforms.</span>
605
+ <a name="l00589"></a>00589 <span class="comment">// http://www.developerweb.net/forum/archive/index.php/t-3439.html</span>
606
+ <a name="l00590"></a>00590 <span class="comment">// That's why we use APR's timeout facilities as well (see Hooks.cpp).</span>
607
+ <a name="l00591"></a>00591 <span class="keyword">struct </span>timeval tv;
608
+ <a name="l00592"></a>00592 <span class="keywordtype">int</span> ret;
609
+ <a name="l00593"></a>00593
610
+ <a name="l00594"></a>00594 tv.tv_sec = msec / 1000;
611
+ <a name="l00595"></a>00595 tv.tv_usec = msec % 1000 * 1000;
612
+ <a name="l00596"></a>00596 ret = syscalls::setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO,
613
+ <a name="l00597"></a>00597 &amp;tv, <span class="keyword">sizeof</span>(tv));
614
+ <a name="l00598"></a>00598 <span class="preprocessor"> #ifndef __SOLARIS__</span>
615
+ <a name="l00599"></a>00599 <span class="preprocessor"></span> <span class="comment">// SO_SNDTIMEO is unimplemented and returns an error on Solaris</span>
616
+ <a name="l00600"></a>00600 <span class="comment">// 9 and 10 SPARC. Seems to work okay without it.</span>
617
+ <a name="l00601"></a>00601 <span class="keywordflow">if</span> (ret == -1) {
618
+ <a name="l00602"></a>00602 <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 set read timeout for socket"</span>, errno);
619
+ <a name="l00603"></a>00603 }
620
+ <a name="l00604"></a>00604 <span class="preprocessor"> #endif</span>
621
+ <a name="l00605"></a>00605 <span class="preprocessor"></span> }
622
+ <a name="l00606"></a>00606 };
623
+ <a name="l00607"></a>00607
624
+ <a name="l00608"></a>00608 } <span class="comment">// namespace Passenger</span>
625
+ <a name="l00609"></a>00609
626
+ <a name="l00610"></a>00610 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_MESSAGE_CHANNEL_H_ */</span>
519
627
  </pre></div></div>
520
- <hr size="1"><address style="text-align: right;"><small>Generated on Mon Dec 15 15:27:24 2008 for Passenger by&nbsp;
628
+ <hr size="1"><address style="text-align: right;"><small>Generated on Fri Mar 13 19:24:32 2009 for Passenger by&nbsp;
521
629
  <a href="http://www.doxygen.org/index.html">
522
630
  <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
523
631
  </body>