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
data/ext/apache2/Application.h
CHANGED
@@ -22,11 +22,15 @@
|
|
22
22
|
|
23
23
|
#include <boost/shared_ptr.hpp>
|
24
24
|
#include <boost/function.hpp>
|
25
|
+
#include <oxt/system_calls.hpp>
|
26
|
+
#include <oxt/backtrace.hpp>
|
25
27
|
#include <string>
|
28
|
+
#include <vector>
|
26
29
|
|
27
30
|
#include <sys/types.h>
|
28
31
|
#include <sys/socket.h>
|
29
32
|
#include <sys/un.h>
|
33
|
+
#include <netdb.h>
|
30
34
|
#include <unistd.h>
|
31
35
|
#include <errno.h>
|
32
36
|
#include <ctime>
|
@@ -35,6 +39,7 @@
|
|
35
39
|
#include "MessageChannel.h"
|
36
40
|
#include "Exceptions.h"
|
37
41
|
#include "Logging.h"
|
42
|
+
#include "Utils.h"
|
38
43
|
|
39
44
|
namespace Passenger {
|
40
45
|
|
@@ -105,6 +110,7 @@ public:
|
|
105
110
|
* @throws boost::thread_interrupted
|
106
111
|
*/
|
107
112
|
virtual void sendHeaders(const char *headers, unsigned int size) {
|
113
|
+
TRACE_POINT();
|
108
114
|
int stream = getStream();
|
109
115
|
if (stream == -1) {
|
110
116
|
throw IOException("Cannot write headers to the request handler "
|
@@ -112,9 +118,10 @@ public:
|
|
112
118
|
}
|
113
119
|
try {
|
114
120
|
MessageChannel(stream).writeScalar(headers, size);
|
115
|
-
} catch (
|
116
|
-
|
117
|
-
"to the request handler"
|
121
|
+
} catch (SystemException &e) {
|
122
|
+
e.setBriefMessage("An error occured while writing headers "
|
123
|
+
"to the request handler");
|
124
|
+
throw;
|
118
125
|
}
|
119
126
|
}
|
120
127
|
|
@@ -144,6 +151,7 @@ public:
|
|
144
151
|
* @throws boost::thread_interrupted
|
145
152
|
*/
|
146
153
|
virtual void sendBodyBlock(const char *block, unsigned int size) {
|
154
|
+
TRACE_POINT();
|
147
155
|
int stream = getStream();
|
148
156
|
if (stream == -1) {
|
149
157
|
throw IOException("Cannot write request body block to the "
|
@@ -152,9 +160,10 @@ public:
|
|
152
160
|
}
|
153
161
|
try {
|
154
162
|
MessageChannel(stream).writeRaw(block, size);
|
155
|
-
} catch (
|
156
|
-
|
157
|
-
"request body to the request handler"
|
163
|
+
} catch (SystemException &e) {
|
164
|
+
e.setBriefMessage("An error occured while sending the "
|
165
|
+
"request body to the request handler");
|
166
|
+
throw;
|
158
167
|
}
|
159
168
|
}
|
160
169
|
|
@@ -167,6 +176,28 @@ public:
|
|
167
176
|
*/
|
168
177
|
virtual int getStream() const = 0;
|
169
178
|
|
179
|
+
/**
|
180
|
+
* Set the timeout value for reading data from the I/O stream.
|
181
|
+
* If no data can be read within the timeout period, then the
|
182
|
+
* read call will fail with error EAGAIN or EWOULDBLOCK.
|
183
|
+
*
|
184
|
+
* @param msec The timeout, in milliseconds. If 0 is given,
|
185
|
+
* there will be no timeout.
|
186
|
+
* @throws SystemException Cannot set the timeout.
|
187
|
+
*/
|
188
|
+
virtual void setReaderTimeout(unsigned int msec) = 0;
|
189
|
+
|
190
|
+
/**
|
191
|
+
* Set the timeout value for writing data from the I/O stream.
|
192
|
+
* If no data can be written within the timeout period, then the
|
193
|
+
* write call will fail with error EAGAIN or EWOULDBLOCK.
|
194
|
+
*
|
195
|
+
* @param msec The timeout, in milliseconds. If 0 is given,
|
196
|
+
* there will be no timeout.
|
197
|
+
* @throws SystemException Cannot set the timeout.
|
198
|
+
*/
|
199
|
+
virtual void setWriterTimeout(unsigned int msec) = 0;
|
200
|
+
|
170
201
|
/**
|
171
202
|
* Indicate that we don't want to read data anymore from the I/O stream.
|
172
203
|
* Calling this method after closeStream() is called will have no effect.
|
@@ -225,6 +256,7 @@ private:
|
|
225
256
|
}
|
226
257
|
|
227
258
|
virtual ~StandardSession() {
|
259
|
+
TRACE_POINT();
|
228
260
|
closeStream();
|
229
261
|
closeCallback();
|
230
262
|
}
|
@@ -233,9 +265,18 @@ private:
|
|
233
265
|
return fd;
|
234
266
|
}
|
235
267
|
|
268
|
+
virtual void setReaderTimeout(unsigned int msec) {
|
269
|
+
MessageChannel(fd).setReadTimeout(msec);
|
270
|
+
}
|
271
|
+
|
272
|
+
virtual void setWriterTimeout(unsigned int msec) {
|
273
|
+
MessageChannel(fd).setWriteTimeout(msec);
|
274
|
+
}
|
275
|
+
|
236
276
|
virtual void shutdownReader() {
|
277
|
+
TRACE_POINT();
|
237
278
|
if (fd != -1) {
|
238
|
-
int ret =
|
279
|
+
int ret = syscalls::shutdown(fd, SHUT_RD);
|
239
280
|
if (ret == -1) {
|
240
281
|
throw SystemException("Cannot shutdown the writer stream",
|
241
282
|
errno);
|
@@ -244,8 +285,9 @@ private:
|
|
244
285
|
}
|
245
286
|
|
246
287
|
virtual void shutdownWriter() {
|
288
|
+
TRACE_POINT();
|
247
289
|
if (fd != -1) {
|
248
|
-
int ret =
|
290
|
+
int ret = syscalls::shutdown(fd, SHUT_WR);
|
249
291
|
if (ret == -1) {
|
250
292
|
throw SystemException("Cannot shutdown the writer stream",
|
251
293
|
errno);
|
@@ -254,8 +296,9 @@ private:
|
|
254
296
|
}
|
255
297
|
|
256
298
|
virtual void closeStream() {
|
299
|
+
TRACE_POINT();
|
257
300
|
if (fd != -1) {
|
258
|
-
int ret =
|
301
|
+
int ret = syscalls::close(fd);
|
259
302
|
if (ret == -1) {
|
260
303
|
throw SystemException("Cannot close the session stream",
|
261
304
|
errno);
|
@@ -276,8 +319,88 @@ private:
|
|
276
319
|
string appRoot;
|
277
320
|
pid_t pid;
|
278
321
|
string listenSocketName;
|
279
|
-
|
322
|
+
string listenSocketType;
|
280
323
|
int ownerPipe;
|
324
|
+
|
325
|
+
SessionPtr connectToUnixServer(const function<void()> &closeCallback) const {
|
326
|
+
TRACE_POINT();
|
327
|
+
int fd, ret;
|
328
|
+
|
329
|
+
do {
|
330
|
+
fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
331
|
+
} while (fd == -1 && errno == EINTR);
|
332
|
+
if (fd == -1) {
|
333
|
+
throw SystemException("Cannot create a new unconnected Unix socket", errno);
|
334
|
+
}
|
335
|
+
|
336
|
+
struct sockaddr_un addr;
|
337
|
+
addr.sun_family = AF_UNIX;
|
338
|
+
strncpy(addr.sun_path, listenSocketName.c_str(), sizeof(addr.sun_path));
|
339
|
+
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
|
340
|
+
do {
|
341
|
+
ret = ::connect(fd, (const sockaddr *) &addr, sizeof(addr));
|
342
|
+
} while (ret == -1 && errno == EINTR);
|
343
|
+
if (ret == -1) {
|
344
|
+
int e = errno;
|
345
|
+
string message("Cannot connect to Unix socket '");
|
346
|
+
message.append(listenSocketName);
|
347
|
+
message.append("'");
|
348
|
+
do {
|
349
|
+
ret = close(fd);
|
350
|
+
} while (ret == -1 && errno == EINTR);
|
351
|
+
throw SystemException(message, e);
|
352
|
+
}
|
353
|
+
|
354
|
+
return ptr(new StandardSession(pid, closeCallback, fd));
|
355
|
+
}
|
356
|
+
|
357
|
+
SessionPtr connectToTcpServer(const function<void()> &closeCallback) const {
|
358
|
+
TRACE_POINT();
|
359
|
+
int fd, ret;
|
360
|
+
vector<string> args;
|
361
|
+
|
362
|
+
split(listenSocketName, ':', args);
|
363
|
+
if (args.size() != 2 || atoi(args[1]) == 0) {
|
364
|
+
throw IOException("Invalid TCP/IP address '" + listenSocketName + "'");
|
365
|
+
}
|
366
|
+
|
367
|
+
struct addrinfo hints, *res;
|
368
|
+
|
369
|
+
memset(&hints, 0, sizeof(hints));
|
370
|
+
hints.ai_family = PF_INET;
|
371
|
+
hints.ai_socktype = SOCK_STREAM;
|
372
|
+
ret = getaddrinfo(args[0].c_str(), args[1].c_str(), &hints, &res);
|
373
|
+
if (ret != 0) {
|
374
|
+
int e = errno;
|
375
|
+
throw IOException("Cannot resolve address '" + listenSocketName +
|
376
|
+
"': " + gai_strerror(e));
|
377
|
+
}
|
378
|
+
|
379
|
+
do {
|
380
|
+
fd = socket(PF_INET, SOCK_STREAM, 0);
|
381
|
+
} while (fd == -1 && errno == EINTR);
|
382
|
+
if (fd == -1) {
|
383
|
+
freeaddrinfo(res);
|
384
|
+
throw SystemException("Cannot create a new unconnected TCP socket", errno);
|
385
|
+
}
|
386
|
+
|
387
|
+
do {
|
388
|
+
ret = ::connect(fd, res->ai_addr, res->ai_addrlen);
|
389
|
+
} while (ret == -1 && errno == EINTR);
|
390
|
+
freeaddrinfo(res);
|
391
|
+
if (ret == -1) {
|
392
|
+
int e = errno;
|
393
|
+
string message("Cannot connect to TCP server '");
|
394
|
+
message.append(listenSocketName);
|
395
|
+
message.append("'");
|
396
|
+
do {
|
397
|
+
ret = close(fd);
|
398
|
+
} while (ret == -1 && errno == EINTR);
|
399
|
+
throw SystemException(message, e);
|
400
|
+
}
|
401
|
+
|
402
|
+
return ptr(new StandardSession(pid, closeCallback, fd));
|
403
|
+
}
|
281
404
|
|
282
405
|
public:
|
283
406
|
/**
|
@@ -288,23 +411,23 @@ public:
|
|
288
411
|
* This must be a valid directory, but the path does not have to be absolute.
|
289
412
|
* @param pid The process ID of this application instance.
|
290
413
|
* @param listenSocketName The name of the listener socket of this application instance.
|
291
|
-
* @param
|
292
|
-
*
|
293
|
-
* contain the leading null byte, even if it's an abstract namespace socket.
|
414
|
+
* @param listenSocketType The type of the listener socket, e.g. "unix" for Unix
|
415
|
+
* domain sockets.
|
294
416
|
* @param ownerPipe The owner pipe of this application instance.
|
295
417
|
* @post getAppRoot() == theAppRoot && getPid() == pid
|
296
418
|
*/
|
297
419
|
Application(const string &theAppRoot, pid_t pid, const string &listenSocketName,
|
298
|
-
|
420
|
+
const string &listenSocketType, int ownerPipe) {
|
299
421
|
appRoot = theAppRoot;
|
300
422
|
this->pid = pid;
|
301
423
|
this->listenSocketName = listenSocketName;
|
302
|
-
this->
|
424
|
+
this->listenSocketType = listenSocketType;
|
303
425
|
this->ownerPipe = ownerPipe;
|
304
426
|
P_TRACE(3, "Application " << this << ": created.");
|
305
427
|
}
|
306
428
|
|
307
429
|
virtual ~Application() {
|
430
|
+
TRACE_POINT();
|
308
431
|
int ret;
|
309
432
|
|
310
433
|
if (ownerPipe != -1) {
|
@@ -312,7 +435,7 @@ public:
|
|
312
435
|
ret = close(ownerPipe);
|
313
436
|
} while (ret == -1 && errno == EINTR);
|
314
437
|
}
|
315
|
-
if (
|
438
|
+
if (listenSocketType == "unix") {
|
316
439
|
do {
|
317
440
|
ret = unlink(listenSocketName.c_str());
|
318
441
|
} while (ret == -1 && errno == EINTR);
|
@@ -384,36 +507,14 @@ public:
|
|
384
507
|
* @throws IOException Something went wrong during the connection process.
|
385
508
|
*/
|
386
509
|
SessionPtr connect(const function<void()> &closeCallback) const {
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
if (fd == -1) {
|
393
|
-
throw SystemException("Cannot create a new unconnected Unix socket", errno);
|
394
|
-
}
|
395
|
-
|
396
|
-
struct sockaddr_un addr;
|
397
|
-
addr.sun_family = AF_UNIX;
|
398
|
-
if (usingAbstractNamespace) {
|
399
|
-
strncpy(addr.sun_path + 1, listenSocketName.c_str(), sizeof(addr.sun_path) - 1);
|
400
|
-
addr.sun_path[0] = '\0';
|
510
|
+
TRACE_POINT();
|
511
|
+
if (listenSocketType == "unix") {
|
512
|
+
return connectToUnixServer(closeCallback);
|
513
|
+
} else if (listenSocketType == "tcp") {
|
514
|
+
return connectToTcpServer(closeCallback);
|
401
515
|
} else {
|
402
|
-
|
403
|
-
}
|
404
|
-
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
|
405
|
-
do {
|
406
|
-
ret = ::connect(fd, (const sockaddr *) &addr, sizeof(addr));
|
407
|
-
} while (ret == -1 && errno == EINTR);
|
408
|
-
if (ret == -1) {
|
409
|
-
int e = errno;
|
410
|
-
string message("Cannot connect to Unix socket '");
|
411
|
-
message.append(listenSocketName);
|
412
|
-
message.append("' on the abstract namespace");
|
413
|
-
throw SystemException(message, e);
|
516
|
+
throw IOException("Unsupported socket type '" + listenSocketType + "'");
|
414
517
|
}
|
415
|
-
|
416
|
-
return ptr(new StandardSession(pid, closeCallback, fd));
|
417
518
|
}
|
418
519
|
};
|
419
520
|
|
@@ -24,6 +24,7 @@
|
|
24
24
|
#include <sys/types.h>
|
25
25
|
|
26
26
|
#include "Application.h"
|
27
|
+
#include "PoolOptions.h"
|
27
28
|
|
28
29
|
namespace Passenger {
|
29
30
|
|
@@ -91,26 +92,30 @@ public:
|
|
91
92
|
virtual ~ApplicationPool() {};
|
92
93
|
|
93
94
|
/**
|
94
|
-
*
|
95
|
+
* Checks whether this ApplicationPool object is still connected to the
|
96
|
+
* ApplicationPool server.
|
97
|
+
*
|
98
|
+
* If that's not the case, then one should reconnect to the ApplicationPool server.
|
99
|
+
*
|
100
|
+
* This method is only meaningful for instances of type ApplicationPoolServer::Client.
|
101
|
+
* The default implementation always returns true.
|
102
|
+
*/
|
103
|
+
virtual bool connected() const {
|
104
|
+
return true;
|
105
|
+
}
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Open a new session with the application specified by <tt>PoolOptions.appRoot</tt>.
|
95
109
|
* See the class description for ApplicationPool, as well as Application::connect(),
|
96
110
|
* on how to use the returned session object.
|
97
111
|
*
|
98
112
|
* Internally, this method may either spawn a new application instance, or use
|
99
113
|
* an existing one.
|
100
114
|
*
|
101
|
-
*
|
102
|
-
*
|
103
|
-
*
|
104
|
-
*
|
105
|
-
* @param appRoot The application root of a RoR application, i.e. the folder that
|
106
|
-
* contains 'app/', 'public/', 'config/', etc. This must be a valid
|
107
|
-
* directory, but does not have to be an absolute path.
|
108
|
-
* @param lowerPrivilege Whether to lower the application's privileges.
|
109
|
-
* @param lowestUser The user to fallback to if lowering privilege fails.
|
110
|
-
* @param environment The RAILS_ENV/RACK_ENV environment that should be used. May not be empty.
|
111
|
-
* @param spawnMethod The spawn method to use. Either "smart" or "conservative".
|
112
|
-
* See the Ruby class SpawnManager for details.
|
113
|
-
* @param appType The application type. Either "rails" or "rack".
|
115
|
+
* @param options An object containing information on which application to open
|
116
|
+
* a session with, as well as spawning details. Spawning details will be used
|
117
|
+
* if the pool decides that spawning a new application instance is necessary.
|
118
|
+
* See SpawnManager and PoolOptions for details.
|
114
119
|
* @return A session object.
|
115
120
|
* @throw SpawnException An attempt was made to spawn a new application instance, but that attempt failed.
|
116
121
|
* @throw BusyException The application pool is too busy right now, and cannot
|
@@ -123,9 +128,14 @@ public:
|
|
123
128
|
* <tt>get("/home/../home/foo")</tt>, then ApplicationPool will think
|
124
129
|
* they're 2 different applications, and thus will spawn 2 application instances.
|
125
130
|
*/
|
126
|
-
virtual Application::SessionPtr get(const
|
127
|
-
|
128
|
-
|
131
|
+
virtual Application::SessionPtr get(const PoolOptions &options) = 0;
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Convenience shortcut for calling get() with default spawn options.
|
135
|
+
*/
|
136
|
+
virtual Application::SessionPtr get(const string &appRoot) {
|
137
|
+
return get(PoolOptions(appRoot));
|
138
|
+
}
|
129
139
|
|
130
140
|
/**
|
131
141
|
* Clear all application instances that are currently in the pool.
|
@@ -173,18 +183,6 @@ public:
|
|
173
183
|
*/
|
174
184
|
virtual void setMaxPerApp(unsigned int max) = 0;
|
175
185
|
|
176
|
-
/**
|
177
|
-
* Sets whether to use a global queue instead of a per-backend process
|
178
|
-
* queue. If enabled, when all backend processes are active, get() will
|
179
|
-
* wait until there's at least one backend process that's idle, instead
|
180
|
-
* of queuing the request into a random process's private queue.
|
181
|
-
* This is especially useful if a website has one or more long-running
|
182
|
-
* requests.
|
183
|
-
*
|
184
|
-
* Defaults to false.
|
185
|
-
*/
|
186
|
-
virtual void setUseGlobalQueue(bool value) = 0;
|
187
|
-
|
188
186
|
/**
|
189
187
|
* Get the process ID of the spawn server that is used.
|
190
188
|
*
|
@@ -22,6 +22,8 @@
|
|
22
22
|
|
23
23
|
#include <boost/shared_ptr.hpp>
|
24
24
|
#include <boost/thread/mutex.hpp>
|
25
|
+
#include <oxt/system_calls.hpp>
|
26
|
+
#include <oxt/backtrace.hpp>
|
25
27
|
|
26
28
|
#include <sys/types.h>
|
27
29
|
#include <sys/stat.h>
|
@@ -40,12 +42,12 @@
|
|
40
42
|
#include "Application.h"
|
41
43
|
#include "Exceptions.h"
|
42
44
|
#include "Logging.h"
|
43
|
-
#include "System.h"
|
44
45
|
|
45
46
|
namespace Passenger {
|
46
47
|
|
47
48
|
using namespace std;
|
48
49
|
using namespace boost;
|
50
|
+
using namespace oxt;
|
49
51
|
|
50
52
|
|
51
53
|
/**
|
@@ -140,16 +142,31 @@ private:
|
|
140
142
|
/**
|
141
143
|
* The socket connection to the ApplicationPool server, as was
|
142
144
|
* established by ApplicationPoolServer::connect().
|
145
|
+
*
|
146
|
+
* The value may be -1, which indicates that the connection has
|
147
|
+
* been closed.
|
143
148
|
*/
|
144
149
|
int server;
|
145
150
|
|
146
|
-
mutex lock;
|
151
|
+
mutable boost::mutex lock;
|
147
152
|
|
148
153
|
~SharedData() {
|
154
|
+
TRACE_POINT();
|
155
|
+
if (server != -1) {
|
156
|
+
disconnect();
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
/**
|
161
|
+
* Disconnect from the ApplicationPool server.
|
162
|
+
*/
|
163
|
+
void disconnect() {
|
164
|
+
TRACE_POINT();
|
149
165
|
int ret;
|
150
166
|
do {
|
151
167
|
ret = close(server);
|
152
168
|
} while (ret == -1 && errno == EINTR);
|
169
|
+
server = -1;
|
153
170
|
}
|
154
171
|
};
|
155
172
|
|
@@ -174,7 +191,7 @@ private:
|
|
174
191
|
|
175
192
|
virtual ~RemoteSession() {
|
176
193
|
closeStream();
|
177
|
-
mutex::scoped_lock(data->lock);
|
194
|
+
boost::mutex::scoped_lock(data->lock);
|
178
195
|
MessageChannel(data->server).write("close", toString(id).c_str(), NULL);
|
179
196
|
}
|
180
197
|
|
@@ -182,9 +199,17 @@ private:
|
|
182
199
|
return fd;
|
183
200
|
}
|
184
201
|
|
202
|
+
virtual void setReaderTimeout(unsigned int msec) {
|
203
|
+
MessageChannel(fd).setReadTimeout(msec);
|
204
|
+
}
|
205
|
+
|
206
|
+
virtual void setWriterTimeout(unsigned int msec) {
|
207
|
+
MessageChannel(fd).setWriteTimeout(msec);
|
208
|
+
}
|
209
|
+
|
185
210
|
virtual void shutdownReader() {
|
186
211
|
if (fd != -1) {
|
187
|
-
int ret =
|
212
|
+
int ret = syscalls::shutdown(fd, SHUT_RD);
|
188
213
|
if (ret == -1) {
|
189
214
|
throw SystemException("Cannot shutdown the writer stream",
|
190
215
|
errno);
|
@@ -194,7 +219,7 @@ private:
|
|
194
219
|
|
195
220
|
virtual void shutdownWriter() {
|
196
221
|
if (fd != -1) {
|
197
|
-
int ret =
|
222
|
+
int ret = syscalls::shutdown(fd, SHUT_WR);
|
198
223
|
if (ret == -1) {
|
199
224
|
throw SystemException("Cannot shutdown the writer stream",
|
200
225
|
errno);
|
@@ -204,7 +229,7 @@ private:
|
|
204
229
|
|
205
230
|
virtual void closeStream() {
|
206
231
|
if (fd != -1) {
|
207
|
-
int ret =
|
232
|
+
int ret = syscalls::close(fd);
|
208
233
|
if (ret == -1) {
|
209
234
|
throw SystemException("Cannot close the session stream",
|
210
235
|
errno);
|
@@ -246,112 +271,167 @@ private:
|
|
246
271
|
data->server = sock;
|
247
272
|
}
|
248
273
|
|
274
|
+
virtual bool connected() const {
|
275
|
+
boost::mutex::scoped_lock(data->lock);
|
276
|
+
return data->server != -1;
|
277
|
+
}
|
278
|
+
|
249
279
|
virtual void clear() {
|
250
280
|
MessageChannel channel(data->server);
|
251
|
-
mutex::scoped_lock l(data->lock);
|
252
|
-
|
281
|
+
boost::mutex::scoped_lock l(data->lock);
|
282
|
+
try {
|
283
|
+
channel.write("clear", NULL);
|
284
|
+
} catch (...) {
|
285
|
+
data->disconnect();
|
286
|
+
throw;
|
287
|
+
}
|
253
288
|
}
|
254
289
|
|
255
290
|
virtual void setMaxIdleTime(unsigned int seconds) {
|
256
291
|
MessageChannel channel(data->server);
|
257
|
-
mutex::scoped_lock l(data->lock);
|
258
|
-
|
292
|
+
boost::mutex::scoped_lock l(data->lock);
|
293
|
+
try {
|
294
|
+
channel.write("setMaxIdleTime", toString(seconds).c_str(), NULL);
|
295
|
+
} catch (...) {
|
296
|
+
data->disconnect();
|
297
|
+
throw;
|
298
|
+
}
|
259
299
|
}
|
260
300
|
|
261
301
|
virtual void setMax(unsigned int max) {
|
262
302
|
MessageChannel channel(data->server);
|
263
|
-
mutex::scoped_lock l(data->lock);
|
264
|
-
|
303
|
+
boost::mutex::scoped_lock l(data->lock);
|
304
|
+
try {
|
305
|
+
channel.write("setMax", toString(max).c_str(), NULL);
|
306
|
+
} catch (...) {
|
307
|
+
data->disconnect();
|
308
|
+
throw;
|
309
|
+
}
|
265
310
|
}
|
266
311
|
|
267
312
|
virtual unsigned int getActive() const {
|
268
313
|
MessageChannel channel(data->server);
|
269
|
-
mutex::scoped_lock l(data->lock);
|
314
|
+
boost::mutex::scoped_lock l(data->lock);
|
270
315
|
vector<string> args;
|
271
316
|
|
272
|
-
|
273
|
-
|
274
|
-
|
317
|
+
try {
|
318
|
+
channel.write("getActive", NULL);
|
319
|
+
channel.read(args);
|
320
|
+
return atoi(args[0].c_str());
|
321
|
+
} catch (...) {
|
322
|
+
data->disconnect();
|
323
|
+
throw;
|
324
|
+
}
|
275
325
|
}
|
276
326
|
|
277
327
|
virtual unsigned int getCount() const {
|
278
328
|
MessageChannel channel(data->server);
|
279
|
-
mutex::scoped_lock l(data->lock);
|
329
|
+
boost::mutex::scoped_lock l(data->lock);
|
280
330
|
vector<string> args;
|
281
331
|
|
282
|
-
|
283
|
-
|
284
|
-
|
332
|
+
try {
|
333
|
+
channel.write("getCount", NULL);
|
334
|
+
channel.read(args);
|
335
|
+
return atoi(args[0].c_str());
|
336
|
+
} catch (...) {
|
337
|
+
data->disconnect();
|
338
|
+
throw;
|
339
|
+
}
|
285
340
|
}
|
286
341
|
|
287
342
|
virtual void setMaxPerApp(unsigned int max) {
|
288
|
-
MessageChannel channel(data->server);
|
289
|
-
mutex::scoped_lock l(data->lock);
|
290
|
-
channel.write("setMaxPerApp", toString(max).c_str(), NULL);
|
291
|
-
}
|
292
|
-
|
293
|
-
virtual void setUseGlobalQueue(bool value) {
|
294
343
|
MessageChannel channel(data->server);
|
295
344
|
boost::mutex::scoped_lock l(data->lock);
|
296
|
-
|
345
|
+
try {
|
346
|
+
channel.write("setMaxPerApp", toString(max).c_str(), NULL);
|
347
|
+
} catch (...) {
|
348
|
+
data->disconnect();
|
349
|
+
throw;
|
350
|
+
}
|
297
351
|
}
|
298
352
|
|
299
353
|
virtual pid_t getSpawnServerPid() const {
|
300
354
|
this_thread::disable_syscall_interruption dsi;
|
301
355
|
MessageChannel channel(data->server);
|
302
|
-
mutex::scoped_lock l(data->lock);
|
356
|
+
boost::mutex::scoped_lock l(data->lock);
|
303
357
|
vector<string> args;
|
304
358
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
const string &appType = "rails"
|
317
|
-
) {
|
359
|
+
try {
|
360
|
+
channel.write("getSpawnServerPid", NULL);
|
361
|
+
channel.read(args);
|
362
|
+
return atoi(args[0].c_str());
|
363
|
+
} catch (...) {
|
364
|
+
data->disconnect();
|
365
|
+
throw;
|
366
|
+
}
|
367
|
+
}
|
368
|
+
|
369
|
+
virtual Application::SessionPtr get(const PoolOptions &options) {
|
318
370
|
this_thread::disable_syscall_interruption dsi;
|
371
|
+
TRACE_POINT();
|
372
|
+
|
319
373
|
MessageChannel channel(data->server);
|
320
|
-
mutex::scoped_lock l(data->lock);
|
374
|
+
boost::mutex::scoped_lock l(data->lock);
|
321
375
|
vector<string> args;
|
322
376
|
int stream;
|
323
377
|
bool result;
|
324
378
|
|
325
379
|
try {
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
380
|
+
vector<string> args;
|
381
|
+
|
382
|
+
args.push_back("get");
|
383
|
+
options.toVector(args);
|
384
|
+
channel.write(args);
|
385
|
+
} catch (const SystemException &e) {
|
386
|
+
UPDATE_TRACE_POINT();
|
387
|
+
data->disconnect();
|
388
|
+
|
389
|
+
string message("Could not send data to the ApplicationPool server: ");
|
390
|
+
message.append(e.brief());
|
391
|
+
throw SystemException(message, e.code());
|
335
392
|
}
|
336
393
|
try {
|
394
|
+
UPDATE_TRACE_POINT();
|
337
395
|
result = channel.read(args);
|
338
396
|
} catch (const SystemException &e) {
|
397
|
+
UPDATE_TRACE_POINT();
|
398
|
+
data->disconnect();
|
339
399
|
throw SystemException("Could not read a message from "
|
340
400
|
"the ApplicationPool server", e.code());
|
341
401
|
}
|
342
402
|
if (!result) {
|
403
|
+
UPDATE_TRACE_POINT();
|
404
|
+
data->disconnect();
|
343
405
|
throw IOException("The ApplicationPool server unexpectedly "
|
344
406
|
"closed the connection.");
|
345
407
|
}
|
346
408
|
if (args[0] == "ok") {
|
347
|
-
|
409
|
+
UPDATE_TRACE_POINT();
|
410
|
+
pid_t pid = (pid_t) atol(args[1]);
|
411
|
+
int sessionID = atoi(args[2]);
|
412
|
+
|
413
|
+
try {
|
414
|
+
stream = channel.readFileDescriptor();
|
415
|
+
} catch (...) {
|
416
|
+
UPDATE_TRACE_POINT();
|
417
|
+
data->disconnect();
|
418
|
+
throw;
|
419
|
+
}
|
420
|
+
|
348
421
|
return ptr(new RemoteSession(dataSmartPointer,
|
349
|
-
|
422
|
+
pid, sessionID, stream));
|
350
423
|
} else if (args[0] == "SpawnException") {
|
424
|
+
UPDATE_TRACE_POINT();
|
351
425
|
if (args[2] == "true") {
|
352
426
|
string errorPage;
|
353
427
|
|
354
|
-
|
428
|
+
try {
|
429
|
+
result = channel.readScalar(errorPage);
|
430
|
+
} catch (...) {
|
431
|
+
data->disconnect();
|
432
|
+
throw;
|
433
|
+
}
|
434
|
+
if (!result) {
|
355
435
|
throw IOException("The ApplicationPool server "
|
356
436
|
"unexpectedly closed the connection.");
|
357
437
|
}
|
@@ -360,10 +440,15 @@ private:
|
|
360
440
|
throw SpawnException(args[1]);
|
361
441
|
}
|
362
442
|
} else if (args[0] == "BusyException") {
|
443
|
+
UPDATE_TRACE_POINT();
|
363
444
|
throw BusyException(args[1]);
|
364
445
|
} else if (args[0] == "IOException") {
|
446
|
+
UPDATE_TRACE_POINT();
|
447
|
+
data->disconnect();
|
365
448
|
throw IOException(args[1]);
|
366
449
|
} else {
|
450
|
+
UPDATE_TRACE_POINT();
|
451
|
+
data->disconnect();
|
367
452
|
throw IOException("The ApplicationPool server returned "
|
368
453
|
"an unknown message: " + toString(args));
|
369
454
|
}
|
@@ -408,12 +493,13 @@ private:
|
|
408
493
|
* @post serverSocket == -1 && serverPid == 0
|
409
494
|
*/
|
410
495
|
void shutdownServer() {
|
496
|
+
TRACE_POINT();
|
411
497
|
this_thread::disable_syscall_interruption dsi;
|
412
498
|
int ret;
|
413
499
|
time_t begin;
|
414
500
|
bool done = false;
|
415
501
|
|
416
|
-
|
502
|
+
syscalls::close(serverSocket);
|
417
503
|
if (!statusReportFIFO.empty()) {
|
418
504
|
do {
|
419
505
|
ret = unlink(statusReportFIFO.c_str());
|
@@ -422,28 +508,28 @@ private:
|
|
422
508
|
|
423
509
|
P_TRACE(2, "Waiting for existing ApplicationPoolServerExecutable (PID " <<
|
424
510
|
serverPid << ") to exit...");
|
425
|
-
begin =
|
426
|
-
while (!done &&
|
511
|
+
begin = syscalls::time(NULL);
|
512
|
+
while (!done && syscalls::time(NULL) < begin + 5) {
|
427
513
|
/*
|
428
514
|
* Some Apache modules fork(), but don't close file descriptors.
|
429
515
|
* mod_wsgi is one such example. Because of that, closing serverSocket
|
430
516
|
* won't always cause the ApplicationPool server to exit. So we send it a
|
431
517
|
* signal.
|
432
518
|
*/
|
433
|
-
|
519
|
+
syscalls::kill(serverPid, SIGINT);
|
434
520
|
|
435
|
-
ret =
|
521
|
+
ret = syscalls::waitpid(serverPid, NULL, WNOHANG);
|
436
522
|
done = ret > 0 || ret == -1;
|
437
523
|
if (!done) {
|
438
|
-
|
524
|
+
syscalls::usleep(100000);
|
439
525
|
}
|
440
526
|
}
|
441
527
|
if (done) {
|
442
528
|
P_TRACE(2, "ApplicationPoolServerExecutable exited.");
|
443
529
|
} else {
|
444
530
|
P_DEBUG("ApplicationPoolServerExecutable not exited in time. Killing it...");
|
445
|
-
|
446
|
-
|
531
|
+
syscalls::kill(serverPid, SIGTERM);
|
532
|
+
syscalls::waitpid(serverPid, NULL, 0);
|
447
533
|
}
|
448
534
|
|
449
535
|
serverSocket = -1;
|
@@ -459,6 +545,7 @@ private:
|
|
459
545
|
* @throw SystemException Something went wrong.
|
460
546
|
*/
|
461
547
|
void restartServer() {
|
548
|
+
TRACE_POINT();
|
462
549
|
int fds[2];
|
463
550
|
pid_t pid;
|
464
551
|
|
@@ -466,14 +553,15 @@ private:
|
|
466
553
|
shutdownServer();
|
467
554
|
}
|
468
555
|
|
469
|
-
if (
|
556
|
+
if (syscalls::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
|
470
557
|
throw SystemException("Cannot create a Unix socket pair", errno);
|
471
558
|
}
|
472
559
|
|
473
560
|
createStatusReportFIFO();
|
474
561
|
|
475
|
-
pid =
|
562
|
+
pid = syscalls::fork();
|
476
563
|
if (pid == 0) { // Child process.
|
564
|
+
dup2(STDERR_FILENO, STDOUT_FILENO); // Redirect stdout to the same channel as stderr.
|
477
565
|
dup2(fds[0], SERVER_SOCKET_FD);
|
478
566
|
|
479
567
|
// Close all unnecessary file descriptors
|
@@ -495,18 +583,20 @@ private:
|
|
495
583
|
m_rubyCommand.c_str(),
|
496
584
|
m_user.c_str(),
|
497
585
|
statusReportFIFO.c_str(),
|
498
|
-
|
586
|
+
(char *) 0);
|
499
587
|
int e = errno;
|
500
|
-
fprintf(stderr, "*** Passenger ERROR
|
588
|
+
fprintf(stderr, "*** Passenger ERROR (%s:%d):\n"
|
589
|
+
"Cannot execute %s: %s (%d)\n",
|
590
|
+
__FILE__, __LINE__,
|
501
591
|
m_serverExecutable.c_str(), strerror(e), e);
|
502
592
|
fflush(stderr);
|
503
593
|
_exit(1);
|
504
594
|
} else if (pid == -1) { // Error.
|
505
|
-
|
506
|
-
|
595
|
+
syscalls::close(fds[0]);
|
596
|
+
syscalls::close(fds[1]);
|
507
597
|
throw SystemException("Cannot create a new process", errno);
|
508
598
|
} else { // Parent process.
|
509
|
-
|
599
|
+
syscalls::close(fds[0]);
|
510
600
|
serverSocket = fds[1];
|
511
601
|
|
512
602
|
int flags = fcntl(serverSocket, F_GETFD);
|
@@ -519,14 +609,24 @@ private:
|
|
519
609
|
}
|
520
610
|
|
521
611
|
void createStatusReportFIFO() {
|
612
|
+
TRACE_POINT();
|
522
613
|
char filename[PATH_MAX];
|
523
614
|
int ret;
|
615
|
+
mode_t permissions;
|
616
|
+
|
617
|
+
createPassengerTempDir();
|
524
618
|
|
525
|
-
|
526
|
-
|
619
|
+
if (m_user.empty()) {
|
620
|
+
permissions = S_IRUSR | S_IWUSR;
|
621
|
+
} else {
|
622
|
+
permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
623
|
+
}
|
624
|
+
|
625
|
+
snprintf(filename, sizeof(filename), "%s/status.fifo",
|
626
|
+
getPassengerTempDir().c_str());
|
527
627
|
filename[PATH_MAX - 1] = '\0';
|
528
628
|
do {
|
529
|
-
ret = mkfifo(filename,
|
629
|
+
ret = mkfifo(filename, permissions);
|
530
630
|
} while (ret == -1 && errno == EINTR);
|
531
631
|
if (ret == -1 && errno != EEXIST) {
|
532
632
|
int e = errno;
|
@@ -536,6 +636,12 @@ private:
|
|
536
636
|
statusReportFIFO = "";
|
537
637
|
} else {
|
538
638
|
statusReportFIFO = filename;
|
639
|
+
|
640
|
+
// It seems that the permissions passed to mkfifo()
|
641
|
+
// aren't respected, so here we chmod the file.
|
642
|
+
do {
|
643
|
+
ret = chmod(filename, permissions);
|
644
|
+
} while (ret == -1 && errno == EINTR);
|
539
645
|
}
|
540
646
|
}
|
541
647
|
|
@@ -572,6 +678,7 @@ public:
|
|
572
678
|
m_logFile(logFile),
|
573
679
|
m_rubyCommand(rubyCommand),
|
574
680
|
m_user(user) {
|
681
|
+
TRACE_POINT();
|
575
682
|
serverSocket = -1;
|
576
683
|
serverPid = 0;
|
577
684
|
this_thread::disable_syscall_interruption dsi;
|
@@ -579,7 +686,9 @@ public:
|
|
579
686
|
}
|
580
687
|
|
581
688
|
~ApplicationPoolServer() {
|
689
|
+
TRACE_POINT();
|
582
690
|
if (serverSocket != -1) {
|
691
|
+
UPDATE_TRACE_POINT();
|
583
692
|
this_thread::disable_syscall_interruption dsi;
|
584
693
|
shutdownServer();
|
585
694
|
}
|
@@ -618,6 +727,7 @@ public:
|
|
618
727
|
* @throws IOException Something went wrong.
|
619
728
|
*/
|
620
729
|
ApplicationPoolPtr connect() {
|
730
|
+
TRACE_POINT();
|
621
731
|
try {
|
622
732
|
this_thread::disable_syscall_interruption dsi;
|
623
733
|
MessageChannel channel(serverSocket);
|
@@ -652,6 +762,7 @@ public:
|
|
652
762
|
* before calling detach().
|
653
763
|
*/
|
654
764
|
void detach() {
|
765
|
+
TRACE_POINT();
|
655
766
|
int ret;
|
656
767
|
do {
|
657
768
|
ret = close(serverSocket);
|