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
@@ -30,7 +30,10 @@ class RequestHandler:
30
30
  try:
31
31
  env, input_stream = self.parse_request(client)
32
32
  if env:
33
- self.process_request(env, input_stream, client)
33
+ if env['REQUEST_METHOD'] == 'ping':
34
+ self.process_ping(env, input_stream, client)
35
+ else:
36
+ self.process_request(env, input_stream, client)
34
37
  else:
35
38
  done = True
36
39
  except KeyboardInterrupt:
@@ -147,6 +150,9 @@ class RequestHandler:
147
150
  finally:
148
151
  if hasattr(result, 'close'):
149
152
  result.close()
153
+
154
+ def process_ping(self, env, input_stream, output_stream):
155
+ output_stream.send("pong")
150
156
 
151
157
  def import_error_handler(environ, start_response):
152
158
  write = start_response('500 Import Error', [('Content-type', 'text/plain')])
@@ -1,4 +1,4 @@
1
- .TH "passenger-memory-stats" "1" "2.0" "Phusion Passenger" "Administration Commands"
1
+ .TH "passenger-memory-stats" "8" "2.0" "Phusion Passenger" "Administration Commands"
2
2
  .SH "NAME"
3
3
  .LP
4
4
  passenger\-memory\-stats \- reports a snapshot of the Apache and Phusion Passenger memory statistcs
@@ -19,7 +19,7 @@ $LOAD_PATH << "#{File.dirname(__FILE__)}/../lib"
19
19
  require 'passenger/html_template'
20
20
  require 'passenger/spawn_manager'
21
21
  require 'passenger/platform_info'
22
- include Passenger
22
+ include PhusionPassenger
23
23
 
24
24
  if !defined?(Mysql::Error)
25
25
  module Mysql
@@ -8,32 +8,11 @@
8
8
  using namespace Passenger;
9
9
 
10
10
  namespace tut {
11
- static bool firstRun = true;
12
- static unsigned int initialFileDescriptors;
13
-
14
- static unsigned int countOpenFileDescriptors() {
15
- int ret;
16
- unsigned int result = 0;
17
- for (long i = sysconf(_SC_OPEN_MAX) - 1; i >= 0; i--) {
18
- do {
19
- ret = dup2(i, i);
20
- } while (ret == -1 && errno == EINTR);
21
- if (ret != -1) {
22
- result++;
23
- }
24
- }
25
- return result;
26
- }
27
-
28
11
  struct ApplicationPoolServerTest {
29
12
  ApplicationPoolServerPtr server;
30
13
  ApplicationPoolPtr pool, pool2;
31
14
 
32
15
  ApplicationPoolServerTest() {
33
- if (firstRun) {
34
- initialFileDescriptors = countOpenFileDescriptors();
35
- firstRun = false;
36
- }
37
16
  server = ptr(new ApplicationPoolServer(
38
17
  "../ext/apache2/ApplicationPoolServerExecutable",
39
18
  "stub/spawn_server.rb"));
@@ -91,12 +70,5 @@ namespace tut {
91
70
  }
92
71
  }
93
72
  }
94
-
95
- TEST_METHOD(5) {
96
- // ApplicationPoolServer should not leak file descriptors after running all
97
- // of the above tests.
98
- server = ApplicationPoolServerPtr();
99
- ensure_equals(countOpenFileDescriptors(), initialFileDescriptors);
100
- }
101
73
  }
102
74
 
@@ -17,6 +17,10 @@ namespace tut {
17
17
  pool = server->connect();
18
18
  pool2 = server->connect();
19
19
  }
20
+
21
+ ApplicationPoolPtr newPoolConnection() {
22
+ return server->connect();
23
+ }
20
24
  };
21
25
 
22
26
  DEFINE_TEST_GROUP(ApplicationPoolServer_ApplicationPoolTest);
@@ -4,7 +4,9 @@
4
4
  #include <cstring>
5
5
  #include <cstdlib>
6
6
  #include <cerrno>
7
+ #include <sys/types.h>
7
8
  #include <signal.h>
9
+ #include <utime.h>
8
10
 
9
11
  /**
10
12
  * This file is used as a template to test the different ApplicationPool implementations.
@@ -12,6 +14,18 @@
12
14
  */
13
15
  #ifdef USE_TEMPLATE
14
16
 
17
+ struct TempFile {
18
+ const char *filename;
19
+
20
+ TempFile(const char *filename) {
21
+ this->filename = filename;
22
+ }
23
+
24
+ ~TempFile() {
25
+ unlink(filename);
26
+ }
27
+ };
28
+
15
29
  static string createRequestHeaders(const char *uri = "/foo/new") {
16
30
  string headers;
17
31
  #define ADD_HEADER(name, value) \
@@ -24,6 +38,7 @@
24
38
  ADD_HEADER("REQUEST_URI", uri);
25
39
  ADD_HEADER("REQUEST_METHOD", "GET");
26
40
  ADD_HEADER("REMOTE_ADDR", "localhost");
41
+ ADD_HEADER("PATH_INFO", uri);
27
42
  return headers;
28
43
  }
29
44
 
@@ -47,11 +62,17 @@
47
62
  }
48
63
 
49
64
  static Application::SessionPtr spawnRackApp(ApplicationPoolPtr pool, const char *appRoot) {
50
- return pool->get(appRoot, true, "nobody", "production", "smart", "rack");
65
+ PoolOptions options;
66
+ options.appRoot = appRoot;
67
+ options.appType = "rack";
68
+ return pool->get(options);
51
69
  }
52
70
 
53
71
  static Application::SessionPtr spawnWsgiApp(ApplicationPoolPtr pool, const char *appRoot) {
54
- return pool->get(appRoot, true, "nobody", "production", "smart", "wsgi");
72
+ PoolOptions options;
73
+ options.appRoot = appRoot;
74
+ options.appType = "wsgi";
75
+ return pool->get(options);
55
76
  }
56
77
 
57
78
  TEST_METHOD(1) {
@@ -69,7 +90,7 @@
69
90
  TEST_METHOD(2) {
70
91
  // Verify that the pool spawns a new app, and that
71
92
  // after the session is closed, the app is kept around.
72
- Application::SessionPtr session(pool->get("stub/railsapp"));
93
+ Application::SessionPtr session(spawnRackApp(pool, "stub/rack"));
73
94
  ensure_equals("Before the session was closed, the app was busy", pool->getActive(), 1u);
74
95
  ensure_equals("Before the session was closed, the app was in the pool", pool->getCount(), 1u);
75
96
  session.reset();
@@ -81,17 +102,17 @@
81
102
  // If we call get() with an application root, then we close the session,
82
103
  // and then we call get() again with the same application root,
83
104
  // then the pool should not have spawned more than 1 app in total.
84
- Application::SessionPtr session(pool->get("stub/railsapp"));
105
+ Application::SessionPtr session(spawnRackApp(pool, "stub/rack"));
85
106
  session.reset();
86
- session = pool->get("stub/railsapp");
107
+ session = spawnRackApp(pool, "stub/rack");
87
108
  ensure_equals(pool->getCount(), 1u);
88
109
  }
89
110
 
90
111
  TEST_METHOD(4) {
91
112
  // If we call get() with an application root, then we call get() again before closing
92
113
  // the session, then the pool should have spawned 2 apps in total.
93
- Application::SessionPtr session(pool->get("stub/railsapp"));
94
- Application::SessionPtr session2(pool2->get("stub/railsapp"));
114
+ Application::SessionPtr session(spawnRackApp(pool, "stub/rack"));
115
+ Application::SessionPtr session2(spawnRackApp(pool, "stub/rack"));
95
116
  ensure_equals(pool->getCount(), 2u);
96
117
  }
97
118
 
@@ -105,12 +126,12 @@
105
126
 
106
127
  session->sendHeaders(createRequestHeaders());
107
128
  string result(readAll(session->getStream()));
108
- ensure("Session 1 belongs to the correct app", result.find("hello world"));
129
+ ensure("Session 1 belongs to the correct app", result.find("hello world") != string::npos);
109
130
  session.reset();
110
131
 
111
132
  session2->sendHeaders(createRequestHeaders());
112
133
  result = readAll(session2->getStream());
113
- ensure("Session 2 belongs to the correct app", result.find("this is railsapp2"));
134
+ ensure("Session 2 belongs to the correct app", result.find("this is railsapp2") != string::npos);
114
135
  session2.reset();
115
136
  }
116
137
 
@@ -246,8 +267,8 @@
246
267
  }
247
268
 
248
269
  TEST_METHOD(12) {
249
- // If tmp/restart.txt is present, then the applications under app_root
250
- // should be restarted.
270
+ // If tmp/restart.txt didn't exist but has now been created,
271
+ // then the applications under app_root should be restarted.
251
272
  struct stat buf;
252
273
  Application::SessionPtr session1 = pool->get("stub/railsapp");
253
274
  Application::SessionPtr session2 = pool2->get("stub/railsapp");
@@ -260,62 +281,46 @@
260
281
  ensure_equals("No apps are active", pool->getActive(), 0u);
261
282
  ensure_equals("Both apps are killed, and a new one was spawned",
262
283
  pool->getCount(), 1u);
263
- ensure("Restart file has been deleted",
264
- stat("stub/railsapp/tmp/restart.txt", &buf) == -1
265
- && errno == ENOENT);
284
+ try {
285
+ ensure("Restart file still exists",
286
+ stat("stub/railsapp/tmp/restart.txt", &buf) == 0);
287
+ unlink("stub/railsapp/tmp/restart.txt");
288
+ } catch (...) {
289
+ unlink("stub/railsapp/tmp/restart.txt");
290
+ throw;
291
+ }
266
292
  }
267
293
 
268
294
  TEST_METHOD(13) {
269
- // If tmp/restart.txt is present, but cannot be deleted, then
270
- // the applications under app_root should still be restarted.
271
- // However, a subsequent get() should not result in a restart.
272
- pid_t old_pid, pid;
273
- struct stat buf;
274
- Application::SessionPtr session1 = pool->get("stub/railsapp");
275
- Application::SessionPtr session2 = pool2->get("stub/railsapp");
276
- session1.reset();
277
- session2.reset();
295
+ // If tmp/restart.txt was present, and its timestamp changed
296
+ // since the last check, then the applications under app_root
297
+ // should still be restarted. However, a subsequent get()
298
+ // should not result in a restart.
299
+ pid_t old_pid;
278
300
 
279
301
  system("mkdir -p stub/railsapp/tmp/restart.txt");
280
-
281
- old_pid = pool->get("stub/railsapp")->getPid();
282
302
  try {
283
- ensure("Restart file has not been deleted",
284
- stat("stub/railsapp/tmp/restart.txt", &buf) == 0);
285
- system("rmdir stub/railsapp/tmp/restart.txt");
303
+ Application::SessionPtr session = pool->get("stub/railsapp");
304
+ old_pid = session->getPid();
305
+ session.reset();
306
+
307
+ struct utimbuf buf;
308
+ buf.actime = time(NULL) - 10;
309
+ buf.modtime = time(NULL) - 10;
310
+ utime("stub/railsapp/tmp/restart.txt", &buf);
311
+
312
+ session = pool->get("stub/railsapp");
313
+ ensure("The app was restarted", session->getPid() != old_pid);
314
+ old_pid = session->getPid();
315
+ session.reset();
316
+
317
+ session = pool->get("stub/railsapp");
318
+ ensure_equals("The app was not restarted",
319
+ old_pid, session->getPid());
286
320
  } catch (...) {
287
321
  system("rmdir stub/railsapp/tmp/restart.txt");
288
322
  throw;
289
323
  }
290
-
291
- pid = pool->get("stub/railsapp")->getPid();
292
- ensure_equals("The app was not restarted", pid, old_pid);
293
- unlink("stub/railsapp/tmp/restart.txt");
294
- }
295
-
296
- TEST_METHOD(14) {
297
- // If tmp/restart.txt is present, but cannot be deleted, then
298
- // the applications under app_root should still be restarted.
299
- // A subsequent get() should only restart if we've changed
300
- // restart.txt's mtime.
301
- pid_t old_pid;
302
- Application::SessionPtr session1 = pool->get("stub/railsapp");
303
- Application::SessionPtr session2 = pool2->get("stub/railsapp");
304
- session1.reset();
305
- session2.reset();
306
-
307
- setenv("nextRestartTxtDeletionShouldFail", "1", 1);
308
- system("touch stub/railsapp/tmp/restart.txt");
309
- old_pid = pool->get("stub/railsapp")->getPid();
310
- ensure_equals(pool->getActive(), 0u);
311
- ensure_equals(pool->getCount(), 1u);
312
-
313
- sleep(1); // Allow the next mtime to be different.
314
- system("touch stub/railsapp/tmp/restart.txt");
315
- ensure("The app is restarted, and the last app instance was not reused",
316
- pool2->get("stub/railsapp")->getPid() != old_pid);
317
-
318
- unlink("stub/railsapp/tmp/restart.txt");
319
324
  }
320
325
 
321
326
  TEST_METHOD(15) {
@@ -325,17 +330,24 @@
325
330
  Application::SessionPtr session = pool->get("stub/railsapp");
326
331
  session->sendHeaders(createRequestHeaders("/bar"));
327
332
  string result = readAll(session->getStream());
328
- ensure(result.find("bar 1!"));
333
+ ensure(result.find("bar 1!") != string::npos);
329
334
  session.reset();
330
-
335
+
331
336
  system("cp -f stub/railsapp/app/controllers/bar_controller_2.rb "
332
337
  "stub/railsapp/app/controllers/bar_controller.rb");
333
338
  system("touch stub/railsapp/tmp/restart.txt");
334
- session = pool->get("stub/railsapp");
335
- session->sendHeaders(createRequestHeaders("/bar"));
336
- result = readAll(session->getStream());
337
- ensure("App code has been reloaded", result.find("bar 2!"));
339
+ try {
340
+ session = pool->get("stub/railsapp");
341
+ session->sendHeaders(createRequestHeaders("/bar"));
342
+ result = readAll(session->getStream());
343
+ ensure("App code has been reloaded", result.find("bar 2!") != string::npos);
344
+ } catch (...) {
345
+ unlink("stub/railsapp/app/controllers/bar_controller.rb");
346
+ unlink("touch stub/railsapp/tmp/restart.txt");
347
+ throw;
348
+ }
338
349
  unlink("stub/railsapp/app/controllers/bar_controller.rb");
350
+ unlink("touch stub/railsapp/tmp/restart.txt");
339
351
  }
340
352
 
341
353
  TEST_METHOD(16) {
@@ -351,10 +363,55 @@
351
363
  }
352
364
 
353
365
  TEST_METHOD(17) {
354
- // MaxPerApp must be respected.
366
+ // MaxPerApp is respected.
355
367
  pool->setMax(3);
356
368
  pool->setMaxPerApp(1);
357
- // TODO: how do we test this?
369
+
370
+ // We connect to stub/rack while it already has an instance with
371
+ // 1 request in its queue. Assert that the pool doesn't spawn
372
+ // another instance.
373
+ Application::SessionPtr session1 = spawnRackApp(pool, "stub/rack");
374
+ Application::SessionPtr session2 = spawnRackApp(pool2, "stub/rack");
375
+ ensure_equals(pool->getCount(), 1u);
376
+
377
+ // We connect to stub/wsgi. Assert that the pool spawns a new
378
+ // instance for this app.
379
+ ApplicationPoolPtr pool3(newPoolConnection());
380
+ Application::SessionPtr session3 = spawnWsgiApp(pool3, "stub/wsgi");
381
+ ensure_equals(pool->getCount(), 2u);
382
+ }
383
+
384
+ TEST_METHOD(18) {
385
+ // Application instance is shutdown after 'maxRequests' requests.
386
+ PoolOptions options("stub/railsapp");
387
+ int reader;
388
+ pid_t originalPid;
389
+ Application::SessionPtr session;
390
+
391
+ options.maxRequests = 4;
392
+ pool->setMax(1);
393
+ session = pool->get(options);
394
+ originalPid = session->getPid();
395
+ session.reset();
396
+
397
+ for (unsigned int i = 0; i < 4; i++) {
398
+ session = pool->get(options);
399
+ session->sendHeaders(createRequestHeaders());
400
+ session->shutdownWriter();
401
+ reader = session->getStream();
402
+ readAll(reader);
403
+ // Must explicitly call reset() here because we
404
+ // want to close the session right now.
405
+ session.reset();
406
+ // In case of ApplicationPoolServer, we sleep here
407
+ // for a little while to force a context switch to
408
+ // the server, so that the session close event may
409
+ // be processed.
410
+ usleep(100000);
411
+ }
412
+
413
+ session = pool->get(options);
414
+ ensure(session->getPid() != originalPid);
358
415
  }
359
416
 
360
417
  struct SpawnRackAppFunction {
@@ -362,7 +419,11 @@
362
419
  bool *done;
363
420
 
364
421
  void operator()() {
365
- spawnRackApp(pool, "stub/rack");
422
+ PoolOptions options;
423
+ options.appRoot = "stub/rack";
424
+ options.appType = "rack";
425
+ options.useGlobalQueue = true;
426
+ pool->get(options);
366
427
  *done = true;
367
428
  }
368
429
  };
@@ -371,9 +432,13 @@
371
432
  // If global queueing mode is enabled, then get() waits until
372
433
  // there's at least one idle backend process for this application
373
434
  // domain.
374
- pool->setUseGlobalQueue(true);
375
435
  pool->setMax(1);
376
- Application::SessionPtr session = spawnRackApp(pool, "stub/rack");
436
+
437
+ PoolOptions options;
438
+ options.appRoot = "stub/rack";
439
+ options.appType = "rack";
440
+ options.useGlobalQueue = true;
441
+ Application::SessionPtr session = pool->get(options);
377
442
 
378
443
  bool done = false;
379
444
  SpawnRackAppFunction func;
@@ -391,6 +456,179 @@
391
456
  thr.join();
392
457
  }
393
458
 
394
- // TODO: test maxIdleTime == 0
459
+ TEST_METHOD(20) {
460
+ // If tmp/always_restart.txt is present, then the application under app_root
461
+ // should be always restarted.
462
+ try {
463
+ struct stat buf;
464
+ Application::SessionPtr session1 = pool->get("stub/railsapp");
465
+ Application::SessionPtr session2 = pool2->get("stub/railsapp");
466
+ session1.reset();
467
+ session2.reset();
468
+
469
+ system("touch stub/railsapp/tmp/always_restart.txt");
470
+ pool->get("stub/railsapp");
471
+
472
+ ensure_equals("No apps are active", pool->getActive(), 0u);
473
+ ensure_equals("Both apps are killed, and a new one was spawned",
474
+ pool->getCount(), 1u);
475
+ ensure("always_restart file has not been deleted",
476
+ stat("stub/railsapp/tmp/always_restart.txt", &buf) == 0);
477
+ unlink("stub/railsapp/tmp/always_restart.txt");
478
+ } catch (...) {
479
+ unlink("stub/railsapp/tmp/always_restart.txt");
480
+ throw;
481
+ }
482
+ }
483
+
484
+ TEST_METHOD(21) {
485
+ // If tmp/always_restart.txt is present and is a directory,
486
+ // then the application under app_root
487
+ // should be always restarted.
488
+ try {
489
+ struct stat buf;
490
+ Application::SessionPtr session1 = pool->get("stub/railsapp");
491
+ Application::SessionPtr session2 = pool2->get("stub/railsapp");
492
+ session1.reset();
493
+ session2.reset();
494
+
495
+ system("mkdir stub/railsapp/tmp/always_restart.txt");
496
+ pool->get("stub/railsapp");
497
+
498
+ ensure_equals("No apps are active", pool->getActive(), 0u);
499
+ ensure_equals("Both apps are killed, and a new one was spawned",
500
+ pool->getCount(), 1u);
501
+ ensure("always_restart file has not been deleted",
502
+ stat("stub/railsapp/tmp/always_restart.txt", &buf) == 0);
503
+ system("rmdir stub/railsapp/tmp/always_restart.txt");
504
+ } catch (...) {
505
+ system("rmdir stub/railsapp/tmp/always_restart.txt");
506
+ throw;
507
+ }
508
+ }
509
+
510
+ TEST_METHOD(22) {
511
+ // Test whether tmp/always_restart.txt really results in code reload.
512
+ try {
513
+ system("cp -f stub/railsapp/app/controllers/bar_controller_1.rb "
514
+ "stub/railsapp/app/controllers/bar_controller.rb");
515
+ Application::SessionPtr session = pool->get("stub/railsapp");
516
+ session->sendHeaders(createRequestHeaders("/bar"));
517
+ string result = readAll(session->getStream());
518
+ ensure(result.find("bar 1!") != string::npos);
519
+ session.reset();
520
+
521
+ system("cp -f stub/railsapp/app/controllers/bar_controller_2.rb "
522
+ "stub/railsapp/app/controllers/bar_controller.rb");
523
+ system("touch stub/railsapp/tmp/always_restart.txt");
524
+ session = pool->get("stub/railsapp");
525
+ session->sendHeaders(createRequestHeaders("/bar"));
526
+ result = readAll(session->getStream());
527
+ ensure("App code has been reloaded (1)", result.find("bar 2!") != string::npos);
528
+ session.reset();
529
+
530
+ system("cp -f stub/railsapp/app/controllers/bar_controller_1.rb "
531
+ "stub/railsapp/app/controllers/bar_controller.rb");
532
+ session = pool->get("stub/railsapp");
533
+ session->sendHeaders(createRequestHeaders("/bar"));
534
+ result = readAll(session->getStream());
535
+ ensure("App code has been reloaded (2)", result.find("bar 1!") != string::npos);
536
+ session.reset();
537
+
538
+ unlink("stub/railsapp/app/controllers/bar_controller.rb");
539
+ unlink("stub/railsapp/tmp/always_restart.txt");
540
+ } catch (...) {
541
+ unlink("stub/railsapp/app/controllers/bar_controller.rb");
542
+ unlink("stub/railsapp/tmp/always_restart.txt");
543
+ throw;
544
+ }
545
+ }
546
+
547
+ TEST_METHOD(23) {
548
+ // If tmp/restart.txt and tmp/always_restart.txt are present,
549
+ // the application under app_root should still be restarted and
550
+ // both files must be kept
551
+ try {
552
+ pid_t old_pid, pid;
553
+ struct stat buf;
554
+ Application::SessionPtr session1 = pool->get("stub/railsapp");
555
+ Application::SessionPtr session2 = pool2->get("stub/railsapp");
556
+ session1.reset();
557
+ session2.reset();
558
+
559
+ system("touch stub/railsapp/tmp/restart.txt");
560
+ system("touch stub/railsapp/tmp/always_restart.txt");
561
+
562
+ old_pid = pool->get("stub/railsapp")->getPid();
563
+ ensure("always_restart file has not been deleted",
564
+ stat("stub/railsapp/tmp/always_restart.txt", &buf) == 0);
565
+
566
+ ensure("Restart file has not been deleted",
567
+ stat("stub/railsapp/tmp/restart.txt", &buf) == 0);
568
+
569
+ pid = pool->get("stub/railsapp")->getPid();
570
+ ensure("The app was restarted", pid != old_pid);
395
571
 
572
+ unlink("stub/railsapp/tmp/restart.txt");
573
+ unlink("stub/railsapp/tmp/always_restart.txt");
574
+ } catch (...) {
575
+ unlink("stub/railsapp/tmp/restart.txt");
576
+ unlink("stub/railsapp/tmp/always_restart.txt");
577
+ throw;
578
+ }
579
+ }
580
+
581
+ TEST_METHOD(24) {
582
+ // It should look for restart.txt in the directory given by
583
+ // the restartDir option, if available.
584
+ struct stat buf;
585
+ char path[1024];
586
+ PoolOptions options("stub/rack");
587
+ options.appType = "rack";
588
+ options.restartDir = string(getcwd(path, sizeof(path))) + "/stub/rack";
589
+
590
+ Application::SessionPtr session1 = pool->get(options);
591
+ Application::SessionPtr session2 = pool2->get(options);
592
+ session1.reset();
593
+ session2.reset();
594
+
595
+ TempFile tempfile("stub/rack/restart.txt");
596
+ system("touch stub/rack/restart.txt");
597
+
598
+ pool->get(options);
599
+
600
+ ensure_equals("No apps are active", pool->getActive(), 0u);
601
+ ensure_equals("Both apps are killed, and a new one was spawned",
602
+ pool->getCount(), 1u);
603
+ ensure("Restart file still exists",
604
+ stat("stub/rack/restart.txt", &buf) == 0);
605
+ }
606
+
607
+ TEST_METHOD(25) {
608
+ // restartDir may also be a directory relative to the
609
+ // application root.
610
+ struct stat buf;
611
+ PoolOptions options("stub/rack");
612
+ options.appType = "rack";
613
+ options.restartDir = "public";
614
+
615
+ Application::SessionPtr session1 = pool->get(options);
616
+ Application::SessionPtr session2 = pool2->get(options);
617
+ session1.reset();
618
+ session2.reset();
619
+
620
+ TempFile tempfile("stub/rack/public/restart.txt");
621
+ system("touch stub/rack/public/restart.txt");
622
+
623
+ pool->get(options);
624
+
625
+ ensure_equals("No apps are active", pool->getActive(), 0u);
626
+ ensure_equals("Both apps are killed, and a new one was spawned",
627
+ pool->getCount(), 1u);
628
+ ensure("Restart file still exists",
629
+ stat("stub/rack/public/restart.txt", &buf) == 0);
630
+ }
631
+
632
+ /*************************************/
633
+
396
634
  #endif /* USE_TEMPLATE */