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.
- data/DEVELOPERS.TXT +10 -4
- data/LICENSE +1 -1
- data/NEWS +0 -0
- data/Rakefile +183 -117
- data/benchmark/dispatcher.rb +5 -9
- data/bin/passenger-install-apache2-module +52 -18
- data/bin/passenger-memory-stats +67 -13
- data/bin/passenger-spawn-server +8 -4
- data/bin/passenger-status +21 -46
- data/bin/passenger-stress-test +5 -5
- data/debian/postinst +1 -1
- data/doc/ApplicationPool algorithm.txt +180 -128
- data/doc/Architectural overview.html +1 -778
- data/doc/Security of user switching support.html +1 -643
- data/doc/Users guide Apache.html +3127 -0
- data/doc/Users guide Nginx.html +1458 -0
- data/doc/Users guide.html +1404 -467
- data/doc/Users guide.txt +843 -105
- data/doc/cxxapi/ApplicationPoolServer_8h-source.html +751 -641
- data/doc/cxxapi/ApplicationPool_8h-source.html +168 -171
- data/doc/cxxapi/Application_8h-source.html +494 -394
- data/doc/cxxapi/Bucket_8h-source.html +21 -15
- data/doc/cxxapi/CachedFileStat_8h-source.html +191 -0
- data/doc/cxxapi/Configuration_8h-source.html +311 -149
- data/doc/cxxapi/DirectoryMapper_8h-source.html +309 -0
- data/doc/cxxapi/DummySpawnManager_8h-source.html +3 -4
- data/doc/cxxapi/Exceptions_8h-source.html +182 -165
- data/doc/cxxapi/FileChecker_8h-source.html +130 -0
- data/doc/cxxapi/Hooks_8h-source.html +2 -3
- data/doc/cxxapi/Logging_8h-source.html +92 -89
- data/doc/cxxapi/MessageChannel_8h-source.html +585 -477
- data/doc/cxxapi/PoolOptions_8h-source.html +305 -0
- data/doc/cxxapi/SpawnManager_8h-source.html +515 -540
- data/doc/cxxapi/StandardApplicationPool_8h-source.html +779 -679
- data/doc/cxxapi/SystemTime_8h-source.html +104 -0
- data/doc/cxxapi/Utils_8h-source.html +331 -227
- data/doc/cxxapi/annotated.html +6 -7
- data/doc/cxxapi/classClient-members.html +1 -2
- data/doc/cxxapi/classClient.html +1 -2
- data/doc/cxxapi/classHooks-members.html +5 -2
- data/doc/cxxapi/classHooks.html +112 -2
- data/doc/cxxapi/classPassenger_1_1Application-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1Application.html +8 -9
- data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +42 -81
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +3 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +3 -2
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +74 -3
- data/doc/cxxapi/classPassenger_1_1BusyException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1BusyException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +38 -0
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +256 -0
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +2 -3
- data/doc/cxxapi/{classPassenger_1_1Thread-members.html → classPassenger_1_1FileChecker-members.html} +4 -5
- data/doc/cxxapi/classPassenger_1_1FileChecker.html +121 -0
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1FileSystemException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1IOException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +5 -2
- data/doc/cxxapi/classPassenger_1_1MessageChannel.html +155 -5
- data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption-members.html → classPassenger_1_1RuntimeException-members.html} +2 -3
- data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption.html → classPassenger_1_1RuntimeException.html} +10 -8
- data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1SpawnException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1SpawnManager.html +15 -56
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +5 -4
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +20 -81
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1SystemException-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1SystemException.html +9 -10
- data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/{classboost_1_1this__thread_1_1disable__syscall__interruption-members.html → classPassenger_1_1SystemTime-members.html} +5 -3
- data/doc/cxxapi/classPassenger_1_1SystemTime.html +86 -0
- data/doc/cxxapi/classPassenger_1_1TempFile-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1TempFile.html +17 -9
- data/doc/cxxapi/definitions_8h-source.html +1 -2
- data/doc/cxxapi/files.html +6 -3
- data/doc/cxxapi/functions.html +98 -35
- data/doc/cxxapi/functions_func.html +60 -32
- data/doc/cxxapi/functions_type.html +1 -2
- data/doc/cxxapi/functions_vars.html +27 -2
- data/doc/cxxapi/graph_legend.html +1 -2
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Configuration.html +3 -4
- data/doc/cxxapi/group__Configuration.png +0 -0
- data/doc/cxxapi/group__Core.html +3 -4
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Exceptions.html +4 -2
- data/doc/cxxapi/group__Hooks.html +1 -6
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/group__Support.html +259 -36
- data/doc/cxxapi/hierarchy.html +6 -7
- data/doc/cxxapi/inherit__graph__0.map +1 -1
- data/doc/cxxapi/inherit__graph__0.md5 +1 -1
- data/doc/cxxapi/inherit__graph__0.png +0 -0
- data/doc/cxxapi/inherit__graph__1.map +1 -1
- data/doc/cxxapi/inherit__graph__1.md5 +1 -1
- data/doc/cxxapi/inherit__graph__1.png +0 -0
- data/doc/cxxapi/inherit__graph__10.map +1 -1
- data/doc/cxxapi/inherit__graph__10.md5 +1 -1
- data/doc/cxxapi/inherit__graph__10.png +0 -0
- data/doc/cxxapi/inherit__graph__11.map +1 -1
- data/doc/cxxapi/inherit__graph__11.md5 +1 -1
- data/doc/cxxapi/inherit__graph__11.png +0 -0
- data/doc/cxxapi/inherit__graph__12.map +2 -1
- data/doc/cxxapi/inherit__graph__12.md5 +1 -1
- data/doc/cxxapi/inherit__graph__12.png +0 -0
- data/doc/cxxapi/inherit__graph__13.map +1 -1
- data/doc/cxxapi/inherit__graph__13.md5 +1 -1
- data/doc/cxxapi/inherit__graph__13.png +0 -0
- data/doc/cxxapi/inherit__graph__14.map +1 -2
- data/doc/cxxapi/inherit__graph__14.md5 +1 -1
- data/doc/cxxapi/inherit__graph__14.png +0 -0
- data/doc/cxxapi/inherit__graph__15.map +1 -1
- data/doc/cxxapi/inherit__graph__15.md5 +1 -1
- data/doc/cxxapi/inherit__graph__15.png +0 -0
- data/doc/cxxapi/inherit__graph__16.map +1 -1
- data/doc/cxxapi/inherit__graph__16.md5 +1 -1
- data/doc/cxxapi/inherit__graph__16.png +0 -0
- data/doc/cxxapi/inherit__graph__17.png +0 -0
- data/doc/cxxapi/inherit__graph__18.png +0 -0
- data/doc/cxxapi/inherit__graph__19.png +0 -0
- data/doc/cxxapi/inherit__graph__2.map +1 -1
- data/doc/cxxapi/inherit__graph__2.md5 +1 -1
- data/doc/cxxapi/inherit__graph__2.png +0 -0
- data/doc/cxxapi/inherit__graph__20.map +1 -1
- data/doc/cxxapi/inherit__graph__20.md5 +1 -1
- data/doc/cxxapi/inherit__graph__20.png +0 -0
- data/doc/cxxapi/inherit__graph__21.map +1 -1
- data/doc/cxxapi/inherit__graph__21.md5 +1 -1
- data/doc/cxxapi/inherit__graph__21.png +0 -0
- data/doc/cxxapi/inherit__graph__3.map +1 -1
- data/doc/cxxapi/inherit__graph__3.md5 +1 -1
- data/doc/cxxapi/inherit__graph__3.png +0 -0
- data/doc/cxxapi/inherit__graph__4.map +1 -1
- data/doc/cxxapi/inherit__graph__4.md5 +1 -1
- data/doc/cxxapi/inherit__graph__4.png +0 -0
- data/doc/cxxapi/inherit__graph__5.map +2 -1
- data/doc/cxxapi/inherit__graph__5.md5 +1 -1
- data/doc/cxxapi/inherit__graph__5.png +0 -0
- data/doc/cxxapi/inherit__graph__6.map +1 -1
- data/doc/cxxapi/inherit__graph__6.md5 +1 -1
- data/doc/cxxapi/inherit__graph__6.png +0 -0
- data/doc/cxxapi/inherit__graph__7.map +1 -1
- data/doc/cxxapi/inherit__graph__7.md5 +1 -1
- data/doc/cxxapi/inherit__graph__7.png +0 -0
- data/doc/cxxapi/inherit__graph__8.map +1 -1
- data/doc/cxxapi/inherit__graph__8.md5 +1 -1
- data/doc/cxxapi/inherit__graph__8.png +0 -0
- data/doc/cxxapi/inherit__graph__9.map +1 -2
- data/doc/cxxapi/inherit__graph__9.md5 +1 -1
- data/doc/cxxapi/inherit__graph__9.png +0 -0
- data/doc/cxxapi/inherits.html +30 -31
- data/doc/cxxapi/main.html +1 -2
- data/doc/cxxapi/modules.html +1 -2
- data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -2
- data/doc/cxxapi/structPassenger_1_1AnythingToString.html +2 -3
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -2
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +2 -3
- data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +49 -0
- data/doc/cxxapi/structPassenger_1_1PoolOptions.html +404 -0
- data/doc/cxxapi/tree.html +18 -20
- data/doc/images/conservative_spawning.png +0 -0
- data/doc/images/conservative_spawning.svg +248 -0
- data/doc/images/smart-lv2.png +0 -0
- data/doc/images/smart-lv2.svg +320 -0
- data/doc/rdoc/classes/ConditionVariable.html +68 -34
- data/doc/rdoc/classes/Exception.html +16 -16
- data/doc/rdoc/classes/GC.html +9 -9
- data/doc/rdoc/classes/IO.html +36 -17
- data/doc/rdoc/classes/PhusionPassenger.html +183 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +511 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer.html +285 -242
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerAlreadyStarted.html +3 -3
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerError.html +3 -3
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerNotStarted.html +3 -3
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/UnknownMessage.html +3 -3
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +247 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AppInitError.html +36 -19
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/Application.html +81 -96
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/ConsoleTextTemplate.html +18 -18
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/FrameworkInitError.html +20 -18
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/HTMLTemplate.html +18 -18
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/InitializationError.html +9 -9
- data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/MessageChannel.html +93 -92
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/NativeSupport.html +55 -25
- data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +185 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +182 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +424 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +444 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +154 -0
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +408 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/UnknownError.html +13 -13
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +687 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/VersionNotFound.html +8 -8
- data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
- data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
- data/doc/rdoc/classes/PlatformInfo.html +663 -159
- data/doc/rdoc/classes/RakeExtensions.html +4 -4
- data/doc/rdoc/classes/Signal.html +134 -0
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +15 -10
- data/doc/rdoc/files/README.html +5 -7
- data/doc/rdoc/files/ext/{passenger → phusion_passenger}/native_support_c.html +2 -2
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_request_handler_rb.html +7 -9
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +120 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_server_rb.html +7 -10
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +99 -0
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +92 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/application_rb.html +6 -8
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/console_text_template_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/constants_rb.html +4 -5
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/dependencies_rb.html +6 -8
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +116 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/exceptions_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/html_template_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/message_channel_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/platform_info_rb.html +6 -7
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +123 -0
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +117 -0
- data/doc/rdoc/files/lib/{passenger/utils_rb.html → phusion_passenger/railz/application_spawner_rb.html} +24 -17
- data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +139 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +118 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/simple_benchmarking_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/spawn_manager_rb.html +40 -24
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +169 -0
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +120 -0
- data/doc/rdoc/files/lib/rake/extensions_rb.html +3 -4
- data/doc/rdoc/fr_class_index.html +37 -19
- data/doc/rdoc/fr_file_index.html +25 -14
- data/doc/rdoc/fr_method_index.html +145 -74
- data/ext/apache2/Application.h +145 -44
- data/ext/apache2/ApplicationPool.h +27 -29
- data/ext/apache2/ApplicationPoolServer.h +183 -72
- data/ext/apache2/ApplicationPoolServerExecutable.cpp +249 -42
- data/ext/apache2/Bucket.cpp +61 -9
- data/ext/apache2/Bucket.h +15 -8
- data/ext/apache2/CachedFileStat.cpp +114 -0
- data/ext/apache2/CachedFileStat.h +169 -0
- data/ext/apache2/Configuration.cpp +213 -22
- data/ext/apache2/Configuration.h +176 -13
- data/ext/apache2/DirectoryMapper.h +287 -0
- data/ext/apache2/Exceptions.h +30 -12
- data/ext/apache2/FileChecker.h +108 -0
- data/ext/apache2/Hooks.cpp +709 -493
- data/ext/apache2/LICENSE-CNRI.TXT +15 -0
- data/ext/apache2/Logging.h +26 -22
- data/ext/apache2/MessageChannel.h +124 -15
- data/ext/apache2/PoolOptions.h +283 -0
- data/ext/apache2/SpawnManager.h +75 -99
- data/ext/apache2/StandardApplicationPool.h +296 -195
- data/ext/apache2/SystemTime.cpp +28 -0
- data/ext/apache2/SystemTime.h +82 -0
- data/ext/apache2/Utils.cpp +172 -18
- data/ext/apache2/Utils.h +124 -19
- data/ext/boost/cstdint.hpp +4 -2
- data/ext/boost/current_function.hpp +67 -0
- data/ext/boost/detail/sp_counted_base.hpp +4 -4
- data/ext/boost/thread/exceptions.hpp +2 -1
- data/ext/boost/thread/pthread/thread.hpp +11 -3
- data/ext/boost/thread/pthread/thread_data.hpp +2 -1
- data/ext/oxt/backtrace.cpp +172 -0
- data/ext/oxt/backtrace.hpp +135 -0
- data/ext/oxt/detail/backtrace_disabled.hpp +39 -0
- data/ext/oxt/detail/backtrace_enabled.hpp +155 -0
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +82 -0
- data/ext/oxt/detail/spin_lock_portable.hpp +38 -0
- data/ext/oxt/detail/spin_lock_pthreads.hpp +97 -0
- data/ext/oxt/detail/tracable_exception_disabled.hpp +46 -0
- data/ext/oxt/detail/tracable_exception_enabled.hpp +48 -0
- data/ext/oxt/macros.hpp +58 -0
- data/ext/oxt/spin_lock.hpp +55 -0
- data/ext/{apache2/System.cpp → oxt/system_calls.cpp} +87 -52
- data/ext/oxt/system_calls.hpp +234 -0
- data/ext/oxt/thread.cpp +32 -0
- data/ext/oxt/thread.hpp +223 -0
- data/ext/oxt/tracable_exception.cpp +87 -0
- data/ext/oxt/tracable_exception.hpp +35 -0
- data/{lib/passenger/constants.rb → ext/phusion_passenger/extconf.rb} +14 -9
- data/ext/{passenger → phusion_passenger}/native_support.c +33 -6
- data/lib/{passenger → phusion_passenger}/abstract_request_handler.rb +209 -93
- data/lib/{passenger → phusion_passenger}/abstract_server.rb +23 -8
- data/lib/phusion_passenger/abstract_server_collection.rb +301 -0
- data/lib/phusion_passenger/admin_tools.rb +25 -0
- data/lib/phusion_passenger/admin_tools/control_process.rb +107 -0
- data/lib/{passenger → phusion_passenger}/application.rb +13 -16
- data/lib/{passenger → phusion_passenger}/console_text_template.rb +2 -2
- data/{ext/passenger/extconf.rb → lib/phusion_passenger/constants.rb} +5 -5
- data/lib/{passenger → phusion_passenger}/dependencies.rb +38 -32
- data/lib/phusion_passenger/events.rb +45 -0
- data/lib/{passenger → phusion_passenger}/exceptions.rb +12 -5
- data/lib/{passenger → phusion_passenger}/html_template.rb +2 -2
- data/lib/{passenger → phusion_passenger}/message_channel.rb +3 -2
- data/lib/phusion_passenger/platform_info.rb +500 -0
- data/lib/{passenger → phusion_passenger}/rack/application_spawner.rb +29 -22
- data/lib/{passenger → phusion_passenger}/rack/request_handler.rb +14 -9
- data/lib/{passenger → phusion_passenger}/railz/application_spawner.rb +94 -74
- data/lib/{passenger → phusion_passenger}/railz/cgi_fixed.rb +2 -2
- data/lib/{passenger → phusion_passenger}/railz/framework_spawner.rb +86 -98
- data/lib/{passenger → phusion_passenger}/railz/request_handler.rb +6 -6
- data/lib/{passenger → phusion_passenger}/simple_benchmarking.rb +0 -0
- data/lib/{passenger → phusion_passenger}/spawn_manager.rb +136 -128
- data/lib/{passenger → phusion_passenger}/templates/apache2_config_snippets.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
- data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +38 -0
- data/lib/{passenger → phusion_passenger}/templates/app_init_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/database_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/deployment_example.txt.erb +1 -1
- data/lib/{passenger → phusion_passenger}/templates/error_layout.css +0 -0
- data/lib/{passenger → phusion_passenger}/templates/error_layout.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/framework_init_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/general_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/invalid_app_root.html.erb +1 -1
- data/lib/{passenger → phusion_passenger}/templates/load_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/no_write_permission_to_passenger_root.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/run_installer_as_root.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/version_not_found.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/welcome.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/utils.rb +210 -44
- data/lib/{passenger → phusion_passenger}/wsgi/application_spawner.rb +18 -15
- data/lib/{passenger → phusion_passenger}/wsgi/request_handler.py +7 -1
- data/man/passenger-memory-stats.8 +1 -1
- data/misc/render_error_pages.rb +1 -1
- data/test/ApplicationPoolServerTest.cpp +0 -28
- data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +4 -0
- data/test/ApplicationPoolTest.cpp +307 -69
- data/test/CachedFileStatTest.cpp +262 -0
- data/test/FileCheckerTest.cpp +79 -0
- data/test/MessageChannelTest.cpp +3 -3
- data/test/PoolOptionsTest.cpp +37 -0
- data/test/SpawnManagerTest.cpp +4 -4
- data/test/StandardApplicationPoolTest.cpp +4 -0
- data/test/SystemTimeTest.cpp +37 -0
- data/test/UtilsTest.cpp +137 -0
- data/test/integration_tests.rb +270 -23
- data/test/oxt/backtrace_test.cpp +128 -0
- data/test/oxt/oxt_test_main.cpp +25 -0
- data/test/oxt/syscall_interruption_test.cpp +50 -0
- data/test/ruby/abstract_request_handler_spec.rb +83 -0
- data/test/ruby/abstract_server_collection_spec.rb +246 -0
- data/test/ruby/application_spec.rb +3 -3
- data/test/ruby/message_channel_spec.rb +2 -2
- data/test/ruby/rack/application_spawner_spec.rb +3 -5
- data/test/ruby/rails/application_spawner_spec.rb +54 -15
- data/test/ruby/rails/framework_spawner_spec.rb +6 -8
- data/test/ruby/rails/minimal_spawner_spec.rb +29 -0
- data/test/ruby/rails/spawner_error_handling_spec.rb +1 -1
- data/test/ruby/rails/spawner_privilege_lowering_spec.rb +3 -3
- data/test/ruby/spawn_manager_spec.rb +23 -12
- data/test/ruby/utils_spec.rb +36 -2
- data/test/ruby/wsgi/application_spawner_spec.rb +47 -0
- data/test/stub/apache2/httpd.conf.erb +3 -5
- data/test/stub/message_channel.rb +2 -2
- data/test/stub/message_channel_2.rb +2 -2
- data/test/stub/message_channel_3.rb +3 -3
- data/test/stub/minimal-railsapp/README +0 -0
- data/test/stub/minimal-railsapp/config/application.rb +0 -0
- data/test/stub/minimal-railsapp/config/environment.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -0
- data/test/stub/rails_apps/foobar/app/controllers/foo_controller.rb +8 -0
- data/test/stub/rails_apps/foobar/config/environments/development.rb +1 -2
- data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +21 -1
- data/test/stub/rails_apps/mycook/sites/some.site/public/uploads.html +26 -0
- data/test/stub/rails_apps/mycook/sites/some.site/public/welcome/cached.html +26 -0
- data/test/stub/railsapp/app/controllers/application.rb +0 -0
- data/test/stub/railsapp/app/controllers/bar_controller_1.rb +0 -0
- data/test/stub/railsapp/app/controllers/bar_controller_2.rb +1 -1
- data/test/stub/railsapp/app/controllers/foo_controller.rb +4 -0
- data/test/stub/railsapp/app/helpers/application_helper.rb +0 -0
- data/test/stub/railsapp/config/boot.rb +0 -0
- data/test/stub/railsapp/config/database.yml +0 -0
- data/test/stub/railsapp/config/environment.rb +0 -0
- data/test/stub/railsapp/config/environments/development.rb +0 -0
- data/test/stub/railsapp/config/environments/production.rb +0 -0
- data/test/stub/railsapp/config/initializers/inflections.rb +0 -0
- data/test/stub/railsapp/config/initializers/mime_types.rb +0 -0
- data/test/stub/railsapp/config/routes.rb +0 -0
- data/test/stub/railsapp/public/useless.txt +0 -0
- data/test/stub/spawn_server.rb +3 -4
- data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
- data/test/support/apache2_controller.rb +57 -7
- data/test/support/tut.h +15 -0
- data/vendor/README +12 -0
- data/vendor/README_FOR_PACKAGERS +1 -0
- data/vendor/rack-0.9.1/AUTHORS +8 -0
- data/vendor/rack-0.9.1/COPYING +18 -0
- data/vendor/rack-0.9.1/ChangeLog +1423 -0
- data/vendor/rack-0.9.1/KNOWN-ISSUES +18 -0
- data/vendor/rack-0.9.1/README +306 -0
- data/vendor/rack-0.9.1/Rakefile +188 -0
- data/vendor/rack-0.9.1/SPEC +129 -0
- data/vendor/rack-0.9.1/lib/rack.rb +86 -0
- data/vendor/rack-0.9.1/lib/rack/adapter/camping.rb +22 -0
- data/vendor/rack-0.9.1/lib/rack/auth/abstract/handler.rb +28 -0
- data/vendor/rack-0.9.1/lib/rack/auth/abstract/request.rb +37 -0
- data/vendor/rack-0.9.1/lib/rack/auth/basic.rb +58 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/md5.rb +124 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/nonce.rb +51 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/params.rb +55 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/request.rb +40 -0
- data/vendor/rack-0.9.1/lib/rack/auth/openid.rb +438 -0
- data/vendor/rack-0.9.1/lib/rack/builder.rb +67 -0
- data/vendor/rack-0.9.1/lib/rack/cascade.rb +36 -0
- data/vendor/rack-0.9.1/lib/rack/commonlogger.rb +61 -0
- data/vendor/rack-0.9.1/lib/rack/conditionalget.rb +43 -0
- data/vendor/rack-0.9.1/lib/rack/content_length.rb +25 -0
- data/vendor/rack-0.9.1/lib/rack/deflater.rb +87 -0
- data/vendor/rack-0.9.1/lib/rack/directory.rb +150 -0
- data/vendor/rack-0.9.1/lib/rack/file.rb +85 -0
- data/vendor/rack-0.9.1/lib/rack/handler.rb +48 -0
- data/vendor/rack-0.9.1/lib/rack/handler/cgi.rb +57 -0
- data/vendor/rack-0.9.1/lib/rack/handler/evented_mongrel.rb +8 -0
- data/vendor/rack-0.9.1/lib/rack/handler/fastcgi.rb +86 -0
- data/vendor/rack-0.9.1/lib/rack/handler/lsws.rb +52 -0
- data/vendor/rack-0.9.1/lib/rack/handler/mongrel.rb +82 -0
- data/vendor/rack-0.9.1/lib/rack/handler/scgi.rb +57 -0
- data/vendor/rack-0.9.1/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
- data/vendor/rack-0.9.1/lib/rack/handler/thin.rb +15 -0
- data/vendor/rack-0.9.1/lib/rack/handler/webrick.rb +61 -0
- data/vendor/rack-0.9.1/lib/rack/head.rb +19 -0
- data/vendor/rack-0.9.1/lib/rack/lint.rb +465 -0
- data/vendor/rack-0.9.1/lib/rack/lobster.rb +65 -0
- data/vendor/rack-0.9.1/lib/rack/methodoverride.rb +27 -0
- data/vendor/rack-0.9.1/lib/rack/mime.rb +204 -0
- data/vendor/rack-0.9.1/lib/rack/mock.rb +160 -0
- data/vendor/rack-0.9.1/lib/rack/recursive.rb +57 -0
- data/vendor/rack-0.9.1/lib/rack/reloader.rb +64 -0
- data/vendor/rack-0.9.1/lib/rack/request.rb +218 -0
- data/vendor/rack-0.9.1/lib/rack/response.rb +171 -0
- data/vendor/rack-0.9.1/lib/rack/session/abstract/id.rb +153 -0
- data/vendor/rack-0.9.1/lib/rack/session/cookie.rb +89 -0
- data/vendor/rack-0.9.1/lib/rack/session/memcache.rb +97 -0
- data/vendor/rack-0.9.1/lib/rack/session/pool.rb +73 -0
- data/vendor/rack-0.9.1/lib/rack/showexceptions.rb +348 -0
- data/vendor/rack-0.9.1/lib/rack/showstatus.rb +106 -0
- data/vendor/rack-0.9.1/lib/rack/static.rb +38 -0
- data/vendor/rack-0.9.1/lib/rack/urlmap.rb +48 -0
- data/vendor/rack-0.9.1/lib/rack/utils.rb +347 -0
- metadata +1197 -1055
- data/doc/cxxapi/System_8h-source.html +0 -251
- data/doc/cxxapi/classDirectoryMapper-members.html +0 -38
- data/doc/cxxapi/classDirectoryMapper.html +0 -203
- data/doc/cxxapi/classPassenger_1_1Thread.html +0 -100
- data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption.html +0 -46
- data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption-members.html +0 -33
- data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption.html +0 -44
- data/doc/cxxapi/namespacePassenger.html +0 -208
- data/doc/cxxapi/namespacePassenger_1_1InterruptableCalls.html +0 -43
- data/doc/cxxapi/namespacemembers.html +0 -70
- data/doc/cxxapi/namespacemembers_func.html +0 -66
- data/doc/cxxapi/namespacemembers_type.html +0 -46
- data/doc/cxxapi/namespaces.html +0 -35
- data/doc/rdoc/classes/Passenger.html +0 -136
- data/doc/rdoc/classes/Passenger/AbstractRequestHandler.html +0 -402
- data/doc/rdoc/classes/Passenger/SpawnManager.html +0 -379
- data/doc/rdoc/classes/Passenger/Utils.html +0 -578
- data/ext/apache2/System.h +0 -228
- data/lib/passenger/platform_info.rb +0 -302
- data/lib/passenger/templates/app_exited_during_initialization.html.erb +0 -19
- data/test/stub/apache2/httpd.conf +0 -75
- data/test/stub/rails_apps/foobar/config/environments/test.rb +0 -22
- data/test/stub/rails_apps/mycook/config/environments/test.rb +0 -22
- data/test/stub/railsapp/config/environments/test.rb +0 -22
- data/test/stub/railsapp2/config/environments/test.rb +0 -22
@@ -18,9 +18,9 @@
|
|
18
18
|
|
19
19
|
require 'socket'
|
20
20
|
require 'fcntl'
|
21
|
-
require '
|
22
|
-
require '
|
23
|
-
module
|
21
|
+
require 'phusion_passenger/message_channel'
|
22
|
+
require 'phusion_passenger/utils'
|
23
|
+
module PhusionPassenger
|
24
24
|
|
25
25
|
# The request handler is the layer which connects Apache with the underlying application's
|
26
26
|
# request dispatcher (i.e. either Rails's Dispatcher class or Rack).
|
@@ -39,30 +39,20 @@ module Passenger
|
|
39
39
|
# administrator maintenance overhead. These decisions are documented
|
40
40
|
# in this section.
|
41
41
|
#
|
42
|
-
# === Abstract namespace Unix sockets
|
43
|
-
#
|
44
|
-
# AbstractRequestHandler listens on a Unix socket for incoming requests. If possible,
|
45
|
-
# AbstractRequestHandler will try to create a Unix socket on the _abstract namespace_,
|
46
|
-
# instead of on the filesystem. If the RoR application crashes (segfault),
|
47
|
-
# or if it gets killed by SIGKILL, or if the system loses power, then there
|
48
|
-
# will be no stale socket files left on the filesystem.
|
49
|
-
# Unfortunately, abstract namespace Unix sockets are only supported by Linux.
|
50
|
-
# On systems that do not support abstract namespace Unix sockets,
|
51
|
-
# AbstractRequestHandler will automatically fallback to using regular Unix socket files.
|
52
|
-
#
|
53
|
-
# It is possible to force AbstractRequestHandler to use regular Unix socket files by
|
54
|
-
# setting the environment variable PASSENGER_NO_ABSTRACT_NAMESPACE_SOCKETS
|
55
|
-
# to 1.
|
56
|
-
#
|
57
42
|
# === Owner pipes
|
58
43
|
#
|
59
44
|
# Because only the web server communicates directly with a request handler,
|
60
45
|
# we want the request handler to exit if the web server has also exited.
|
61
46
|
# This is implemented by using a so-called _owner pipe_. The writable part
|
62
|
-
# of the pipe will be
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
47
|
+
# of the pipe will be passed to the web server* via a Unix socket, and the web
|
48
|
+
# server will own that part of the pipe, while AbstractRequestHandler owns
|
49
|
+
# the readable part of the pipe. AbstractRequestHandler will continuously
|
50
|
+
# check whether the other side of the pipe has been closed. If so, then it
|
51
|
+
# knows that the web server has exited, and so the request handler will exit
|
52
|
+
# as well. This works even if the web server gets killed by SIGKILL.
|
53
|
+
#
|
54
|
+
# * It might also be passed to the ApplicationPoolServerExecutable, if the web
|
55
|
+
# server's using ApplicationPoolServer instead of StandardApplicationPool.
|
66
56
|
#
|
67
57
|
#
|
68
58
|
# == Request format
|
@@ -94,7 +84,7 @@ class AbstractRequestHandler
|
|
94
84
|
HARD_TERMINATION_SIGNAL = "SIGTERM"
|
95
85
|
# Signal which will cause the Rails application to exit as soon as it's done processing a request.
|
96
86
|
SOFT_TERMINATION_SIGNAL = "SIGUSR1"
|
97
|
-
BACKLOG_SIZE =
|
87
|
+
BACKLOG_SIZE = 100
|
98
88
|
MAX_HEADER_SIZE = 128 * 1024
|
99
89
|
|
100
90
|
# String constants which exist to relieve Ruby's garbage collector.
|
@@ -104,72 +94,117 @@ class AbstractRequestHandler
|
|
104
94
|
CONTENT_LENGTH = 'CONTENT_LENGTH' # :nodoc:
|
105
95
|
HTTP_CONTENT_LENGTH = 'HTTP_CONTENT_LENGTH' # :nodoc:
|
106
96
|
X_POWERED_BY = 'X-Powered-By' # :nodoc:
|
97
|
+
REQUEST_METHOD = 'REQUEST_METHOD' # :nodoc:
|
98
|
+
PING = 'ping' # :nodoc:
|
107
99
|
|
108
100
|
# The name of the socket on which the request handler accepts
|
109
|
-
# new connections.
|
110
|
-
#
|
101
|
+
# new connections. At this moment, this value is always the filename
|
102
|
+
# of a Unix domain socket.
|
111
103
|
#
|
112
|
-
#
|
113
|
-
# then the name does _not_ contain a leading null byte.
|
114
|
-
#
|
115
|
-
# See also using_abstract_namespace?
|
104
|
+
# See also #socket_type.
|
116
105
|
attr_reader :socket_name
|
117
|
-
|
106
|
+
|
107
|
+
# The type of socket that #socket_name refers to. At the moment, the
|
108
|
+
# value is always 'unix', which indicates a Unix domain socket.
|
109
|
+
attr_reader :socket_type
|
110
|
+
|
111
|
+
# Specifies the maximum allowed memory usage, in MB. If after having processed
|
112
|
+
# a request AbstractRequestHandler detects that memory usage has risen above
|
113
|
+
# this limit, then it will gracefully exit (that is, exit after having processed
|
114
|
+
# all pending requests).
|
115
|
+
#
|
116
|
+
# A value of 0 (the default) indicates that there's no limit.
|
117
|
+
attr_accessor :memory_limit
|
118
|
+
|
119
|
+
# The number of times the main loop has iterated so far. Mostly useful
|
120
|
+
# for unit test assertions.
|
121
|
+
attr_reader :iterations
|
122
|
+
|
123
|
+
# Number of requests processed so far. This includes requests that raised
|
124
|
+
# exceptions.
|
125
|
+
attr_reader :processed_requests
|
126
|
+
|
118
127
|
# Create a new RequestHandler with the given owner pipe.
|
119
128
|
# +owner_pipe+ must be the readable part of a pipe IO object.
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
126
|
-
if !@using_abstract_namespace
|
129
|
+
#
|
130
|
+
# Additionally, the following options may be given:
|
131
|
+
# - memory_limit: Used to set the +memory_limit+ attribute.
|
132
|
+
def initialize(owner_pipe, options = {})
|
133
|
+
if should_use_unix_sockets?
|
127
134
|
create_unix_socket_on_filesystem
|
135
|
+
else
|
136
|
+
create_tcp_socket
|
128
137
|
end
|
129
|
-
@socket.
|
138
|
+
@socket.close_on_exec!
|
130
139
|
@owner_pipe = owner_pipe
|
131
140
|
@previous_signal_handlers = {}
|
141
|
+
@main_loop_thread_lock = Mutex.new
|
142
|
+
@main_loop_thread_cond = ConditionVariable.new
|
143
|
+
@memory_limit = options["memory_limit"] || 0
|
144
|
+
@iterations = 0
|
145
|
+
@processed_requests = 0
|
132
146
|
end
|
133
147
|
|
134
148
|
# Clean up temporary stuff created by the request handler.
|
135
|
-
#
|
149
|
+
#
|
150
|
+
# If the main loop was started by #main_loop, then this method may only
|
151
|
+
# be called after the main loop has exited.
|
152
|
+
#
|
153
|
+
# If the main loop was started by #start_main_loop_thread, then this method
|
154
|
+
# may be called at any time, and it will stop the main loop thread.
|
136
155
|
def cleanup
|
156
|
+
if @main_loop_thread
|
157
|
+
@main_loop_thread.raise(Interrupt.new("Cleaning up"))
|
158
|
+
@main_loop_thread.join
|
159
|
+
end
|
137
160
|
@socket.close rescue nil
|
138
161
|
@owner_pipe.close rescue nil
|
139
|
-
|
140
|
-
File.unlink(@socket_name) rescue nil
|
141
|
-
end
|
162
|
+
File.unlink(@socket_name) rescue nil
|
142
163
|
end
|
143
164
|
|
144
|
-
#
|
145
|
-
def
|
146
|
-
return @
|
165
|
+
# Check whether the main loop's currently running.
|
166
|
+
def main_loop_running?
|
167
|
+
return @main_loop_running
|
147
168
|
end
|
148
169
|
|
149
170
|
# Enter the request handler's main loop.
|
150
171
|
def main_loop
|
151
172
|
reset_signal_handlers
|
152
173
|
begin
|
153
|
-
|
154
|
-
|
174
|
+
@graceful_termination_pipe = IO.pipe
|
175
|
+
@graceful_termination_pipe[0].close_on_exec!
|
176
|
+
@graceful_termination_pipe[1].close_on_exec!
|
177
|
+
|
178
|
+
@main_loop_thread_lock.synchronize do
|
179
|
+
@main_loop_running = true
|
180
|
+
@main_loop_thread_cond.broadcast
|
181
|
+
end
|
182
|
+
|
183
|
+
install_useful_signal_handlers
|
184
|
+
|
185
|
+
while true
|
186
|
+
@iterations += 1
|
155
187
|
client = accept_connection
|
156
188
|
if client.nil?
|
157
189
|
break
|
158
190
|
end
|
159
|
-
trap SOFT_TERMINATION_SIGNAL do
|
160
|
-
done = true
|
161
|
-
end
|
162
191
|
begin
|
163
192
|
headers, input = parse_request(client)
|
164
193
|
if headers
|
165
|
-
|
194
|
+
if headers[REQUEST_METHOD] == PING
|
195
|
+
process_ping(headers, input, client)
|
196
|
+
else
|
197
|
+
process_request(headers, input, client)
|
198
|
+
end
|
166
199
|
end
|
167
200
|
rescue IOError, SocketError, SystemCallError => e
|
168
201
|
print_exception("Passenger RequestHandler", e)
|
169
202
|
ensure
|
203
|
+
# 'input' is the same as 'client' so we don't
|
204
|
+
# need to close that.
|
170
205
|
client.close rescue nil
|
171
206
|
end
|
172
|
-
|
207
|
+
@processed_requests += 1
|
173
208
|
end
|
174
209
|
rescue EOFError
|
175
210
|
# Exit main loop.
|
@@ -181,47 +216,54 @@ class AbstractRequestHandler
|
|
181
216
|
raise
|
182
217
|
end
|
183
218
|
ensure
|
219
|
+
@graceful_termination_pipe[0].close rescue nil
|
220
|
+
@graceful_termination_pipe[1].close rescue nil
|
184
221
|
revert_signal_handlers
|
222
|
+
@main_loop_thread_lock.synchronize do
|
223
|
+
@main_loop_running = false
|
224
|
+
@main_loop_thread_cond.broadcast
|
225
|
+
end
|
185
226
|
end
|
186
227
|
end
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
# of the problem. The system supports base64-encoded
|
197
|
-
# names for abstract namespace unix sockets just fine.
|
198
|
-
@socket_name = generate_random_id(:hex)
|
199
|
-
@socket_name = @socket_name.slice(0, NativeSupport::UNIX_PATH_MAX - 2)
|
200
|
-
fd = NativeSupport.create_unix_socket("\x00#{socket_name}", BACKLOG_SIZE)
|
201
|
-
@socket = IO.new(fd)
|
202
|
-
@socket.instance_eval do
|
203
|
-
def accept
|
204
|
-
fd = NativeSupport.accept(fileno)
|
205
|
-
return IO.new(fd)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
return true
|
209
|
-
rescue Errno::EADDRINUSE
|
210
|
-
# Do nothing, try again with another name.
|
211
|
-
rescue Errno::ENOENT
|
212
|
-
# Abstract namespace sockets not supported on this system.
|
213
|
-
return false
|
228
|
+
|
229
|
+
# Start the main loop in a new thread. This thread will be stopped by #cleanup.
|
230
|
+
def start_main_loop_thread
|
231
|
+
@main_loop_thread = Thread.new do
|
232
|
+
main_loop
|
233
|
+
end
|
234
|
+
@main_loop_thread_lock.synchronize do
|
235
|
+
while !@main_loop_running
|
236
|
+
@main_loop_thread_cond.wait(@main_loop_thread_lock)
|
214
237
|
end
|
215
238
|
end
|
216
239
|
end
|
240
|
+
|
241
|
+
private
|
242
|
+
include Utils
|
217
243
|
|
244
|
+
def should_use_unix_sockets?
|
245
|
+
# There seems to be a bug in MacOS X w.r.t. Unix sockets.
|
246
|
+
# When the Unix socket subsystem is under high stress, a
|
247
|
+
# recv()/read() on a Unix socket can return 0 even when EOF is
|
248
|
+
# not reached. We work around this by using TCP sockets on
|
249
|
+
# MacOS X.
|
250
|
+
return RUBY_PLATFORM !~ /darwin/
|
251
|
+
end
|
252
|
+
|
218
253
|
def create_unix_socket_on_filesystem
|
219
254
|
done = false
|
220
255
|
while !done
|
221
256
|
begin
|
222
|
-
|
223
|
-
|
257
|
+
if defined?(NativeSupport)
|
258
|
+
unix_path_max = NativeSupport::UNIX_PATH_MAX
|
259
|
+
else
|
260
|
+
unix_path_max = 100
|
261
|
+
end
|
262
|
+
@socket_name = "#{passenger_tmpdir}/passenger_backend.#{generate_random_id(:base64)}"
|
263
|
+
@socket_name = @socket_name.slice(0, unix_path_max - 1)
|
224
264
|
@socket = UNIXServer.new(@socket_name)
|
265
|
+
@socket.listen(BACKLOG_SIZE)
|
266
|
+
@socket_type = "unix"
|
225
267
|
File.chmod(0600, @socket_name)
|
226
268
|
done = true
|
227
269
|
rescue Errno::EADDRINUSE
|
@@ -229,12 +271,21 @@ private
|
|
229
271
|
end
|
230
272
|
end
|
231
273
|
end
|
274
|
+
|
275
|
+
def create_tcp_socket
|
276
|
+
# We use "127.0.0.1" as address in order to force
|
277
|
+
# TCPv4 instead of TCPv6.
|
278
|
+
@socket = TCPServer.new('127.0.0.1', 0)
|
279
|
+
@socket.listen(BACKLOG_SIZE)
|
280
|
+
@socket_name = "127.0.0.1:#{@socket.addr[1]}"
|
281
|
+
@socket_type = "tcp"
|
282
|
+
end
|
232
283
|
|
233
284
|
# Reset signal handlers to their default handler, and install some
|
234
285
|
# special handlers for a few signals. The previous signal handlers
|
235
286
|
# will be put back by calling revert_signal_handlers.
|
236
287
|
def reset_signal_handlers
|
237
|
-
Signal.
|
288
|
+
Signal.list_trappable.each_key do |signal|
|
238
289
|
begin
|
239
290
|
prev_handler = trap(signal, DEFAULT)
|
240
291
|
if prev_handler != DEFAULT
|
@@ -245,9 +296,45 @@ private
|
|
245
296
|
end
|
246
297
|
end
|
247
298
|
trap('HUP', IGNORE)
|
299
|
+
end
|
300
|
+
|
301
|
+
def install_useful_signal_handlers
|
302
|
+
trappable_signals = Signal.list_trappable
|
303
|
+
|
304
|
+
trap(SOFT_TERMINATION_SIGNAL) do
|
305
|
+
@graceful_termination_pipe[1].close rescue nil
|
306
|
+
end if trappable_signals.has_key?(SOFT_TERMINATION_SIGNAL.sub(/^SIG/, ''))
|
307
|
+
|
248
308
|
trap('ABRT') do
|
249
309
|
raise SignalException, "SIGABRT"
|
250
|
-
end
|
310
|
+
end if trappable_signals.has_key?('ABRT')
|
311
|
+
|
312
|
+
trap('QUIT') do
|
313
|
+
if Kernel.respond_to?(:caller_for_all_threads)
|
314
|
+
output = "========== Process #{Process.pid}: backtrace dump ==========\n"
|
315
|
+
caller_for_all_threads.each_pair do |thread, stack|
|
316
|
+
output << ("-" * 60) << "\n"
|
317
|
+
output << "# Thread: #{thread.inspect}, "
|
318
|
+
if thread == Thread.main
|
319
|
+
output << "[main thread], "
|
320
|
+
else
|
321
|
+
output << "[current thread], "
|
322
|
+
end
|
323
|
+
output << "alive = #{thread.alive?}\n"
|
324
|
+
output << ("-" * 60) << "\n"
|
325
|
+
output << " " << stack.join("\n ")
|
326
|
+
output << "\n\n"
|
327
|
+
end
|
328
|
+
else
|
329
|
+
output = "========== Process #{Process.pid}: backtrace dump ==========\n"
|
330
|
+
output << ("-" * 60) << "\n"
|
331
|
+
output << "# Current thread: #{Thread.current.inspect}\n"
|
332
|
+
output << ("-" * 60) << "\n"
|
333
|
+
output << " " << caller.join("\n ")
|
334
|
+
end
|
335
|
+
STDERR.puts(output)
|
336
|
+
STDERR.flush
|
337
|
+
end if trappable_signals.has_key?('QUIT')
|
251
338
|
end
|
252
339
|
|
253
340
|
def revert_signal_handlers
|
@@ -257,10 +344,38 @@ private
|
|
257
344
|
end
|
258
345
|
|
259
346
|
def accept_connection
|
260
|
-
ios = select([@socket, @owner_pipe
|
347
|
+
ios = select([@socket, @owner_pipe, @graceful_termination_pipe[0]]).first
|
261
348
|
if ios.include?(@socket)
|
262
349
|
client = @socket.accept
|
263
|
-
client.
|
350
|
+
client.close_on_exec!
|
351
|
+
|
352
|
+
# Some people report that sometimes their Ruby (MRI/REE)
|
353
|
+
# processes get stuck with 100% CPU usage. Upon further
|
354
|
+
# inspection with strace, it turns out that these Ruby
|
355
|
+
# processes are continuously calling lseek() on a socket,
|
356
|
+
# which of course returns ESPIPE as error. gdb reveals
|
357
|
+
# lseek() is called by fwrite(), which in turn is called
|
358
|
+
# by rb_fwrite(). The affected socket is the
|
359
|
+
# AbstractRequestHandler client socket.
|
360
|
+
#
|
361
|
+
# I inspected the MRI source code and didn't find
|
362
|
+
# anything that would explain this behavior. This makes
|
363
|
+
# me think that it's a glibc bug, but that's very
|
364
|
+
# unlikely.
|
365
|
+
#
|
366
|
+
# The rb_fwrite() implementation takes an entirely
|
367
|
+
# different code path if I set 'sync' to true: it will
|
368
|
+
# skip fwrite() and use write() instead. So here we set
|
369
|
+
# 'sync' to true in the hope that this will work around
|
370
|
+
# the problem.
|
371
|
+
client.sync = true
|
372
|
+
|
373
|
+
# We monkeypatch the 'sync=' method to a no-op so that
|
374
|
+
# sync mode can't be disabled.
|
375
|
+
client.instance_eval do
|
376
|
+
def client.sync=(value)
|
377
|
+
end
|
378
|
+
end
|
264
379
|
|
265
380
|
# The real input stream is not seekable (calling _seek_
|
266
381
|
# or _rewind_ on it will raise an exception). But some
|
@@ -274,8 +389,10 @@ private
|
|
274
389
|
|
275
390
|
return client
|
276
391
|
else
|
277
|
-
# The other end of the pipe has been closed
|
278
|
-
#
|
392
|
+
# The other end of the owner pipe has been closed, or the
|
393
|
+
# graceful termination pipe has been closed. This is our
|
394
|
+
# call to gracefully terminate (after having processed all
|
395
|
+
# incoming requests).
|
279
396
|
return nil
|
280
397
|
end
|
281
398
|
end
|
@@ -301,6 +418,10 @@ private
|
|
301
418
|
print_exception("Passenger RequestHandler", e)
|
302
419
|
end
|
303
420
|
|
421
|
+
def process_ping(env, input, output)
|
422
|
+
output.write("pong")
|
423
|
+
end
|
424
|
+
|
304
425
|
# Generate a long, cryptographically secure random ID string, which
|
305
426
|
# is also a valid filename.
|
306
427
|
def generate_random_id(method)
|
@@ -318,11 +439,6 @@ private
|
|
318
439
|
return data
|
319
440
|
end
|
320
441
|
|
321
|
-
def abstract_namespace_sockets_allowed?
|
322
|
-
return !ENV['PASSENGER_NO_ABSTRACT_NAMESPACE_SOCKETS'] ||
|
323
|
-
ENV['PASSENGER_NO_ABSTRACT_NAMESPACE_SOCKETS'].empty?
|
324
|
-
end
|
325
|
-
|
326
442
|
def self.determine_passenger_version
|
327
443
|
rakefile = "#{File.dirname(__FILE__)}/../../Rakefile"
|
328
444
|
if File.exist?(rakefile)
|
@@ -347,4 +463,4 @@ public
|
|
347
463
|
PASSENGER_HEADER = determine_passenger_header
|
348
464
|
end
|
349
465
|
|
350
|
-
end # module
|
466
|
+
end # module PhusionPassenger
|
@@ -19,10 +19,9 @@
|
|
19
19
|
require 'socket'
|
20
20
|
require 'set'
|
21
21
|
require 'timeout'
|
22
|
-
require '
|
23
|
-
require '
|
24
|
-
|
25
|
-
module Passenger
|
22
|
+
require 'phusion_passenger/message_channel'
|
23
|
+
require 'phusion_passenger/utils'
|
24
|
+
module PhusionPassenger
|
26
25
|
|
27
26
|
# An abstract base class for a server, with the following properties:
|
28
27
|
#
|
@@ -43,7 +42,7 @@ module Passenger
|
|
43
42
|
#
|
44
43
|
# Here's an example on using AbstractServer:
|
45
44
|
#
|
46
|
-
# class MyServer <
|
45
|
+
# class MyServer < PhusionPassenger::AbstractServer
|
47
46
|
# def initialize
|
48
47
|
# super()
|
49
48
|
# define_message_handler(:hello, :handle_hello)
|
@@ -88,11 +87,25 @@ class AbstractServer
|
|
88
87
|
class ServerError < StandardError
|
89
88
|
end
|
90
89
|
|
90
|
+
# The last time when this AbstractServer had processed a message.
|
91
|
+
attr_accessor :last_activity_time
|
92
|
+
|
93
|
+
# The maximum time that this AbstractServer may be idle. Used by
|
94
|
+
# AbstractServerCollection to determine when this object should
|
95
|
+
# be cleaned up. nil or 0 indicate that this object should never
|
96
|
+
# be idle cleaned.
|
97
|
+
attr_accessor :max_idle_time
|
98
|
+
|
99
|
+
# Used by AbstractServerCollection to remember when this AbstractServer
|
100
|
+
# should be idle cleaned.
|
101
|
+
attr_accessor :next_cleaning_time
|
102
|
+
|
91
103
|
def initialize
|
92
104
|
@done = false
|
93
105
|
@message_handlers = {}
|
94
106
|
@signal_handlers = {}
|
95
107
|
@orig_signal_handlers = {}
|
108
|
+
@last_activity_time = Time.now
|
96
109
|
end
|
97
110
|
|
98
111
|
# Start the server. This method does not block since the server runs
|
@@ -109,7 +122,8 @@ class AbstractServer
|
|
109
122
|
|
110
123
|
@parent_socket, @child_socket = UNIXSocket.pair
|
111
124
|
before_fork
|
112
|
-
@pid = fork
|
125
|
+
@pid = fork
|
126
|
+
if @pid.nil?
|
113
127
|
begin
|
114
128
|
STDOUT.sync = true
|
115
129
|
STDERR.sync = true
|
@@ -278,7 +292,7 @@ private
|
|
278
292
|
# Reset all signal handlers to default. This is called in the child process,
|
279
293
|
# before entering the main loop.
|
280
294
|
def reset_signal_handlers
|
281
|
-
Signal.
|
295
|
+
Signal.list_trappable.each_key do |signal|
|
282
296
|
begin
|
283
297
|
@orig_signal_handlers[signal] = trap(signal, 'DEFAULT')
|
284
298
|
rescue ArgumentError
|
@@ -311,6 +325,7 @@ private
|
|
311
325
|
while !@done
|
312
326
|
begin
|
313
327
|
name, *args = channel.read
|
328
|
+
@last_activity_time = Time.now
|
314
329
|
if name.nil?
|
315
330
|
@done = true
|
316
331
|
elsif @message_handlers.has_key?(name)
|
@@ -331,4 +346,4 @@ private
|
|
331
346
|
end
|
332
347
|
end
|
333
348
|
|
334
|
-
end # module
|
349
|
+
end # module PhusionPassenger
|