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/Bucket.cpp
CHANGED
@@ -19,29 +19,67 @@
|
|
19
19
|
*/
|
20
20
|
#include "Bucket.h"
|
21
21
|
|
22
|
+
using namespace Passenger;
|
23
|
+
|
24
|
+
static void bucket_destroy(void *data);
|
22
25
|
static apr_status_t bucket_read(apr_bucket *a, const char **str, apr_size_t *len, apr_read_type_e block);
|
23
26
|
|
24
27
|
static const apr_bucket_type_t apr_bucket_type_passenger_pipe = {
|
25
28
|
"PASSENGER_PIPE",
|
26
29
|
5,
|
27
30
|
apr_bucket_type_t::APR_BUCKET_DATA,
|
28
|
-
|
31
|
+
bucket_destroy,
|
29
32
|
bucket_read,
|
30
33
|
apr_bucket_setaside_notimpl,
|
31
34
|
apr_bucket_split_notimpl,
|
32
35
|
apr_bucket_copy_notimpl
|
33
36
|
};
|
34
37
|
|
38
|
+
struct BucketData {
|
39
|
+
Application::SessionPtr session;
|
40
|
+
apr_file_t *pipe;
|
41
|
+
};
|
42
|
+
|
43
|
+
static void
|
44
|
+
bucket_destroy(void *data) {
|
45
|
+
BucketData *bucket_data = (BucketData *) data;
|
46
|
+
if (data != NULL) {
|
47
|
+
delete bucket_data;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
35
51
|
static apr_status_t
|
36
52
|
bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type_e block) {
|
37
53
|
apr_file_t *pipe;
|
38
54
|
char *buf;
|
39
55
|
apr_status_t ret;
|
40
56
|
|
41
|
-
|
57
|
+
BucketData *data = (BucketData *) bucket->data;
|
58
|
+
pipe = data->pipe;
|
42
59
|
|
43
60
|
*str = NULL;
|
44
61
|
*len = APR_BUCKET_BUFF_SIZE;
|
62
|
+
|
63
|
+
if (block == APR_NONBLOCK_READ) {
|
64
|
+
/*
|
65
|
+
* The bucket brigade that Hooks::handleRequest() passes using
|
66
|
+
* ap_pass_brigade() is always passed through ap_content_length_filter,
|
67
|
+
* which is a filter which attempts to read all data from the
|
68
|
+
* bucket brigade and computes the Content-Length header from
|
69
|
+
* that. We don't want this to happen; because suppose that the
|
70
|
+
* Rails application sends back 1 GB of data, then
|
71
|
+
* ap_content_length_filter will buffer this entire 1 GB of data
|
72
|
+
* in memory before passing it to the HTTP client.
|
73
|
+
*
|
74
|
+
* ap_content_length_filter aborts and passes the bucket brigade
|
75
|
+
* down the filter chain when it encounters an APR_EAGAIN, except
|
76
|
+
* for the first read. So by returning APR_EAGAIN on every
|
77
|
+
* non-blocking read request, we can prevent ap_content_length_filter
|
78
|
+
* from buffering all data.
|
79
|
+
*/
|
80
|
+
return APR_EAGAIN;
|
81
|
+
}
|
82
|
+
|
45
83
|
buf = (char *) apr_bucket_alloc(*len, bucket->list); // TODO: check for failure?
|
46
84
|
|
47
85
|
do {
|
@@ -50,6 +88,8 @@ bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type
|
|
50
88
|
|
51
89
|
if (ret != APR_SUCCESS && ret != APR_EOF) {
|
52
90
|
// ... we might want to set an error flag here ...
|
91
|
+
delete data;
|
92
|
+
bucket->data = NULL;
|
53
93
|
apr_bucket_free(buf);
|
54
94
|
return ret;
|
55
95
|
}
|
@@ -59,13 +99,21 @@ bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type
|
|
59
99
|
*/
|
60
100
|
if (*len > 0) {
|
61
101
|
apr_bucket_heap *h;
|
102
|
+
|
103
|
+
*str = buf;
|
104
|
+
bucket->data = NULL;
|
105
|
+
|
62
106
|
/* Change the current bucket to refer to what we read */
|
63
107
|
bucket = apr_bucket_heap_make(bucket, buf, *len, apr_bucket_free);
|
64
108
|
h = (apr_bucket_heap *) bucket->data;
|
65
109
|
h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
|
66
|
-
|
67
|
-
|
110
|
+
APR_BUCKET_INSERT_AFTER(bucket, passenger_bucket_create(
|
111
|
+
data->session, pipe, bucket->list));
|
112
|
+
delete data;
|
68
113
|
} else {
|
114
|
+
delete data;
|
115
|
+
bucket->data = NULL;
|
116
|
+
|
69
117
|
apr_bucket_free(buf);
|
70
118
|
bucket = apr_bucket_immortal_make(bucket, "", 0);
|
71
119
|
*str = (const char *) bucket->data;
|
@@ -76,23 +124,27 @@ bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type
|
|
76
124
|
return APR_SUCCESS;
|
77
125
|
}
|
78
126
|
|
79
|
-
apr_bucket *
|
80
|
-
passenger_bucket_make(apr_bucket *bucket, apr_file_t *pipe) {
|
127
|
+
static apr_bucket *
|
128
|
+
passenger_bucket_make(apr_bucket *bucket, Application::SessionPtr session, apr_file_t *pipe) {
|
129
|
+
BucketData *data = new BucketData();
|
130
|
+
data->session = session;
|
131
|
+
data->pipe = pipe;
|
132
|
+
|
81
133
|
bucket->type = &apr_bucket_type_passenger_pipe;
|
82
134
|
bucket->length = (apr_size_t)(-1);
|
83
135
|
bucket->start = -1;
|
84
|
-
bucket->data =
|
136
|
+
bucket->data = data;
|
85
137
|
return bucket;
|
86
138
|
}
|
87
139
|
|
88
140
|
apr_bucket *
|
89
|
-
passenger_bucket_create(apr_file_t *pipe, apr_bucket_alloc_t *list) {
|
141
|
+
passenger_bucket_create(Application::SessionPtr session, apr_file_t *pipe, apr_bucket_alloc_t *list) {
|
90
142
|
apr_bucket *bucket;
|
91
143
|
|
92
144
|
bucket = (apr_bucket *) apr_bucket_alloc(sizeof(*bucket), list);
|
93
145
|
APR_BUCKET_INIT(bucket);
|
94
146
|
bucket->free = apr_bucket_free;
|
95
147
|
bucket->list = list;
|
96
|
-
return passenger_bucket_make(bucket, pipe);
|
148
|
+
return passenger_bucket_make(bucket, session, pipe);
|
97
149
|
}
|
98
150
|
|
data/ext/apache2/Bucket.h
CHANGED
@@ -21,18 +21,25 @@
|
|
21
21
|
#define _PASSENGER_BUCKET_H_
|
22
22
|
|
23
23
|
/**
|
24
|
-
* apr_bucket_pipe closes a pipe's file descriptor when it has reached
|
25
|
-
* but not when an error has occurred.
|
26
|
-
* file descriptor
|
24
|
+
* apr_bucket_pipe closes a pipe's file descriptor when it has reached
|
25
|
+
* end-of-stream, but not when an error has occurred. This behavior is
|
26
|
+
* undesirable because it can easily cause file descriptor leaks.
|
27
27
|
*
|
28
|
-
* passenger_bucket is like apr_bucket_pipe, but
|
29
|
-
*
|
30
|
-
*
|
28
|
+
* passenger_bucket is like apr_bucket_pipe, but it also holds a reference to
|
29
|
+
* a Session. When a read error has occured or when end-of-stream has been
|
30
|
+
* reached, the Session will be dereferenced, so that the underlying file
|
31
|
+
* descriptor is closed.
|
32
|
+
*
|
33
|
+
* passenger_bucket also ignores the APR_NONBLOCK_READ flag because that's
|
34
|
+
* known to cause strange I/O problems.
|
31
35
|
*/
|
32
36
|
|
33
|
-
#include
|
37
|
+
#include <apr_buckets.h>
|
38
|
+
#include "Application.h"
|
34
39
|
|
35
|
-
apr_bucket *passenger_bucket_create(
|
40
|
+
apr_bucket *passenger_bucket_create(Passenger::Application::SessionPtr session,
|
41
|
+
apr_file_t *pipe,
|
42
|
+
apr_bucket_alloc_t *list);
|
36
43
|
|
37
44
|
#endif /* _PASSENGER_BUCKET_H_ */
|
38
45
|
|
@@ -0,0 +1,114 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - http://www.modrails.com/
|
3
|
+
* Copyright (C) 2009 Phusion
|
4
|
+
*
|
5
|
+
* Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* This program is free software; you can redistribute it and/or modify
|
8
|
+
* it under the terms of the GNU General Public License as published by
|
9
|
+
* the Free Software Foundation; version 2 of the License.
|
10
|
+
*
|
11
|
+
* This program is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
* GNU General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU General Public License along
|
17
|
+
* with this program; if not, write to the Free Software Foundation, Inc.,
|
18
|
+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
19
|
+
*/
|
20
|
+
#include "CachedFileStat.h"
|
21
|
+
|
22
|
+
#include <map>
|
23
|
+
#include <list>
|
24
|
+
|
25
|
+
#include <boost/shared_ptr.hpp>
|
26
|
+
#include <boost/thread.hpp>
|
27
|
+
|
28
|
+
using namespace std;
|
29
|
+
using namespace boost;
|
30
|
+
using namespace Passenger;
|
31
|
+
|
32
|
+
// CachedMultiFileStat is written in C++, with a C wrapper API around it.
|
33
|
+
// I'm not going to reinvent my own linked list and hash table in C when I
|
34
|
+
// can just use the STL.
|
35
|
+
struct CachedMultiFileStat {
|
36
|
+
struct Item {
|
37
|
+
string filename;
|
38
|
+
CachedFileStat cstat;
|
39
|
+
|
40
|
+
Item(const string &filename)
|
41
|
+
: cstat(filename)
|
42
|
+
{
|
43
|
+
this->filename = filename;
|
44
|
+
}
|
45
|
+
};
|
46
|
+
|
47
|
+
typedef shared_ptr<Item> ItemPtr;
|
48
|
+
typedef list<ItemPtr> ItemList;
|
49
|
+
typedef map<string, ItemList::iterator> ItemMap;
|
50
|
+
|
51
|
+
unsigned int maxSize;
|
52
|
+
ItemList items;
|
53
|
+
ItemMap cache;
|
54
|
+
boost::mutex lock;
|
55
|
+
|
56
|
+
CachedMultiFileStat(unsigned int maxSize) {
|
57
|
+
this->maxSize = maxSize;
|
58
|
+
}
|
59
|
+
|
60
|
+
int stat(const string &filename, struct stat *buf, unsigned int throttleRate = 0) {
|
61
|
+
boost::unique_lock<boost::mutex> l(lock);
|
62
|
+
ItemMap::iterator it(cache.find(filename));
|
63
|
+
ItemPtr item;
|
64
|
+
int ret;
|
65
|
+
|
66
|
+
if (it == cache.end()) {
|
67
|
+
// Filename not in cache.
|
68
|
+
// If cache is full, remove the least recently used
|
69
|
+
// cache entry.
|
70
|
+
if (cache.size() == maxSize) {
|
71
|
+
ItemList::iterator listEnd(items.end());
|
72
|
+
listEnd--;
|
73
|
+
string filename((*listEnd)->filename);
|
74
|
+
items.pop_back();
|
75
|
+
cache.erase(filename);
|
76
|
+
}
|
77
|
+
|
78
|
+
// Add to cache as most recently used.
|
79
|
+
item = ItemPtr(new Item(filename));
|
80
|
+
items.push_front(item);
|
81
|
+
cache[filename] = items.begin();
|
82
|
+
} else {
|
83
|
+
// Cache hit.
|
84
|
+
item = *it->second;
|
85
|
+
|
86
|
+
// Mark this cache item as most recently used.
|
87
|
+
items.erase(it->second);
|
88
|
+
items.push_front(item);
|
89
|
+
cache[filename] = items.begin();
|
90
|
+
}
|
91
|
+
ret = item->cstat.refresh(throttleRate);
|
92
|
+
*buf = item->cstat.info;
|
93
|
+
return ret;
|
94
|
+
}
|
95
|
+
};
|
96
|
+
|
97
|
+
CachedMultiFileStat *
|
98
|
+
cached_multi_file_stat_new(unsigned int max_size) {
|
99
|
+
return new CachedMultiFileStat(max_size);
|
100
|
+
}
|
101
|
+
|
102
|
+
void
|
103
|
+
cached_multi_file_stat_free(CachedMultiFileStat *mstat) {
|
104
|
+
delete mstat;
|
105
|
+
}
|
106
|
+
|
107
|
+
int
|
108
|
+
cached_multi_file_stat_perform(CachedMultiFileStat *mstat,
|
109
|
+
const char *filename,
|
110
|
+
struct stat *buf,
|
111
|
+
unsigned int throttle_rate)
|
112
|
+
{
|
113
|
+
return mstat->stat(filename, buf, throttle_rate);
|
114
|
+
}
|
@@ -0,0 +1,169 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - http://www.modrails.com/
|
3
|
+
* Copyright (C) 2009 Phusion
|
4
|
+
*
|
5
|
+
* Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* This program is free software; you can redistribute it and/or modify
|
8
|
+
* it under the terms of the GNU General Public License as published by
|
9
|
+
* the Free Software Foundation; version 2 of the License.
|
10
|
+
*
|
11
|
+
* This program is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
* GNU General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU General Public License along
|
17
|
+
* with this program; if not, write to the Free Software Foundation, Inc.,
|
18
|
+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
19
|
+
*/
|
20
|
+
#ifndef _PASSENGER_CACHED_FILE_STAT_H_
|
21
|
+
#define _PASSENGER_CACHED_FILE_STAT_H_
|
22
|
+
|
23
|
+
#include <sys/types.h>
|
24
|
+
#include <sys/stat.h>
|
25
|
+
#include <unistd.h>
|
26
|
+
#include <time.h>
|
27
|
+
|
28
|
+
#ifdef __cplusplus
|
29
|
+
|
30
|
+
#include <errno.h>
|
31
|
+
#include <string>
|
32
|
+
#include <oxt/system_calls.hpp>
|
33
|
+
|
34
|
+
#include "SystemTime.h"
|
35
|
+
|
36
|
+
namespace Passenger {
|
37
|
+
|
38
|
+
using namespace std;
|
39
|
+
using namespace oxt;
|
40
|
+
|
41
|
+
/**
|
42
|
+
* CachedFileStat allows one to stat() a file at a throttled rate, in order
|
43
|
+
* to minimize stress on the filesystem. It does this by caching the old stat
|
44
|
+
* data for a specified amount of time.
|
45
|
+
*/
|
46
|
+
class CachedFileStat {
|
47
|
+
private:
|
48
|
+
/** The last return value of stat(). */
|
49
|
+
int last_result;
|
50
|
+
|
51
|
+
/** The errno set by the last stat() call. */
|
52
|
+
int last_errno;
|
53
|
+
|
54
|
+
/** The filename of the file to stat. */
|
55
|
+
string filename;
|
56
|
+
|
57
|
+
/** The last time a stat() was performed. */
|
58
|
+
time_t last_time;
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Checks whether <em>interval</em> seconds have elapsed since <em>begin</em>
|
62
|
+
* The current time is returned via the <tt>currentTime</tt> argument,
|
63
|
+
* so that the caller doesn't have to call time() again if it needs the current
|
64
|
+
* time.
|
65
|
+
*
|
66
|
+
* @pre begin <= time(NULL)
|
67
|
+
* @return Whether <tt>interval</tt> seconds have elapsed since <tt>begin</tt>.
|
68
|
+
* @throws SystemException Something went wrong while retrieving the time.
|
69
|
+
* @throws boost::thread_interrupted
|
70
|
+
*/
|
71
|
+
bool expired(time_t begin, unsigned int interval, time_t ¤tTime) {
|
72
|
+
currentTime = SystemTime::get();
|
73
|
+
return (unsigned int) (currentTime - begin) >= interval;
|
74
|
+
}
|
75
|
+
|
76
|
+
public:
|
77
|
+
/** The cached stat info. */
|
78
|
+
struct stat info;
|
79
|
+
|
80
|
+
/**
|
81
|
+
* Creates a new CachedFileStat object. The file will not be
|
82
|
+
* stat()ted until you call refresh().
|
83
|
+
*
|
84
|
+
* @param filename The file to stat.
|
85
|
+
*/
|
86
|
+
CachedFileStat(const string &filename) {
|
87
|
+
memset(&info, 0, sizeof(struct stat));
|
88
|
+
last_result = -1;
|
89
|
+
last_errno = 0;
|
90
|
+
this->filename = filename;
|
91
|
+
last_time = 0;
|
92
|
+
}
|
93
|
+
|
94
|
+
/**
|
95
|
+
* Re-stat() the file, if necessary. If <tt>throttleRate</tt> seconds have
|
96
|
+
* passed since the last time stat() was called, then the file will be
|
97
|
+
* re-stat()ted.
|
98
|
+
*
|
99
|
+
* The stat information, which may either be the result of a new stat() call
|
100
|
+
* or just the old cached information, is be available in the <tt>info</tt>
|
101
|
+
* member.
|
102
|
+
*
|
103
|
+
* @return 0 if the stat() call succeeded or if no stat() was performed,
|
104
|
+
* -1 if something went wrong while statting the file. In the latter
|
105
|
+
* case, <tt>errno</tt> will be populated with an appropriate error code.
|
106
|
+
* @throws SystemException Something went wrong while retrieving the system time.
|
107
|
+
* @throws boost::thread_interrupted
|
108
|
+
*/
|
109
|
+
int refresh(unsigned int throttleRate) {
|
110
|
+
time_t currentTime;
|
111
|
+
int ret;
|
112
|
+
|
113
|
+
if (expired(last_time, throttleRate, currentTime)) {
|
114
|
+
ret = stat(filename.c_str(), &info);
|
115
|
+
if (ret == -1 && errno == EINTR) {
|
116
|
+
/* If the stat() call was interrupted, then don't
|
117
|
+
* update any state so that the caller can call
|
118
|
+
* this function again without us returning a
|
119
|
+
* cached EINTR error.
|
120
|
+
*/
|
121
|
+
return -1;
|
122
|
+
} else {
|
123
|
+
last_result = ret;
|
124
|
+
last_errno = errno;
|
125
|
+
last_time = currentTime;
|
126
|
+
return ret;
|
127
|
+
}
|
128
|
+
} else {
|
129
|
+
errno = last_errno;
|
130
|
+
return last_result;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
};
|
134
|
+
|
135
|
+
} // namespace Passenger
|
136
|
+
|
137
|
+
#endif /* __cplusplus */
|
138
|
+
|
139
|
+
|
140
|
+
#ifdef __cplusplus
|
141
|
+
extern "C" {
|
142
|
+
#endif
|
143
|
+
|
144
|
+
/**
|
145
|
+
* CachedMultiFileStat allows one to stat() files at a throttled rate, in order
|
146
|
+
* to minimize stress on the filesystem. It does this by caching the old stat
|
147
|
+
* data for a specified amount of time.
|
148
|
+
*
|
149
|
+
* Unlike CachedFileStat, which can only stat() one specific file per
|
150
|
+
* CachedFileStat object, CachedMultiFileStat can stat() any file. The
|
151
|
+
* number of cached stat() information is limited by the given cache size.
|
152
|
+
*
|
153
|
+
* This class is fully thread-safe.
|
154
|
+
*/
|
155
|
+
typedef struct CachedMultiFileStat CachedMultiFileStat;
|
156
|
+
|
157
|
+
CachedMultiFileStat *cached_multi_file_stat_new(unsigned int max_size);
|
158
|
+
void cached_multi_file_stat_free(CachedMultiFileStat *mstat);
|
159
|
+
int cached_multi_file_stat_perform(CachedMultiFileStat *mstat,
|
160
|
+
const char *filename,
|
161
|
+
struct stat *buf,
|
162
|
+
unsigned int throttle_rate);
|
163
|
+
|
164
|
+
#ifdef __cplusplus
|
165
|
+
}
|
166
|
+
#endif
|
167
|
+
|
168
|
+
#endif /* _PASSENGER_CACHED_FILE_STAT_H_ */
|
169
|
+
|