passenger 2.2.15 → 3.0.0.pre1
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 +21 -12
- data/LICENSE +1 -1
- data/NEWS +8 -1
- data/PACKAGING.TXT +25 -0
- data/Rakefile +28 -891
- data/bin/passenger +32 -0
- data/bin/passenger-config +5 -5
- data/bin/passenger-install-apache2-module +37 -24
- data/bin/passenger-install-nginx-module +48 -46
- data/bin/passenger-make-enterprisey +8 -9
- data/bin/passenger-memory-stats +20 -150
- data/bin/passenger-status +130 -44
- data/bin/passenger-stress-test +5 -4
- data/build/agents.rb +73 -0
- data/build/apache2.rb +165 -0
- data/build/basics.rb +81 -0
- data/build/common_library.rb +198 -0
- data/build/config.rb +35 -0
- data/{misc/rake/cplusplus.rb → build/cplusplus_support.rb} +1 -1
- data/build/cxx_tests.rb +205 -0
- data/build/documentation.rb +77 -0
- data/{misc/rake → build}/gempackagetask.rb +1 -1
- data/build/integration_tests.rb +57 -0
- data/build/misc.rb +146 -0
- data/build/nginx.rb +64 -0
- data/build/oxt_tests.rb +52 -0
- data/{misc/rake → build}/packagetask.rb +0 -0
- data/build/packaging.rb +189 -0
- data/{misc/rake/extensions.rb → build/rake_extensions.rb} +1 -1
- data/{misc/rake → build}/rdoctask.rb +0 -0
- data/build/ruby_extension.rb +46 -0
- data/build/ruby_tests.rb +42 -0
- data/build/test_basics.rb +31 -0
- data/doc/ApplicationPool algorithm.txt +447 -234
- data/doc/Architectural overview.html +47 -56
- data/doc/Doxyfile +1 -1
- data/doc/Security of user switching support.html +46 -57
- data/doc/Users guide Apache.html +1033 -306
- data/doc/Users guide Apache.txt +419 -99
- data/doc/Users guide Nginx.html +1252 -253
- data/doc/Users guide Nginx.txt +711 -87
- data/doc/Users guide Standalone.html +603 -0
- data/doc/Users guide Standalone.txt +40 -0
- data/doc/cxxapi/AbstractSpawnManager_8h_source.html +141 -0
- data/doc/cxxapi/Account_8h_source.html +206 -0
- data/doc/cxxapi/AccountsDatabase_8h_source.html +161 -0
- data/doc/cxxapi/AgentBase_8h_source.html +70 -0
- data/doc/cxxapi/AgentsStarter_8h_source.html +112 -0
- data/doc/cxxapi/BCrypt_8h_source.html +104 -0
- data/doc/cxxapi/Blowfish_8h_source.html +134 -0
- data/doc/cxxapi/Bucket_8h_source.html +4 -3
- data/doc/cxxapi/Constants_8h_source.html +79 -0
- data/doc/cxxapi/ContentHandler_8h_source.html +95 -0
- data/doc/cxxapi/DirectoryMapper_8h_source.html +9 -8
- data/doc/cxxapi/EventedClient_8h_source.html +629 -0
- data/doc/cxxapi/EventedMessageServer_8h_source.html +358 -0
- data/doc/cxxapi/EventedServer_8h_source.html +326 -0
- data/doc/cxxapi/Exceptions_8h_source.html +366 -0
- data/doc/cxxapi/FileDescriptor_8h_source.html +260 -0
- data/doc/cxxapi/Hooks_8h_source.html +2 -1
- data/doc/cxxapi/HttpStatusExtractor_8h_source.html +382 -0
- data/doc/cxxapi/Logging_8h_source.html +726 -0
- data/doc/cxxapi/MessageChannel_8h_source.html +852 -0
- data/doc/cxxapi/MessageClient_8h_source.html +328 -0
- data/doc/cxxapi/MessageReadersWriters_8h_source.html +539 -0
- data/doc/cxxapi/MessageServer_8h_source.html +606 -0
- data/doc/cxxapi/PoolOptions_8h_source.html +548 -0
- data/doc/cxxapi/Process_8h_source.html +286 -0
- data/doc/cxxapi/RandomGenerator_8h_source.html +191 -0
- data/doc/cxxapi/ResourceLocator_8h_source.html +115 -0
- data/doc/cxxapi/ScgiRequestParser_8h_source.html +406 -0
- data/doc/cxxapi/ServerInstanceDir_8h_source.html +374 -0
- data/doc/cxxapi/Session_8h_source.html +501 -0
- data/doc/cxxapi/SpawnManager_8h_source.html +647 -0
- data/doc/cxxapi/StaticContentHandler_8h_source.html +68 -0
- data/doc/cxxapi/StaticString_8h_source.html +254 -0
- data/doc/cxxapi/StringListCreator_8h_source.html +114 -0
- data/doc/cxxapi/Utils_8h_source.html +442 -0
- data/doc/cxxapi/annotated.html +46 -0
- data/doc/cxxapi/apache2_2Configuration_8h_source.html +82 -0
- data/doc/cxxapi/classAgentWatcher-members.html +30 -26
- data/doc/cxxapi/classAgentWatcher.html +168 -194
- data/doc/cxxapi/classClient-members.html +14 -11
- data/doc/cxxapi/classClient.html +35 -35
- data/doc/cxxapi/classHooks-members.html +2 -0
- data/doc/cxxapi/classHooks.html +2 -0
- data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager-members.html +16 -13
- data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager.html +78 -82
- data/doc/cxxapi/classPassenger_1_1ArgumentException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1ArgumentException.html +26 -22
- data/doc/cxxapi/classPassenger_1_1ArrayMessage-members.html +37 -0
- data/doc/cxxapi/classPassenger_1_1ArrayMessage.html +113 -0
- data/doc/cxxapi/classPassenger_1_1BufferedUpload-members.html +14 -11
- data/doc/cxxapi/classPassenger_1_1BufferedUpload.html +41 -42
- data/doc/cxxapi/classPassenger_1_1BusyException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1BusyException.html +24 -20
- data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +23 -19
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +2 -0
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +8 -6
- data/doc/cxxapi/classPassenger_1_1EOFException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1EOFException.html +27 -23
- data/doc/cxxapi/classPassenger_1_1EventFd-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1EventFd.html +24 -21
- data/doc/cxxapi/classPassenger_1_1EventedClient-members.html +54 -0
- data/doc/cxxapi/classPassenger_1_1EventedClient.html +436 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer-members.html +37 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer.html +59 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.map +3 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.md5 +1 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer-members.html +37 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer.html +93 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.map +3 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.md5 +1 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1FileDescriptor-members.html +16 -13
- data/doc/cxxapi/classPassenger_1_1FileDescriptor.html +63 -70
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +26 -22
- data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +17 -14
- data/doc/cxxapi/classPassenger_1_1FileSystemException.html +32 -30
- data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor-members.html +15 -12
- data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor.html +59 -59
- data/doc/cxxapi/classPassenger_1_1IOException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1IOException.html +27 -23
- data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +36 -33
- data/doc/cxxapi/classPassenger_1_1MessageChannel.html +326 -344
- data/doc/cxxapi/classPassenger_1_1MessageServer-members.html +25 -22
- data/doc/cxxapi/classPassenger_1_1MessageServer.html +160 -191
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext.html +29 -27
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.map +3 -1
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext-members.html +17 -14
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext.html +69 -79
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.map +3 -1
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler-members.html +15 -12
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler.html +60 -63
- data/doc/cxxapi/classPassenger_1_1Process-members.html +20 -17
- data/doc/cxxapi/classPassenger_1_1Process.html +88 -95
- data/doc/cxxapi/classPassenger_1_1RandomGenerator-members.html +13 -10
- data/doc/cxxapi/classPassenger_1_1RandomGenerator.html +36 -35
- data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1RuntimeException.html +24 -20
- data/doc/cxxapi/classPassenger_1_1ScalarMessage-members.html +37 -0
- data/doc/cxxapi/classPassenger_1_1ScalarMessage.html +76 -0
- data/doc/cxxapi/classPassenger_1_1ScgiRequestParser-members.html +26 -23
- data/doc/cxxapi/classPassenger_1_1ScgiRequestParser.html +121 -138
- data/doc/cxxapi/classPassenger_1_1SecurityException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1SecurityException.html +26 -22
- data/doc/cxxapi/classPassenger_1_1Session-members.html +29 -26
- data/doc/cxxapi/classPassenger_1_1Session.html +219 -240
- data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +14 -11
- data/doc/cxxapi/classPassenger_1_1SpawnException.html +36 -37
- data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +18 -15
- data/doc/cxxapi/classPassenger_1_1SpawnManager.html +115 -110
- data/doc/cxxapi/classPassenger_1_1StandardSession-members.html +30 -27
- data/doc/cxxapi/classPassenger_1_1StandardSession.html +163 -184
- data/doc/cxxapi/classPassenger_1_1StaticString-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1StaticString.html +27 -25
- data/doc/cxxapi/classPassenger_1_1SystemException-members.html +16 -13
- data/doc/cxxapi/classPassenger_1_1SystemException.html +65 -67
- data/doc/cxxapi/classPassenger_1_1TimeRetrievalException-members.html +16 -13
- data/doc/cxxapi/classPassenger_1_1TimeRetrievalException.html +27 -23
- data/doc/cxxapi/classPassenger_1_1TimeoutException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1TimeoutException.html +24 -20
- data/doc/cxxapi/classPassenger_1_1Uint16Message-members.html +36 -0
- data/doc/cxxapi/classPassenger_1_1Uint16Message.html +51 -0
- data/doc/cxxapi/classPassenger_1_1Uint32Message-members.html +36 -0
- data/doc/cxxapi/classPassenger_1_1Uint32Message.html +51 -0
- data/doc/cxxapi/classServer-members.html +12 -9
- data/doc/cxxapi/classServer.html +23 -20
- data/doc/cxxapi/classServerInstanceDirToucher-members.html +12 -9
- data/doc/cxxapi/classServerInstanceDirToucher.html +21 -17
- data/doc/cxxapi/classes.html +18 -4
- data/doc/cxxapi/definitions_8h_source.html +1 -0
- data/doc/cxxapi/files.html +36 -1
- data/doc/cxxapi/functions.html +53 -21
- data/doc/cxxapi/functions_0x62.html +82 -0
- data/doc/cxxapi/functions_0x63.html +99 -0
- data/doc/cxxapi/functions_0x64.html +95 -0
- data/doc/cxxapi/functions_0x65.html +88 -0
- data/doc/cxxapi/functions_0x66.html +100 -0
- data/doc/cxxapi/functions_0x67.html +170 -0
- data/doc/cxxapi/functions_0x68.html +88 -0
- data/doc/cxxapi/functions_0x69.html +93 -0
- data/doc/cxxapi/functions_0x6b.html +80 -0
- data/doc/cxxapi/functions_0x6c.html +88 -0
- data/doc/cxxapi/functions_0x6d.html +88 -0
- data/doc/cxxapi/functions_0x6e.html +86 -0
- data/doc/cxxapi/functions_0x6f.html +94 -0
- data/doc/cxxapi/functions_0x70.html +94 -0
- data/doc/cxxapi/functions_0x72.html +110 -0
- data/doc/cxxapi/functions_0x73.html +171 -0
- data/doc/cxxapi/functions_0x74.html +85 -0
- data/doc/cxxapi/functions_0x75.html +85 -0
- data/doc/cxxapi/functions_0x77.html +92 -0
- data/doc/cxxapi/functions_0x7e.html +79 -0
- data/doc/cxxapi/functions_enum.html +14 -12
- data/doc/cxxapi/functions_eval.html +22 -16
- data/doc/cxxapi/functions_func.html +460 -1
- data/doc/cxxapi/functions_vars.html +163 -63
- data/doc/cxxapi/graph_legend.html +1 -0
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Core.html +2 -2
- data/doc/cxxapi/group__Core.map +1 -2
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Exceptions.html +32 -40
- data/doc/cxxapi/group__Hooks.html +2 -1
- data/doc/cxxapi/group__Hooks.map +1 -1
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/group__Support.html +509 -0
- data/doc/cxxapi/hierarchy.html +66 -62
- data/doc/cxxapi/inherit__graph__10.map +3 -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 +4 -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 +3 -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 +3 -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 +3 -1
- 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 +5 -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 +3 -3
- data/doc/cxxapi/inherit__graph__16.md5 +1 -1
- data/doc/cxxapi/inherit__graph__16.png +0 -0
- data/doc/cxxapi/inherit__graph__17.map +3 -1
- data/doc/cxxapi/inherit__graph__17.md5 +1 -1
- data/doc/cxxapi/inherit__graph__17.png +0 -0
- data/doc/cxxapi/inherit__graph__18.map +4 -1
- data/doc/cxxapi/inherit__graph__18.md5 +1 -1
- data/doc/cxxapi/inherit__graph__18.png +0 -0
- data/doc/cxxapi/inherit__graph__19.map +3 -1
- data/doc/cxxapi/inherit__graph__19.md5 +1 -1
- data/doc/cxxapi/inherit__graph__19.png +0 -0
- data/doc/cxxapi/inherit__graph__20.map +3 -2
- 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 +3 -1
- data/doc/cxxapi/inherit__graph__21.md5 +1 -1
- data/doc/cxxapi/inherit__graph__21.png +0 -0
- data/doc/cxxapi/inherit__graph__22.map +3 -1
- data/doc/cxxapi/inherit__graph__22.md5 +1 -1
- data/doc/cxxapi/inherit__graph__22.png +0 -0
- data/doc/cxxapi/inherit__graph__23.map +3 -1
- data/doc/cxxapi/inherit__graph__23.md5 +1 -1
- data/doc/cxxapi/inherit__graph__23.png +0 -0
- data/doc/cxxapi/inherit__graph__24.map +3 -1
- data/doc/cxxapi/inherit__graph__24.md5 +1 -1
- data/doc/cxxapi/inherit__graph__24.png +0 -0
- data/doc/cxxapi/inherit__graph__25.map +3 -1
- data/doc/cxxapi/inherit__graph__25.md5 +1 -1
- data/doc/cxxapi/inherit__graph__25.png +0 -0
- data/doc/cxxapi/inherit__graph__26.map +3 -1
- data/doc/cxxapi/inherit__graph__26.md5 +1 -1
- data/doc/cxxapi/inherit__graph__26.png +0 -0
- data/doc/cxxapi/inherit__graph__27.map +3 -1
- data/doc/cxxapi/inherit__graph__27.md5 +1 -1
- data/doc/cxxapi/inherit__graph__27.png +0 -0
- data/doc/cxxapi/inherit__graph__28.map +4 -1
- data/doc/cxxapi/inherit__graph__28.md5 +1 -1
- data/doc/cxxapi/inherit__graph__28.png +0 -0
- data/doc/cxxapi/inherit__graph__29.map +3 -1
- data/doc/cxxapi/inherit__graph__29.md5 +1 -1
- data/doc/cxxapi/inherit__graph__29.png +0 -0
- data/doc/cxxapi/inherit__graph__30.map +3 -2
- data/doc/cxxapi/inherit__graph__30.md5 +1 -1
- data/doc/cxxapi/inherit__graph__30.png +0 -0
- data/doc/cxxapi/inherit__graph__31.map +3 -1
- data/doc/cxxapi/inherit__graph__31.md5 +1 -1
- data/doc/cxxapi/inherit__graph__31.png +0 -0
- data/doc/cxxapi/inherit__graph__32.map +5 -1
- data/doc/cxxapi/inherit__graph__32.md5 +1 -1
- data/doc/cxxapi/inherit__graph__32.png +0 -0
- data/doc/cxxapi/inherit__graph__33.map +3 -1
- data/doc/cxxapi/inherit__graph__33.md5 +1 -1
- data/doc/cxxapi/inherit__graph__33.png +0 -0
- data/doc/cxxapi/inherit__graph__34.map +3 -3
- data/doc/cxxapi/inherit__graph__34.md5 +1 -1
- data/doc/cxxapi/inherit__graph__34.png +0 -0
- data/doc/cxxapi/inherit__graph__35.map +3 -1
- data/doc/cxxapi/inherit__graph__35.md5 +1 -1
- data/doc/cxxapi/inherit__graph__35.png +0 -0
- data/doc/cxxapi/inherit__graph__36.map +3 -1
- data/doc/cxxapi/inherit__graph__36.md5 +1 -1
- data/doc/cxxapi/inherit__graph__36.png +0 -0
- data/doc/cxxapi/inherit__graph__37.map +3 -1
- data/doc/cxxapi/inherit__graph__37.md5 +1 -1
- data/doc/cxxapi/inherit__graph__37.png +0 -0
- data/doc/cxxapi/inherit__graph__4.map +3 -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 +3 -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 +3 -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 +3 -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 +3 -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 +3 -1
- data/doc/cxxapi/inherit__graph__9.md5 +1 -1
- data/doc/cxxapi/inherit__graph__9.png +0 -0
- data/doc/cxxapi/inherits.html +123 -126
- data/doc/cxxapi/main.html +1 -0
- data/doc/cxxapi/modules.html +2 -1
- data/doc/cxxapi/namespacePassenger.html +263 -492
- data/doc/cxxapi/namespacemembers.html +68 -96
- data/doc/cxxapi/namespacemembers_enum.html +14 -12
- data/doc/cxxapi/namespacemembers_eval.html +20 -15
- data/doc/cxxapi/namespacemembers_func.html +52 -88
- data/doc/cxxapi/namespacemembers_type.html +18 -14
- data/doc/cxxapi/namespaces.html +12 -9
- data/doc/cxxapi/nginx_2Configuration_8h_source.html +125 -0
- data/doc/cxxapi/ngx__http__passenger__module_8h_source.html +94 -0
- data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard-members.html +12 -9
- data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard.html +24 -22
- data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +43 -38
- data/doc/cxxapi/structPassenger_1_1PoolOptions.html +275 -325
- data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash-members.html +12 -9
- data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash.html +24 -22
- data/doc/cxxapi/tree.html +152 -7
- data/doc/users_guide_snippets/{analysis_and_system_maintenance_tools.txt → analysis_and_system_maintenance.txt} +58 -1
- data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +1 -2
- data/doc/users_guide_snippets/global_queueing_explained.txt +1 -5
- data/doc/users_guide_snippets/{rails_spawn_method.txt → passenger_spawn_method.txt} +9 -8
- data/doc/users_guide_snippets/tips.txt +12 -6
- data/doc/users_guide_snippets/under_the_hood/page_caching_support.txt +22 -0
- data/ext/apache2/Bucket.cpp +4 -4
- data/ext/apache2/Bucket.h +3 -3
- data/ext/apache2/Configuration.cpp +278 -381
- data/ext/apache2/Configuration.h +3 -357
- data/ext/apache2/Configuration.hpp +461 -0
- data/ext/apache2/DirectoryMapper.h +3 -3
- data/ext/apache2/HelperAgent.cpp +359 -0
- data/ext/apache2/Hooks.cpp +339 -226
- data/ext/apache2/Hooks.h +1 -1
- data/ext/apache2/mod_passenger.c +10 -4
- data/ext/boost/algorithm/string/case_conv.hpp +4 -4
- data/ext/boost/algorithm/string/concept.hpp +2 -2
- data/ext/boost/algorithm/string/detail/case_conv.hpp +18 -9
- data/ext/boost/algorithm/string/detail/find_format.hpp +44 -43
- data/ext/boost/algorithm/string/detail/find_format_all.hpp +56 -56
- data/ext/boost/algorithm/string/detail/find_format_store.hpp +7 -0
- data/ext/boost/algorithm/string/detail/finder.hpp +14 -14
- data/ext/boost/algorithm/string/detail/formatter.hpp +2 -2
- data/ext/boost/algorithm/string/detail/replace_storage.hpp +3 -3
- data/ext/boost/algorithm/string/detail/sequence.hpp +3 -3
- data/ext/boost/algorithm/string/erase.hpp +98 -98
- data/ext/boost/algorithm/string/find_format.hpp +56 -38
- data/ext/boost/algorithm/string/finder.hpp +6 -6
- data/ext/boost/algorithm/string/formatter.hpp +1 -1
- data/ext/boost/algorithm/string/replace.hpp +99 -99
- data/ext/boost/bind.hpp +5 -1670
- data/ext/boost/bind/bind.hpp +1751 -0
- data/ext/boost/bind/bind_mf2_cc.hpp +228 -0
- data/ext/boost/bind/mem_fn.hpp +389 -0
- data/ext/boost/bind/mem_fn_template.hpp +54 -27
- data/ext/boost/bind/placeholders.hpp +3 -2
- data/ext/boost/concept_check.hpp +10 -0
- data/ext/boost/config/abi/msvc_prefix.hpp +15 -1
- data/ext/boost/config/abi_prefix.hpp +1 -1
- data/ext/boost/config/abi_suffix.hpp +3 -2
- data/ext/boost/config/auto_link.hpp +6 -1
- data/ext/boost/config/compiler/borland.hpp +75 -17
- data/ext/boost/config/compiler/codegear.hpp +163 -0
- data/ext/boost/config/compiler/common_edg.hpp +35 -0
- data/ext/boost/config/compiler/digitalmars.hpp +26 -0
- data/ext/boost/config/compiler/gcc.hpp +69 -14
- data/ext/boost/config/compiler/hp_acc.hpp +32 -0
- data/ext/boost/config/compiler/intel.hpp +13 -2
- data/ext/boost/config/compiler/kai.hpp +0 -2
- data/ext/boost/config/compiler/metrowerks.hpp +29 -1
- data/ext/boost/config/compiler/mpw.hpp +30 -0
- data/ext/boost/config/compiler/pgi.hpp +37 -0
- data/ext/boost/config/compiler/sgi_mipspro.hpp +1 -0
- data/ext/boost/config/compiler/sunpro_cc.hpp +39 -7
- data/ext/boost/config/compiler/vacpp.hpp +31 -3
- data/ext/boost/config/compiler/visualc.hpp +72 -5
- data/ext/boost/config/no_tr1/cmath.hpp +28 -0
- data/ext/boost/config/platform/bsd.hpp +16 -3
- data/ext/boost/config/platform/hpux.hpp +3 -0
- data/ext/boost/config/platform/macos.hpp +8 -0
- data/ext/boost/config/platform/solaris.hpp +7 -0
- data/ext/boost/config/platform/vxworks.hpp +31 -0
- data/ext/boost/config/select_compiler_config.hpp +4 -0
- data/ext/boost/config/select_platform_config.hpp +6 -2
- data/ext/boost/config/select_stdlib_config.hpp +17 -8
- data/ext/boost/config/stdlib/dinkumware.hpp +34 -2
- data/ext/boost/config/stdlib/libcomo.hpp +25 -0
- data/ext/boost/config/stdlib/libstdcpp3.hpp +56 -2
- data/ext/boost/config/stdlib/modena.hpp +25 -0
- data/ext/boost/config/stdlib/msl.hpp +24 -0
- data/ext/boost/config/stdlib/roguewave.hpp +26 -0
- data/ext/boost/config/stdlib/sgi.hpp +25 -0
- data/ext/boost/config/stdlib/stlport.hpp +36 -1
- data/ext/boost/config/stdlib/vacpp.hpp +25 -0
- data/ext/boost/config/suffix.hpp +67 -32
- data/ext/boost/config/warning_disable.hpp +47 -0
- data/ext/boost/cstdint.hpp +62 -36
- data/ext/boost/date_time/c_time.hpp +28 -12
- data/ext/boost/date_time/compiler_config.hpp +27 -5
- data/ext/boost/date_time/constrained_value.hpp +36 -13
- data/ext/boost/date_time/date.hpp +44 -33
- data/ext/boost/date_time/date_duration.hpp +13 -14
- data/ext/boost/date_time/date_facet.hpp +215 -226
- data/ext/boost/date_time/date_generator_formatter.hpp +22 -20
- data/ext/boost/date_time/date_generator_parser.hpp +52 -51
- data/ext/boost/date_time/date_generators.hpp +16 -16
- data/ext/boost/date_time/date_parsing.hpp +115 -98
- data/ext/boost/date_time/filetime_functions.hpp +133 -41
- data/ext/boost/date_time/format_date_parser.hpp +22 -10
- data/ext/boost/date_time/gregorian/conversion.hpp +32 -39
- data/ext/boost/date_time/gregorian/greg_calendar.hpp +15 -14
- data/ext/boost/date_time/gregorian/greg_date.hpp +19 -18
- data/ext/boost/date_time/gregorian/greg_duration.hpp +106 -10
- data/ext/boost/date_time/gregorian/greg_duration_types.hpp +16 -7
- data/ext/boost/date_time/gregorian/greg_weekday.hpp +2 -2
- data/ext/boost/date_time/gregorian/gregorian_io.hpp +11 -4
- data/ext/boost/date_time/gregorian_calendar.hpp +8 -8
- data/ext/boost/date_time/gregorian_calendar.ipp +30 -30
- data/ext/boost/date_time/int_adapter.hpp +4 -2
- data/ext/boost/date_time/microsec_time_clock.hpp +39 -117
- data/ext/boost/date_time/period_parser.hpp +17 -15
- data/ext/boost/date_time/posix_time/conversion.hpp +28 -29
- data/ext/boost/date_time/posix_time/posix_time_config.hpp +19 -19
- data/ext/boost/date_time/posix_time/posix_time_io.hpp +31 -38
- data/ext/boost/date_time/posix_time/time_formatters.hpp +32 -32
- data/ext/boost/date_time/string_parse_tree.hpp +46 -46
- data/ext/boost/date_time/strings_from_facet.hpp +7 -5
- data/ext/boost/date_time/time.hpp +7 -6
- data/ext/boost/date_time/time_defs.hpp +12 -2
- data/ext/boost/date_time/time_duration.hpp +27 -26
- data/ext/boost/date_time/time_facet.hpp +386 -321
- data/ext/boost/date_time/time_formatting_streams.hpp +8 -5
- data/ext/boost/date_time/time_resolution_traits.hpp +29 -25
- data/ext/boost/date_time/time_system_split.hpp +7 -13
- data/ext/boost/date_time/wrapping_int.hpp +21 -15
- data/ext/boost/detail/call_traits.hpp +1 -1
- data/ext/boost/detail/endian.hpp +4 -4
- data/ext/boost/detail/no_exceptions_support.hpp +87 -0
- data/ext/boost/detail/sp_typeinfo.hpp +50 -4
- data/ext/boost/detail/workaround.hpp +63 -3
- data/ext/boost/enable_shared_from_this.hpp +4 -59
- data/ext/boost/exception/current_exception_cast.hpp +43 -0
- data/ext/boost/exception/detail/attribute_noreturn.hpp +17 -0
- data/ext/boost/exception/detail/error_info_impl.hpp +75 -0
- data/ext/boost/exception/detail/exception_ptr.hpp +490 -0
- data/ext/boost/exception/detail/is_output_streamable.hpp +47 -0
- data/ext/boost/exception/detail/object_hex_dump.hpp +50 -0
- data/ext/boost/exception/detail/type_info.hpp +79 -0
- data/ext/boost/exception/diagnostic_information.hpp +182 -0
- data/ext/boost/exception/exception.hpp +422 -0
- data/ext/boost/exception/get_error_info.hpp +130 -0
- data/ext/boost/exception/info.hpp +167 -0
- data/ext/boost/exception/to_string.hpp +83 -0
- data/ext/boost/exception/to_string_stub.hpp +109 -0
- data/ext/boost/exception_ptr.hpp +11 -0
- data/ext/boost/function/detail/prologue.hpp +2 -1
- data/ext/boost/function/function_base.hpp +270 -128
- data/ext/boost/function/function_fwd.hpp +70 -0
- data/ext/boost/function/function_template.hpp +319 -130
- data/ext/boost/get_pointer.hpp +5 -1
- data/ext/boost/integer.hpp +253 -0
- data/ext/boost/integer_fwd.hpp +174 -0
- data/ext/boost/integer_traits.hpp +26 -1
- data/ext/boost/io/ios_state.hpp +8 -0
- data/ext/boost/iterator/detail/config_def.hpp +4 -2
- data/ext/boost/iterator/iterator_adaptor.hpp +7 -2
- data/ext/boost/iterator/iterator_facade.hpp +1 -2
- data/ext/boost/lexical_cast.hpp +113 -105
- data/ext/boost/limits.hpp +1 -1
- data/ext/boost/mem_fn.hpp +5 -370
- data/ext/boost/memory_order.hpp +53 -0
- data/ext/boost/mpl/always.hpp +3 -3
- data/ext/boost/mpl/and.hpp +3 -3
- data/ext/boost/mpl/apply.hpp +3 -3
- data/ext/boost/mpl/apply_fwd.hpp +3 -3
- data/ext/boost/mpl/apply_wrap.hpp +37 -6
- data/ext/boost/mpl/arg.hpp +3 -3
- data/ext/boost/mpl/arg_fwd.hpp +3 -3
- data/ext/boost/mpl/assert.hpp +6 -6
- data/ext/boost/mpl/aux_/adl_barrier.hpp +3 -3
- data/ext/boost/mpl/aux_/arg_typedef.hpp +3 -3
- data/ext/boost/mpl/aux_/arity.hpp +3 -3
- data/ext/boost/mpl/aux_/arity_spec.hpp +3 -3
- data/ext/boost/mpl/aux_/common_name_wknd.hpp +3 -3
- data/ext/boost/mpl/aux_/config/adl.hpp +4 -4
- data/ext/boost/mpl/aux_/config/arrays.hpp +4 -4
- data/ext/boost/mpl/aux_/config/bcc.hpp +28 -0
- data/ext/boost/mpl/aux_/config/bind.hpp +4 -4
- data/ext/boost/mpl/aux_/config/compiler.hpp +8 -6
- data/ext/boost/mpl/aux_/config/ctps.hpp +3 -3
- data/ext/boost/mpl/aux_/config/dtp.hpp +5 -5
- data/ext/boost/mpl/aux_/config/eti.hpp +3 -3
- data/ext/boost/mpl/aux_/config/gcc.hpp +3 -3
- data/ext/boost/mpl/aux_/config/has_apply.hpp +3 -3
- data/ext/boost/mpl/aux_/config/has_xxx.hpp +3 -3
- data/ext/boost/mpl/aux_/config/integral.hpp +4 -4
- data/ext/boost/mpl/aux_/config/intel.hpp +3 -3
- data/ext/boost/mpl/aux_/config/lambda.hpp +3 -3
- data/ext/boost/mpl/aux_/config/msvc.hpp +3 -3
- data/ext/boost/mpl/aux_/config/msvc_typename.hpp +3 -3
- data/ext/boost/mpl/aux_/config/nttp.hpp +3 -3
- data/ext/boost/mpl/aux_/config/overload_resolution.hpp +3 -3
- data/ext/boost/mpl/aux_/config/pp_counter.hpp +3 -3
- data/ext/boost/mpl/aux_/config/preprocessor.hpp +4 -4
- data/ext/boost/mpl/aux_/config/static_constant.hpp +3 -3
- data/ext/boost/mpl/aux_/config/ttp.hpp +4 -4
- data/ext/boost/mpl/aux_/config/use_preprocessed.hpp +3 -3
- data/ext/boost/mpl/aux_/config/workaround.hpp +3 -3
- data/ext/boost/mpl/aux_/full_lambda.hpp +3 -3
- data/ext/boost/mpl/aux_/has_apply.hpp +3 -3
- data/ext/boost/mpl/aux_/has_type.hpp +3 -3
- data/ext/boost/mpl/aux_/include_preprocessed.hpp +3 -3
- data/ext/boost/mpl/aux_/integral_wrapper.hpp +3 -3
- data/ext/boost/mpl/aux_/lambda_arity_param.hpp +3 -3
- data/ext/boost/mpl/aux_/lambda_support.hpp +4 -4
- data/ext/boost/mpl/aux_/msvc_never_true.hpp +3 -3
- data/ext/boost/mpl/aux_/na.hpp +3 -3
- data/ext/boost/mpl/aux_/na_assert.hpp +3 -3
- data/ext/boost/mpl/aux_/na_fwd.hpp +3 -3
- data/ext/boost/mpl/aux_/na_spec.hpp +3 -3
- data/ext/boost/mpl/aux_/nested_type_wknd.hpp +3 -3
- data/ext/boost/mpl/aux_/nttp_decl.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/def_params_tail.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/enum.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/filter_params.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/params.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/sub.hpp +3 -3
- data/ext/boost/mpl/aux_/static_cast.hpp +3 -3
- data/ext/boost/mpl/aux_/template_arity.hpp +3 -3
- data/ext/boost/mpl/aux_/template_arity_fwd.hpp +3 -3
- data/ext/boost/mpl/aux_/type_wrapper.hpp +3 -3
- data/ext/boost/mpl/aux_/value_wknd.hpp +3 -3
- data/ext/boost/mpl/aux_/yes_no.hpp +3 -3
- data/ext/boost/mpl/bind.hpp +3 -3
- data/ext/boost/mpl/bind_fwd.hpp +3 -3
- data/ext/boost/mpl/bool.hpp +3 -3
- data/ext/boost/mpl/bool_fwd.hpp +3 -3
- data/ext/boost/mpl/eval_if.hpp +3 -3
- data/ext/boost/mpl/has_xxx.hpp +10 -8
- data/ext/boost/mpl/identity.hpp +3 -3
- data/ext/boost/mpl/if.hpp +3 -3
- data/ext/boost/mpl/int.hpp +3 -3
- data/ext/boost/mpl/int_fwd.hpp +3 -3
- data/ext/boost/mpl/integral_c.hpp +3 -3
- data/ext/boost/mpl/integral_c_fwd.hpp +3 -3
- data/ext/boost/mpl/integral_c_tag.hpp +3 -3
- data/ext/boost/mpl/lambda.hpp +3 -3
- data/ext/boost/mpl/lambda_fwd.hpp +3 -3
- data/ext/boost/mpl/limits/arity.hpp +3 -3
- data/ext/boost/mpl/logical.hpp +3 -3
- data/ext/boost/mpl/next.hpp +3 -3
- data/ext/boost/mpl/next_prior.hpp +3 -3
- data/ext/boost/mpl/not.hpp +3 -3
- data/ext/boost/mpl/or.hpp +3 -3
- data/ext/boost/mpl/placeholders.hpp +3 -3
- data/ext/boost/mpl/protect.hpp +3 -3
- data/ext/boost/mpl/quote.hpp +18 -7
- data/ext/boost/mpl/size_t.hpp +3 -3
- data/ext/boost/mpl/size_t_fwd.hpp +3 -3
- data/ext/boost/mpl/void.hpp +3 -3
- data/ext/boost/mpl/void_fwd.hpp +3 -3
- data/ext/boost/non_type.hpp +27 -27
- data/ext/boost/operators.hpp +51 -18
- data/ext/boost/preprocessor/arithmetic/detail/div_base.hpp +61 -0
- data/ext/boost/preprocessor/arithmetic/mod.hpp +39 -0
- data/ext/boost/preprocessor/comparison/less_equal.hpp +39 -0
- data/ext/boost/preprocessor/control/deduce_d.hpp +22 -0
- data/ext/boost/preprocessor/logical/not.hpp +30 -0
- data/ext/boost/preprocessor/seq/cat.hpp +48 -0
- data/ext/boost/preprocessor/seq/fold_left.hpp +1070 -0
- data/ext/boost/preprocessor/seq/transform.hpp +48 -0
- data/ext/boost/range/as_literal.hpp +10 -14
- data/ext/boost/range/begin.hpp +4 -4
- data/ext/boost/range/detail/implementation_help.hpp +4 -0
- data/ext/boost/range/end.hpp +4 -4
- data/ext/boost/range/iterator_range.hpp +31 -15
- data/ext/boost/ref.hpp +12 -1
- data/ext/boost/scoped_array.hpp +16 -0
- data/ext/boost/scoped_ptr.hpp +16 -0
- data/ext/boost/shared_ptr.hpp +2 -602
- data/ext/boost/{detail → smart_ptr}/bad_weak_ptr.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count.hpp +14 -19
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_gcc.hpp +13 -9
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_gcc_x86.hpp +5 -12
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_pthreads.hpp +5 -5
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_solaris.hpp +3 -3
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_sync.hpp +9 -5
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_win32.hpp +3 -3
- data/ext/boost/smart_ptr/detail/operator_bool.hpp +56 -0
- data/ext/boost/{detail → smart_ptr/detail}/shared_count.hpp +86 -17
- data/ext/boost/smart_ptr/detail/sp_convertible.hpp +76 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +70 -0
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_acc_ia64.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_cw_ppc.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_cw_x86.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_ia64.hpp +4 -4
- data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +172 -0
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_ppc.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_sparc.hpp +7 -7
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_x86.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_nt.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_pt.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_solaris.hpp +4 -4
- data/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp +131 -0
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_sync.hpp +8 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_w32.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_impl.hpp +5 -5
- data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +49 -0
- data/ext/boost/smart_ptr/detail/spinlock.hpp +53 -0
- data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +85 -0
- data/ext/boost/smart_ptr/detail/spinlock_nt.hpp +89 -0
- data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +87 -0
- data/ext/boost/smart_ptr/detail/spinlock_pt.hpp +79 -0
- data/ext/boost/smart_ptr/detail/spinlock_sync.hpp +87 -0
- data/ext/boost/smart_ptr/detail/yield_k.hpp +149 -0
- data/ext/boost/smart_ptr/enable_shared_from_this.hpp +79 -0
- data/ext/boost/smart_ptr/scoped_array.hpp +107 -0
- data/ext/boost/smart_ptr/scoped_ptr.hpp +131 -0
- data/ext/boost/smart_ptr/shared_ptr.hpp +701 -0
- data/ext/boost/smart_ptr/weak_ptr.hpp +230 -0
- data/ext/boost/src/pthread/thread.cpp +115 -203
- data/ext/boost/src/tss_null.cpp +1 -1
- data/ext/boost/static_assert.hpp +14 -4
- data/ext/boost/thread.hpp +7 -2
- data/ext/boost/thread/barrier.hpp +63 -0
- data/ext/boost/thread/detail/force_cast.hpp +39 -0
- data/ext/boost/thread/detail/move.hpp +29 -2
- data/ext/boost/thread/detail/platform.hpp +3 -3
- data/ext/boost/thread/detail/singleton.hpp +59 -0
- data/ext/boost/thread/detail/thread.hpp +496 -0
- data/ext/boost/thread/detail/thread_group.hpp +105 -0
- data/ext/boost/thread/detail/thread_heap_alloc.hpp +23 -0
- data/ext/boost/thread/detail/thread_interruption.hpp +35 -0
- data/ext/boost/thread/detail/tss_hooks.hpp +82 -0
- data/ext/boost/thread/exceptions.hpp +174 -60
- data/ext/boost/thread/future.hpp +1364 -0
- data/ext/boost/thread/locks.hpp +899 -32
- data/ext/boost/thread/once.hpp +4 -0
- data/ext/boost/thread/pthread/condition_variable.hpp +16 -21
- data/ext/boost/thread/pthread/condition_variable_fwd.hpp +37 -3
- data/ext/boost/thread/pthread/mutex.hpp +20 -7
- data/ext/boost/thread/pthread/once.hpp +7 -2
- data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +5 -1
- data/ext/boost/thread/pthread/recursive_mutex.hpp +22 -5
- data/ext/boost/thread/pthread/shared_mutex.hpp +303 -0
- data/ext/boost/thread/pthread/thread_data.hpp +37 -10
- data/ext/boost/thread/pthread/thread_heap_alloc.hpp +242 -0
- data/ext/boost/thread/pthread/timespec.hpp +11 -3
- data/ext/boost/thread/shared_mutex.hpp +21 -0
- data/ext/boost/thread/thread.hpp +8 -3
- data/ext/boost/thread/thread_time.hpp +4 -0
- data/ext/boost/thread/tss.hpp +106 -13
- data/ext/boost/thread/xtime.hpp +6 -2
- data/ext/boost/throw_exception.hpp +36 -7
- data/ext/boost/token_functions.hpp +1 -1
- data/ext/boost/tokenizer.hpp +1 -1
- data/ext/boost/type_traits/add_pointer.hpp +1 -1
- data/ext/boost/type_traits/add_volatile.hpp +47 -0
- data/ext/boost/type_traits/alignment_of.hpp +29 -1
- data/ext/boost/type_traits/config.hpp +1 -1
- data/ext/boost/type_traits/conversion_traits.hpp +1 -1
- data/ext/boost/type_traits/has_trivial_destructor.hpp +42 -0
- data/ext/boost/type_traits/intrinsics.hpp +88 -1
- data/ext/boost/type_traits/is_abstract.hpp +14 -5
- data/ext/boost/type_traits/is_arithmetic.hpp +8 -0
- data/ext/boost/type_traits/is_array.hpp +3 -2
- data/ext/boost/type_traits/is_base_and_derived.hpp +254 -0
- data/ext/boost/type_traits/is_base_of.hpp +51 -0
- data/ext/boost/type_traits/is_class.hpp +12 -0
- data/ext/boost/type_traits/is_const.hpp +6 -2
- data/ext/boost/type_traits/is_convertible.hpp +14 -2
- data/ext/boost/type_traits/is_enum.hpp +10 -1
- data/ext/boost/type_traits/is_function.hpp +11 -3
- data/ext/boost/type_traits/is_fundamental.hpp +45 -0
- data/ext/boost/type_traits/is_integral.hpp +5 -0
- data/ext/boost/type_traits/is_member_function_pointer.hpp +5 -3
- data/ext/boost/type_traits/is_member_pointer.hpp +4 -2
- data/ext/boost/type_traits/is_pointer.hpp +3 -1
- data/ext/boost/type_traits/is_reference.hpp +4 -2
- data/ext/boost/type_traits/is_signed.hpp +135 -0
- data/ext/boost/type_traits/is_unsigned.hpp +130 -0
- data/ext/boost/type_traits/is_void.hpp +5 -0
- data/ext/boost/type_traits/is_volatile.hpp +4 -2
- data/ext/boost/type_traits/make_unsigned.hpp +137 -0
- data/ext/boost/type_traits/remove_reference.hpp +1 -1
- data/ext/boost/type_traits/type_with_alignment.hpp +106 -1
- data/ext/boost/utility.hpp +2 -1
- data/ext/boost/utility/addressof.hpp +61 -17
- data/ext/boost/utility/binary.hpp +708 -0
- data/ext/boost/utility/enable_if.hpp +2 -2
- data/ext/boost/weak_ptr.hpp +4 -174
- data/ext/common/AbstractSpawnManager.h +110 -0
- data/ext/common/Account.h +175 -0
- data/ext/common/AccountsDatabase.cpp +81 -0
- data/ext/common/AccountsDatabase.h +130 -0
- data/ext/common/AgentBase.cpp +323 -0
- data/ext/common/{Version.h → AgentBase.h} +14 -6
- data/ext/common/AgentsStarter.cpp +154 -0
- data/ext/common/AgentsStarter.h +81 -0
- data/ext/common/AgentsStarter.hpp +619 -0
- data/ext/common/ApplicationPool/Client.h +796 -0
- data/ext/common/{ApplicationPool.h → ApplicationPool/Interface.h} +108 -18
- data/ext/common/ApplicationPool/Pool.h +1315 -0
- data/ext/common/ApplicationPool/Server.h +475 -0
- data/ext/common/BCrypt.cpp +343 -0
- data/ext/common/BCrypt.h +73 -0
- data/ext/common/Blowfish.c +685 -0
- data/ext/common/Blowfish.h +103 -0
- data/ext/common/Constants.h +48 -0
- data/ext/common/EventedClient.h +598 -0
- data/ext/common/EventedMessageServer.h +327 -0
- data/ext/common/EventedServer.h +295 -0
- data/ext/common/Exceptions.h +78 -1
- data/ext/common/FileDescriptor.h +229 -0
- data/ext/common/HelperAgent/BacktracesServer.h +59 -0
- data/ext/common/Logging.cpp +8 -9
- data/ext/common/Logging.h +593 -21
- data/ext/common/LoggingAgent/ChangeNotifier.h +63 -0
- data/ext/common/LoggingAgent/DataStoreId.h +177 -0
- data/ext/common/LoggingAgent/LoggingServer.h +1343 -0
- data/ext/common/LoggingAgent/Main.cpp +278 -0
- data/ext/common/LoggingAgent/RemoteSender.h +457 -0
- data/ext/common/MessageChannel.h +196 -34
- data/ext/common/MessageClient.h +297 -0
- data/ext/common/MessageReadersWriters.h +508 -0
- data/ext/common/MessageServer.h +575 -0
- data/ext/common/PoolOptions.h +279 -117
- data/ext/common/Process.h +255 -0
- data/ext/common/RandomGenerator.h +160 -0
- data/ext/common/ResourceLocator.h +84 -0
- data/ext/common/ServerInstanceDir.h +343 -0
- data/ext/common/Session.h +470 -0
- data/ext/common/SpawnManager.h +256 -201
- data/ext/common/StaticString.h +79 -4
- data/ext/common/StringListCreator.h +2 -2
- data/ext/common/Utils.cpp +385 -397
- data/ext/common/Utils.h +79 -165
- data/ext/common/{Base64.cpp → Utils/Base64.cpp} +0 -0
- data/ext/common/{Base64.h → Utils/Base64.h} +27 -1
- data/ext/common/Utils/BlockingQueue.h +136 -0
- data/ext/common/Utils/BlockingScalar.h +50 -0
- data/ext/common/{CachedFileStat.cpp → Utils/CachedFileStat.cpp} +1 -1
- data/ext/common/{CachedFileStat.h → Utils/CachedFileStat.h} +1 -1
- data/ext/common/{CachedFileStat.hpp → Utils/CachedFileStat.hpp} +1 -1
- data/ext/common/{FileChangeChecker.h → Utils/FileChangeChecker.h} +1 -1
- data/ext/common/Utils/FileHandleGuard.h +81 -0
- data/ext/common/Utils/IOUtils.cpp +754 -0
- data/ext/common/Utils/IOUtils.h +253 -0
- data/ext/common/Utils/MD5.cpp +406 -0
- data/ext/common/Utils/MD5.h +98 -0
- data/ext/common/Utils/MemZeroGuard.h +103 -0
- data/ext/common/Utils/ProcessMetricsCollector.h +462 -0
- data/ext/common/Utils/ScopeGuard.h +72 -0
- data/ext/common/Utils/StrIntUtils.cpp +329 -0
- data/ext/common/Utils/StrIntUtils.h +228 -0
- data/ext/common/{SystemTime.cpp → Utils/SystemTime.cpp} +5 -1
- data/ext/common/Utils/SystemTime.h +201 -0
- data/ext/common/{Timer.h → Utils/Timer.h} +58 -18
- data/ext/common/Utils/VariantMap.h +363 -0
- data/ext/common/Utils/foo.cpp +10 -0
- data/ext/common/Watchdog.cpp +1034 -0
- data/ext/google/COPYING +28 -0
- data/ext/google/ChangeLog +167 -0
- data/ext/google/dense_hash_map +310 -0
- data/ext/google/dense_hash_set +287 -0
- data/ext/google/sparse_hash_map +294 -0
- data/ext/google/sparse_hash_set +275 -0
- data/ext/google/sparsehash/densehashtable.h +1062 -0
- data/ext/google/sparsehash/sparseconfig.h +55 -0
- data/ext/google/sparsehash/sparsehashtable.h +1015 -0
- data/ext/google/sparsetable +1468 -0
- data/ext/google/type_traits.h +250 -0
- data/ext/libev/Changes +302 -0
- data/ext/libev/LICENSE +36 -0
- data/ext/libev/Makefile.am +18 -0
- data/ext/libev/Makefile.in +685 -0
- data/ext/libev/README +58 -0
- data/ext/libev/aclocal.m4 +7549 -0
- data/ext/libev/autogen.sh +6 -0
- data/ext/libev/config.guess +1526 -0
- data/ext/libev/config.h +122 -0
- data/ext/libev/config.h.in +121 -0
- data/ext/libev/config.sub +1658 -0
- data/ext/libev/configure +22156 -0
- data/ext/libev/configure.ac +18 -0
- data/ext/libev/ev++.h +800 -0
- data/ext/libev/ev.c +3694 -0
- data/ext/libev/ev.h +705 -0
- data/ext/libev/ev_epoll.c +228 -0
- data/ext/libev/ev_kqueue.c +196 -0
- data/ext/libev/ev_poll.c +144 -0
- data/ext/libev/ev_port.c +165 -0
- data/ext/libev/ev_select.c +308 -0
- data/ext/libev/ev_vars.h +187 -0
- data/ext/libev/ev_win32.c +153 -0
- data/ext/libev/ev_wrap.h +178 -0
- data/ext/libev/event.c +401 -0
- data/ext/libev/event.h +158 -0
- data/ext/libev/install-sh +294 -0
- data/ext/libev/libev.m4 +38 -0
- data/ext/libev/ltmain.sh +6871 -0
- data/ext/libev/missing +336 -0
- data/ext/libev/mkinstalldirs +111 -0
- data/ext/nginx/Configuration.c +532 -182
- data/ext/nginx/Configuration.h +33 -10
- data/ext/nginx/ContentHandler.c +188 -53
- data/ext/nginx/ContentHandler.h +1 -1
- data/ext/nginx/{HelperServer.cpp → HelperAgent.cpp} +433 -299
- data/ext/nginx/HttpStatusExtractor.h +1 -1
- data/ext/nginx/ScgiRequestParser.h +68 -11
- data/ext/nginx/StaticContentHandler.c +4 -1
- data/ext/nginx/StaticContentHandler.h +1 -1
- data/ext/nginx/config +5 -5
- data/ext/nginx/ngx_http_passenger_module.c +315 -469
- data/ext/nginx/ngx_http_passenger_module.h +8 -17
- data/ext/oxt/backtrace.cpp +49 -41
- data/ext/oxt/backtrace.hpp +1 -1
- data/ext/oxt/detail/backtrace_disabled.hpp +1 -1
- data/ext/oxt/detail/backtrace_enabled.hpp +16 -15
- data/ext/oxt/detail/spin_lock_darwin.hpp +69 -0
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -4
- data/ext/oxt/detail/spin_lock_portable.hpp +1 -1
- data/ext/oxt/detail/spin_lock_pthreads.hpp +1 -1
- data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
- data/ext/oxt/detail/tracable_exception_enabled.hpp +1 -1
- data/ext/oxt/dynamic_thread_group.hpp +195 -0
- data/ext/oxt/macros.hpp +1 -1
- data/ext/oxt/spin_lock.hpp +4 -2
- data/ext/oxt/system_calls.cpp +129 -13
- data/ext/oxt/system_calls.hpp +16 -2
- data/ext/oxt/thread.cpp +1 -1
- data/ext/oxt/thread.hpp +49 -14
- data/ext/oxt/tracable_exception.cpp +5 -5
- data/ext/oxt/tracable_exception.hpp +1 -1
- data/ext/phusion_passenger/extconf.rb +7 -2
- data/ext/phusion_passenger/native_support.c +733 -33
- data/{bin → helper-scripts}/passenger-spawn-server +50 -12
- data/helper-scripts/prespawn +63 -0
- data/lib/phusion_passenger.rb +113 -0
- data/lib/phusion_passenger/abstract_installer.rb +50 -12
- data/lib/phusion_passenger/abstract_request_handler.rb +432 -171
- data/lib/phusion_passenger/abstract_server.rb +125 -122
- data/lib/phusion_passenger/abstract_server_collection.rb +51 -22
- data/lib/phusion_passenger/admin_tools.rb +1 -1
- data/lib/phusion_passenger/admin_tools/memory_stats.rb +299 -0
- data/lib/phusion_passenger/admin_tools/server_instance.rb +334 -0
- data/lib/phusion_passenger/analytics_logger.rb +342 -0
- data/lib/phusion_passenger/{application.rb → app_process.rb} +73 -24
- data/lib/phusion_passenger/classic_rails/application_spawner.rb +344 -0
- data/lib/phusion_passenger/{railz → classic_rails}/cgi_fixed.rb +2 -2
- data/lib/phusion_passenger/{railz → classic_rails}/framework_spawner.rb +75 -98
- data/lib/phusion_passenger/{railz → classic_rails}/request_handler.rb +8 -6
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_base_extension.rb +65 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_benchmarking_extension.rb +48 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_rescue_extension.rb +59 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ar_abstract_adapter_extension.rb +54 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/as_cache_extension.rb +130 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/av_benchmark_helper_extension.rb +47 -0
- data/lib/phusion_passenger/classic_rails_extensions/init.rb +123 -0
- data/lib/phusion_passenger/console_text_template.rb +1 -1
- data/lib/phusion_passenger/constants.rb +9 -5
- data/lib/phusion_passenger/debug_logging.rb +104 -0
- data/lib/phusion_passenger/dependencies.rb +187 -4
- data/lib/phusion_passenger/exceptions.rb +4 -4
- data/lib/phusion_passenger/html_template.rb +6 -8
- data/lib/phusion_passenger/message_channel.rb +137 -21
- data/lib/phusion_passenger/message_client.rb +173 -0
- data/lib/phusion_passenger/native_support.rb +108 -0
- data/lib/phusion_passenger/packaging.rb +82 -13
- data/lib/phusion_passenger/platform_info.rb +84 -475
- data/lib/phusion_passenger/platform_info/apache.rb +329 -0
- data/lib/phusion_passenger/platform_info/binary_compatibility.rb +187 -0
- data/lib/phusion_passenger/platform_info/compiler.rb +154 -0
- data/lib/phusion_passenger/{events.rb → platform_info/curl.rb} +26 -23
- data/lib/phusion_passenger/platform_info/documentation_tools.rb +35 -0
- data/lib/phusion_passenger/platform_info/linux.rb +77 -0
- data/lib/phusion_passenger/platform_info/operating_system.rb +51 -0
- data/lib/phusion_passenger/platform_info/ruby.rb +198 -0
- data/lib/phusion_passenger/platform_info/zlib.rb +38 -0
- data/lib/phusion_passenger/plugin.rb +96 -0
- data/lib/phusion_passenger/public_api.rb +112 -0
- data/lib/phusion_passenger/rack/application_spawner.rb +146 -71
- data/lib/phusion_passenger/rack/request_handler.rb +36 -13
- data/lib/phusion_passenger/rails3_extensions/init.rb +204 -0
- data/lib/phusion_passenger/simple_benchmarking.rb +1 -1
- data/lib/phusion_passenger/spawn_manager.rb +137 -141
- data/lib/phusion_passenger/standalone/app_finder.rb +153 -0
- data/lib/phusion_passenger/standalone/command.rb +237 -0
- data/lib/phusion_passenger/standalone/config_file.rb +119 -0
- data/lib/phusion_passenger/standalone/help_command.rb +57 -0
- data/lib/phusion_passenger/standalone/main.rb +101 -0
- data/lib/phusion_passenger/standalone/package_runtime_command.rb +92 -0
- data/lib/phusion_passenger/standalone/runtime_installer.rb +466 -0
- data/lib/phusion_passenger/standalone/start_command.rb +510 -0
- data/lib/phusion_passenger/standalone/status_command.rb +62 -0
- data/lib/phusion_passenger/standalone/stop_command.rb +74 -0
- data/lib/phusion_passenger/standalone/utils.rb +42 -0
- data/lib/phusion_passenger/standalone/version_command.rb +42 -0
- data/lib/phusion_passenger/templates/framework_init_error.html.erb +1 -1
- data/lib/phusion_passenger/templates/standalone/cannot_write_to_dir.txt.erb +11 -0
- data/lib/phusion_passenger/templates/standalone/config.erb +69 -0
- data/lib/phusion_passenger/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +17 -0
- data/lib/phusion_passenger/templates/standalone/run_installer_as_root.txt.erb +8 -0
- data/lib/phusion_passenger/templates/standalone/welcome.txt.erb +8 -0
- data/lib/phusion_passenger/templates/standalone_default_root/index.html +1 -0
- data/lib/phusion_passenger/templates/version_not_found.html.erb +2 -2
- data/lib/phusion_passenger/utils.rb +476 -125
- data/lib/phusion_passenger/utils/file_system_watcher.rb +186 -0
- data/lib/phusion_passenger/utils/hosts_file_parser.rb +130 -0
- data/lib/phusion_passenger/utils/tmpdir.rb +70 -0
- data/lib/phusion_passenger/utils/unseekable_socket.rb +196 -0
- data/lib/phusion_passenger/wsgi/application_spawner.rb +24 -20
- data/lib/phusion_passenger/wsgi/request_handler.py +1 -1
- data/misc/copy_boost_headers.rb +36 -9
- data/misc/find_owner_pipe_leaks.rb +1 -1
- data/misc/render_error_pages.rb +1 -1
- data/misc/union_station_gateway.crt +32 -0
- data/test/config.yml.example +24 -13
- data/test/cxx/ApplicationPool_PoolTest.cpp +33 -0
- data/test/cxx/ApplicationPool_PoolTestCases.cpp +1029 -0
- data/test/cxx/ApplicationPool_ServerTest.cpp +308 -0
- data/test/cxx/ApplicationPool_Server_PoolTest.cpp +80 -0
- data/test/{Base64Test.cpp → cxx/Base64Test.cpp} +4 -2
- data/test/{CachedFileStatTest.cpp → cxx/CachedFileStatTest.cpp} +3 -3
- data/test/{CxxTestMain.cpp → cxx/CxxTestMain.cpp} +6 -27
- data/test/cxx/EventedClientTest.cpp +386 -0
- data/test/{FileChangeCheckerTest.cpp → cxx/FileChangeCheckerTest.cpp} +3 -5
- data/test/cxx/FileDescriptorTest.cpp +69 -0
- data/test/{HttpStatusExtractorTest.cpp → cxx/HttpStatusExtractorTest.cpp} +1 -1
- data/test/cxx/IOUtilsTest.cpp +398 -0
- data/test/cxx/LoggingTest.cpp +914 -0
- data/test/cxx/MessageChannelTest.cpp +672 -0
- data/test/cxx/MessageReadersWritersTest.cpp +574 -0
- data/test/cxx/MessageServerTest.cpp +383 -0
- data/test/{PoolOptionsTest.cpp → cxx/PoolOptionsTest.cpp} +2 -3
- data/test/{ScgiRequestParserTest.cpp → cxx/ScgiRequestParserTest.cpp} +53 -1
- data/test/cxx/ServerInstanceDirTest.cpp +186 -0
- data/test/cxx/SpawnManagerTest.cpp +161 -0
- data/test/cxx/StaticStringTest.cpp +86 -0
- data/test/{SystemTimeTest.cpp → cxx/SystemTimeTest.cpp} +2 -2
- data/test/cxx/TestSupport.cpp +166 -0
- data/test/cxx/TestSupport.h +254 -0
- data/test/cxx/UtilsTest.cpp +521 -0
- data/test/cxx/VariantMapTest.cpp +179 -0
- data/test/integration_tests/apache2_tests.rb +198 -127
- data/test/integration_tests/cgi_environment_spec.rb +26 -0
- data/test/integration_tests/mycook_spec.rb +2 -28
- data/test/integration_tests/nginx_tests.rb +125 -16
- data/test/integration_tests/spec_helper.rb +19 -0
- data/test/oxt/backtrace_test.cpp +19 -59
- data/test/oxt/counter.hpp +55 -0
- data/test/oxt/dynamic_thread_group_test.cpp +131 -0
- data/test/oxt/oxt_test_main.cpp +2 -2
- data/test/oxt/spin_lock_test.cpp +59 -0
- data/test/oxt/syscall_interruption_test.cpp +1 -1
- data/test/ruby/abstract_request_handler_spec.rb +346 -25
- data/test/ruby/abstract_server_collection_spec.rb +4 -3
- data/test/ruby/abstract_server_spec.rb +37 -27
- data/test/ruby/admin_tools_spec.rb +362 -0
- data/test/ruby/analytics_logger_spec.rb +253 -0
- data/test/ruby/{application_spec.rb → app_process_spec.rb} +14 -14
- data/test/ruby/classic_rails/application_spawner_spec.rb +89 -0
- data/test/ruby/classic_rails/framework_spawner_spec.rb +92 -0
- data/test/ruby/debug_logging_spec.rb +141 -0
- data/test/ruby/message_channel_spec.rb +51 -25
- data/test/ruby/rack/application_spawner_spec.rb +99 -82
- data/test/ruby/shared/abstract_server_spec.rb +23 -0
- data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +375 -0
- data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +38 -0
- data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +19 -0
- data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +15 -0
- data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +27 -0
- data/test/ruby/shared/spawners/preloading_spawner_spec.rb +29 -0
- data/test/ruby/shared/spawners/reload_all_spec.rb +36 -0
- data/test/ruby/shared/spawners/reload_single_spec.rb +52 -0
- data/test/ruby/shared/spawners/spawn_server_spec.rb +28 -0
- data/test/ruby/shared/spawners/spawner_spec.rb +273 -0
- data/test/ruby/shared/utils/pseudo_io_spec.rb +60 -0
- data/test/ruby/spawn_manager_spec.rb +104 -175
- data/test/ruby/spec_helper.rb +104 -0
- data/test/ruby/utils/file_system_watcher_spec.rb +221 -0
- data/test/ruby/utils/hosts_file_parser.rb +258 -0
- data/test/ruby/utils/unseekable_socket_spec.rb +66 -0
- data/test/ruby/utils_spec.rb +410 -59
- data/test/ruby/wsgi/application_spawner_spec.rb +16 -20
- data/test/stub/apache2/httpd.conf.erb +11 -6
- data/test/stub/message_channel.rb +3 -1
- data/test/stub/message_channel_2.rb +3 -1
- data/test/stub/message_channel_3.rb +5 -3
- data/test/stub/nginx/nginx.conf.erb +3 -2
- data/test/stub/rails_apps/1.2/empty/Rakefile +10 -0
- data/test/stub/rails_apps/1.2/empty/app/controllers/application.rb +7 -0
- data/test/stub/rails_apps/{foobar → 1.2/empty}/app/helpers/application_helper.rb +0 -0
- data/test/stub/rails_apps/{mycook → 1.2/empty}/config/boot.rb +3 -3
- data/test/stub/rails_apps/1.2/empty/config/database.yml +31 -0
- data/test/stub/rails_apps/1.2/empty/config/environment.rb +66 -0
- data/test/stub/rails_apps/1.2/empty/config/environments/development.rb +21 -0
- data/test/stub/rails_apps/{foobar → 1.2/empty}/config/environments/production.rb +0 -0
- data/test/stub/rails_apps/1.2/empty/config/environments/staging.rb +18 -0
- data/test/stub/rails_apps/1.2/empty/config/environments/test.rb +19 -0
- data/test/stub/rails_apps/1.2/empty/config/routes.rb +23 -0
- data/test/stub/rails_apps/1.2/empty/doc/README_FOR_APP +2 -0
- data/test/stub/rails_apps/{mycook → 1.2/empty}/public/404.html +0 -0
- data/test/stub/rails_apps/1.2/empty/public/500.html +30 -0
- data/test/stub/rails_apps/1.2/empty/public/dispatch.cgi +10 -0
- data/test/stub/rails_apps/1.2/empty/public/dispatch.fcgi +24 -0
- data/test/stub/rails_apps/1.2/empty/public/dispatch.rb +10 -0
- data/test/stub/rails_apps/{mycook → 1.2/empty}/public/favicon.ico +0 -0
- data/test/stub/rails_apps/{mycook → 1.2/empty}/public/images/rails.png +0 -0
- data/test/stub/rails_apps/1.2/empty/public/robots.txt +1 -0
- data/test/stub/rails_apps/1.2/empty/script/about +3 -0
- data/test/stub/rails_apps/1.2/empty/script/breakpointer +3 -0
- data/test/stub/rails_apps/1.2/empty/script/console +3 -0
- data/test/stub/rails_apps/1.2/empty/script/destroy +3 -0
- data/test/stub/rails_apps/1.2/empty/script/generate +3 -0
- data/test/stub/rails_apps/1.2/empty/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/1.2/empty/script/performance/profiler +3 -0
- data/test/stub/rails_apps/1.2/empty/script/plugin +3 -0
- data/test/stub/rails_apps/1.2/empty/script/process/inspector +3 -0
- data/test/stub/rails_apps/1.2/empty/script/process/reaper +3 -0
- data/test/stub/rails_apps/1.2/empty/script/process/spawner +3 -0
- data/test/stub/rails_apps/1.2/empty/script/runner +3 -0
- data/test/stub/rails_apps/1.2/empty/script/server +3 -0
- data/test/stub/rails_apps/1.2/empty/test/test_helper.rb +28 -0
- data/test/stub/rails_apps/2.0/empty/Rakefile +10 -0
- data/test/stub/rails_apps/2.0/empty/app/controllers/application.rb +10 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/app/helpers/application_helper.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.0/empty}/config/boot.rb +3 -3
- data/test/stub/rails_apps/2.0/empty/config/database.yml +31 -0
- data/test/stub/rails_apps/2.0/empty/config/environment.rb +59 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/config/environments/development.rb +1 -1
- data/test/stub/rails_apps/2.0/empty/config/environments/production.rb +18 -0
- data/test/stub/rails_apps/2.0/empty/config/environments/staging.rb +18 -0
- data/test/stub/rails_apps/2.0/empty/config/environments/test.rb +22 -0
- data/test/stub/rails_apps/{foobar → 2.0/empty}/config/initializers/inflections.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.0/empty}/config/initializers/mime_types.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.0/empty}/config/routes.rb +0 -0
- data/test/stub/rails_apps/2.0/empty/doc/README_FOR_APP +2 -0
- data/test/stub/rails_apps/2.0/empty/public/404.html +30 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/public/422.html +0 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/public/500.html +0 -0
- data/test/stub/rails_apps/2.0/empty/public/dispatch.cgi +10 -0
- data/test/stub/rails_apps/2.0/empty/public/dispatch.fcgi +24 -0
- data/test/stub/rails_apps/2.0/empty/public/dispatch.rb +10 -0
- data/test/stub/rails_apps/2.0/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.0/empty/public/images/rails.png +0 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/public/robots.txt +0 -0
- data/test/stub/rails_apps/2.0/empty/script/about +3 -0
- data/test/stub/rails_apps/2.0/empty/script/console +3 -0
- data/test/stub/rails_apps/2.0/empty/script/destroy +3 -0
- data/test/stub/rails_apps/2.0/empty/script/generate +3 -0
- data/test/stub/rails_apps/2.0/empty/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.0/empty/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.0/empty/script/performance/request +3 -0
- data/test/stub/rails_apps/2.0/empty/script/plugin +3 -0
- data/test/stub/rails_apps/2.0/empty/script/process/inspector +3 -0
- data/test/stub/rails_apps/2.0/empty/script/process/reaper +3 -0
- data/test/stub/rails_apps/2.0/empty/script/process/spawner +3 -0
- data/test/stub/rails_apps/2.0/empty/script/runner +3 -0
- data/test/stub/rails_apps/2.0/empty/script/server +3 -0
- data/test/stub/rails_apps/2.0/empty/test/test_helper.rb +38 -0
- data/test/stub/rails_apps/2.2/empty/Rakefile +10 -0
- data/test/stub/rails_apps/2.2/empty/app/controllers/application.rb +15 -0
- data/test/stub/rails_apps/2.2/empty/app/helpers/application_helper.rb +3 -0
- data/test/stub/rails_apps/2.2/empty/config/boot.rb +109 -0
- data/test/stub/rails_apps/2.2/empty/config/database.yml +31 -0
- data/test/stub/rails_apps/2.2/empty/config/environment.rb +75 -0
- data/test/stub/rails_apps/{foobar → 2.2/empty}/config/environments/development.rb +0 -0
- data/test/stub/rails_apps/2.2/empty/config/environments/production.rb +24 -0
- data/test/stub/rails_apps/2.2/empty/config/environments/staging.rb +24 -0
- data/test/stub/rails_apps/2.2/empty/config/environments/test.rb +22 -0
- data/test/stub/rails_apps/2.2/empty/config/initializers/inflections.rb +10 -0
- data/test/stub/rails_apps/{mycook → 2.2/empty}/config/initializers/mime_types.rb +0 -0
- data/test/stub/rails_apps/2.2/empty/config/initializers/new_rails_defaults.rb +17 -0
- data/test/stub/rails_apps/2.2/empty/config/locales/en.yml +5 -0
- data/test/stub/rails_apps/2.2/empty/config/routes.rb +43 -0
- data/test/stub/rails_apps/2.2/empty/doc/README_FOR_APP +5 -0
- data/test/stub/rails_apps/2.2/empty/public/404.html +30 -0
- data/test/stub/rails_apps/2.2/empty/public/422.html +30 -0
- data/test/stub/rails_apps/2.2/empty/public/500.html +33 -0
- data/test/stub/rails_apps/2.2/empty/public/dispatch.cgi +10 -0
- data/test/stub/rails_apps/2.2/empty/public/dispatch.fcgi +24 -0
- data/test/stub/rails_apps/2.2/empty/public/dispatch.rb +10 -0
- data/test/stub/rails_apps/2.2/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.2/empty/public/images/rails.png +0 -0
- data/test/stub/rails_apps/2.2/empty/public/robots.txt +5 -0
- data/test/stub/rails_apps/2.2/empty/script/about +4 -0
- data/test/stub/rails_apps/2.2/empty/script/console +3 -0
- data/test/stub/rails_apps/2.2/empty/script/dbconsole +3 -0
- data/test/stub/rails_apps/2.2/empty/script/destroy +3 -0
- data/test/stub/rails_apps/2.2/empty/script/generate +3 -0
- data/test/stub/rails_apps/2.2/empty/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.2/empty/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.2/empty/script/performance/request +3 -0
- data/test/stub/rails_apps/2.2/empty/script/plugin +3 -0
- data/test/stub/rails_apps/2.2/empty/script/process/inspector +3 -0
- data/test/stub/rails_apps/2.2/empty/script/process/reaper +3 -0
- data/test/stub/rails_apps/2.2/empty/script/process/spawner +3 -0
- data/test/stub/rails_apps/2.2/empty/script/runner +3 -0
- data/test/stub/rails_apps/2.2/empty/script/server +3 -0
- data/test/stub/rails_apps/2.2/empty/test/performance/browsing_test.rb +9 -0
- data/test/stub/rails_apps/2.2/empty/test/test_helper.rb +38 -0
- data/test/stub/rails_apps/2.3/empty/Rakefile +10 -0
- data/test/stub/rails_apps/2.3/empty/app/controllers/application_controller.rb +10 -0
- data/test/stub/rails_apps/2.3/empty/app/helpers/application_helper.rb +3 -0
- data/test/stub/rails_apps/2.3/empty/config/boot.rb +110 -0
- data/test/stub/rails_apps/2.3/empty/config/database.yml +31 -0
- data/test/stub/rails_apps/2.3/empty/config/environment.rb +41 -0
- data/test/stub/rails_apps/2.3/empty/config/environments/development.rb +17 -0
- data/test/stub/rails_apps/2.3/empty/config/environments/production.rb +28 -0
- data/test/stub/rails_apps/2.3/empty/config/environments/staging.rb +28 -0
- data/test/stub/rails_apps/2.3/empty/config/environments/test.rb +28 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/backtrace_silencers.rb +7 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/inflections.rb +10 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/mime_types.rb +5 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/new_rails_defaults.rb +21 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/session_store.rb +15 -0
- data/test/stub/rails_apps/2.3/empty/config/locales/en.yml +5 -0
- data/test/stub/rails_apps/2.3/empty/config/routes.rb +43 -0
- data/test/stub/rails_apps/2.3/empty/db/seeds.rb +7 -0
- data/test/stub/rails_apps/2.3/empty/doc/README_FOR_APP +2 -0
- data/test/stub/rails_apps/2.3/empty/public/404.html +30 -0
- data/test/stub/rails_apps/2.3/empty/public/422.html +30 -0
- data/test/stub/rails_apps/2.3/empty/public/500.html +30 -0
- data/test/stub/rails_apps/2.3/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.3/empty/public/images/rails.png +0 -0
- data/test/stub/rails_apps/2.3/empty/public/robots.txt +5 -0
- data/test/stub/rails_apps/2.3/empty/script/about +4 -0
- data/test/stub/rails_apps/2.3/empty/script/console +3 -0
- data/test/stub/rails_apps/2.3/empty/script/dbconsole +3 -0
- data/test/stub/rails_apps/2.3/empty/script/destroy +3 -0
- data/test/stub/rails_apps/2.3/empty/script/generate +3 -0
- data/test/stub/rails_apps/2.3/empty/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.3/empty/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.3/empty/script/plugin +3 -0
- data/test/stub/rails_apps/2.3/empty/script/runner +3 -0
- data/test/stub/rails_apps/2.3/empty/script/server +3 -0
- data/test/stub/rails_apps/2.3/empty/test/performance/browsing_test.rb +9 -0
- data/test/stub/rails_apps/2.3/empty/test/test_helper.rb +38 -0
- data/test/stub/rails_apps/2.3/foobar/Rakefile +10 -0
- data/test/stub/rails_apps/{foobar/app/controllers/application.rb → 2.3/foobar/app/controllers/application_controller.rb} +0 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/app/controllers/bar_controller_1.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/app/controllers/bar_controller_2.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/app/controllers/foo_controller.rb +0 -0
- data/test/stub/rails_apps/2.3/foobar/app/helpers/application_helper.rb +3 -0
- data/test/stub/rails_apps/2.3/foobar/config/boot.rb +110 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/config/database.yml +0 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/config/environment.rb +1 -1
- data/test/stub/rails_apps/2.3/foobar/config/environments/development.rb +17 -0
- data/test/stub/rails_apps/2.3/foobar/config/environments/production.rb +18 -0
- data/test/stub/rails_apps/2.3/foobar/config/environments/staging.rb +18 -0
- data/test/stub/rails_apps/{mycook → 2.3/foobar}/config/initializers/inflections.rb +0 -0
- data/test/stub/rails_apps/2.3/foobar/config/initializers/mime_types.rb +5 -0
- data/test/stub/rails_apps/2.3/foobar/config/routes.rb +35 -0
- data/test/stub/rails_apps/2.3/foobar/script/about +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/console +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/dbconsole +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/destroy +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/generate +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/performance/request +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/plugin +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/process/inspector +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/process/reaper +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/process/spawner +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/runner +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/server +3 -0
- data/test/stub/rails_apps/2.3/mycook/Rakefile +10 -0
- data/test/stub/rails_apps/{mycook/app/controllers/application.rb → 2.3/mycook/app/controllers/application_controller.rb} +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/controllers/recipes_controller.rb +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/controllers/uploads_controller.rb +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/controllers/welcome_controller.rb +0 -0
- data/test/stub/rails_apps/2.3/mycook/app/helpers/application_helper.rb +3 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/layouts/default.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/recipes/create.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/recipes/index.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/recipes/new.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/uploads/index.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/uploads/new.html.erb +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/welcome/cached.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/welcome/index.rhtml +0 -0
- data/test/stub/rails_apps/2.3/mycook/config/boot.rb +110 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/database.yml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/environment.rb +1 -1
- data/test/stub/rails_apps/2.3/mycook/config/environments/development.rb +18 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/environments/production.rb +0 -0
- data/test/stub/rails_apps/2.3/mycook/config/initializers/inflections.rb +10 -0
- data/test/stub/rails_apps/2.3/mycook/config/initializers/mime_types.rb +5 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/routes.rb +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/log/useless.txt +0 -0
- data/test/stub/rails_apps/2.3/mycook/public/404.html +30 -0
- data/test/stub/rails_apps/2.3/mycook/public/422.html +30 -0
- data/test/stub/rails_apps/2.3/mycook/public/500.html +30 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/dispatch.cgi +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/dispatch.fcgi +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/dispatch.rb +1 -1
- data/test/stub/rails_apps/2.3/mycook/public/favicon.ico +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/images/angrywizard.gif +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/images/cookbook.gif +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/images/header.png +0 -0
- data/test/stub/rails_apps/2.3/mycook/public/images/rails.png +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/application.js +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/controls.js +73 -73
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/dragdrop.js +166 -165
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/effects.js +174 -166
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/prototype.js +362 -267
- data/test/stub/rails_apps/2.3/mycook/public/robots.txt +5 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/uploads.html +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/welcome/cached.html +0 -0
- data/test/stub/rails_apps/2.3/mycook/script/about +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/console +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/dbconsole +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/destroy +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/generate +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/performance/request +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/plugin +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/process/inspector +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/process/reaper +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/process/spawner +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/runner +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/server +3 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/sites/some.site/public/uploads.html +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/sites/some.site/public/welcome/cached.html +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/cache/useless.txt +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/pids/useless.txt +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/sessions/useless.txt +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/sockets/useless.txt +0 -0
- data/test/stub/rails_apps/3.0/empty/Gemfile +22 -0
- data/test/stub/rails_apps/3.0/empty/Rakefile +10 -0
- data/test/stub/rails_apps/3.0/empty/app/controllers/application_controller.rb +4 -0
- data/test/stub/rails_apps/3.0/empty/app/helpers/application_helper.rb +2 -0
- data/test/stub/rails_apps/3.0/empty/app/views/layouts/application.html.erb +14 -0
- data/test/stub/rails_apps/3.0/empty/config.ru +4 -0
- data/test/stub/rails_apps/3.0/empty/config/application.rb +48 -0
- data/test/stub/rails_apps/3.0/empty/config/boot.rb +13 -0
- data/test/stub/rails_apps/3.0/empty/config/database.yml +22 -0
- data/test/stub/rails_apps/3.0/empty/config/environment.rb +5 -0
- data/test/stub/rails_apps/3.0/empty/config/environments/development.rb +19 -0
- data/test/stub/rails_apps/3.0/empty/config/environments/production.rb +48 -0
- data/test/stub/rails_apps/3.0/empty/config/environments/test.rb +32 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/backtrace_silencers.rb +7 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/inflections.rb +10 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/mime_types.rb +5 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/passenger.rb +1 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/secret_token.rb +7 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/session_store.rb +8 -0
- data/test/stub/rails_apps/3.0/empty/config/locales/en.yml +5 -0
- data/test/stub/rails_apps/3.0/empty/config/routes.rb +58 -0
- data/test/stub/rails_apps/3.0/empty/db/seeds.rb +7 -0
- data/test/stub/rails_apps/3.0/empty/doc/README_FOR_APP +2 -0
- data/test/stub/rails_apps/3.0/empty/log/development.log +3 -0
- data/test/stub/rails_apps/3.0/empty/public/404.html +26 -0
- data/test/stub/rails_apps/3.0/empty/public/422.html +26 -0
- data/test/stub/rails_apps/3.0/empty/public/500.html +26 -0
- data/test/stub/rails_apps/3.0/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/3.0/empty/public/index.html +279 -0
- data/test/stub/rails_apps/3.0/empty/public/robots.txt +5 -0
- data/test/stub/rails_apps/3.0/empty/script/rails +9 -0
- data/test/stub/rails_apps/3.0/empty/test/performance/browsing_test.rb +9 -0
- data/test/stub/rails_apps/3.0/empty/test/test_helper.rb +13 -0
- data/test/stub/spawn_server.rb +4 -2
- data/test/stub/vendor_rails/minimal/actionpack/lib/action_controller.rb +3 -0
- data/test/stub/vendor_rails/minimal/railties/lib/initializer.rb +7 -2
- data/test/support/apache2_controller.rb +10 -2
- data/test/support/nginx_controller.rb +3 -2
- data/test/support/test_helper.rb +282 -46
- data/test/{support → tut}/tut.h +6 -0
- data/test/{support → tut}/tut_reporter.h +0 -0
- metadata +824 -266
- data/benchmark/ApplicationPool.cpp +0 -52
- data/benchmark/accept_vs_socketpair_vs_named_pipes.rb +0 -126
- data/benchmark/dispatcher.rb +0 -42
- data/benchmark/overhead_of_password_checking.rb +0 -81
- data/benchmark/socket_connections_vs_persistent_pipe.rb +0 -99
- data/benchmark/unix_sockets_vs_pipes.rb +0 -83
- data/ext/boost/LICENSE.TXT +0 -23
- data/ext/boost/VERSION.TXT +0 -1
- data/ext/boost/detail/sp_counted_base.hpp +0 -81
- data/ext/boost/src/pthread/exceptions.cpp +0 -146
- data/ext/boost/src/win32/exceptions.cpp +0 -124
- data/ext/boost/src/win32/thread.cpp +0 -629
- data/ext/boost/src/win32/timeconv.inl +0 -130
- data/ext/boost/src/win32/tss_dll.cpp +0 -72
- data/ext/boost/src/win32/tss_pe.cpp +0 -269
- data/ext/boost/thread/pthread/thread.hpp +0 -339
- data/ext/boost/thread/pthread/tss.hpp +0 -103
- data/ext/common/Application.h +0 -511
- data/ext/common/ApplicationPoolServer.h +0 -794
- data/ext/common/ApplicationPoolServerExecutable.cpp +0 -743
- data/ext/common/ApplicationPoolStatusReporter.h +0 -336
- data/ext/common/DummySpawnManager.h +0 -108
- data/ext/common/StandardApplicationPool.h +0 -821
- data/ext/common/SystemTime.h +0 -88
- data/lib/phusion_passenger/admin_tools/control_process.rb +0 -150
- data/lib/phusion_passenger/railz/application_spawner.rb +0 -463
- data/lib/phusion_passenger/templates/invalid_app_root.html.erb +0 -9
- data/test/ApplicationPoolServerTest.cpp +0 -114
- data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +0 -33
- data/test/ApplicationPoolTest.cpp +0 -599
- data/test/MessageChannelTest.cpp +0 -320
- data/test/SpawnManagerTest.cpp +0 -64
- data/test/StandardApplicationPoolTest.cpp +0 -27
- data/test/StaticStringTest.cpp +0 -51
- data/test/UtilsTest.cpp +0 -257
- data/test/ruby/rails/application_spawner_spec.rb +0 -159
- data/test/ruby/rails/framework_spawner_spec.rb +0 -133
- data/test/ruby/rails/minimal_spawner_spec.rb +0 -93
- data/test/ruby/rails/spawner_error_handling_spec.rb +0 -107
- data/test/ruby/rails/spawner_privilege_lowering_spec.rb +0 -97
- data/test/ruby/spawn_server_spec.rb +0 -26
- data/test/stub/MessageServer.dSYM/Contents/Info.plist +0 -25
- data/test/stub/MessageServer.dSYM/Contents/Resources/DWARF/MessageServer +0 -0
- data/test/support/Support.cpp +0 -84
- data/test/support/Support.h +0 -118
- data/test/support/config.rb +0 -38
- data/test/support/run_rspec_tests.rb +0 -10
@@ -0,0 +1,63 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - http://www.modrails.com/
|
3
|
+
* Copyright (c) 2010 Phusion
|
4
|
+
*
|
5
|
+
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
12
|
+
* furnished to do so, subject to the following conditions:
|
13
|
+
*
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
15
|
+
* all copies or substantial portions of the Software.
|
16
|
+
*
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
* THE SOFTWARE.
|
24
|
+
*/
|
25
|
+
#ifndef _PASSENGER_CHANGE_NOTIFIER_H_
|
26
|
+
#define _PASSENGER_CHANGE_NOTIFIER_H_
|
27
|
+
|
28
|
+
#include <boost/function.hpp>
|
29
|
+
#include <boost/shared_ptr.hpp>
|
30
|
+
#include <string>
|
31
|
+
#include <ev++.h>
|
32
|
+
#include "DataStoreId.h"
|
33
|
+
#include "../EventedClient.h"
|
34
|
+
#include "../FileDescriptor.h"
|
35
|
+
#include "../StaticString.h"
|
36
|
+
|
37
|
+
namespace Passenger {
|
38
|
+
|
39
|
+
using namespace std;
|
40
|
+
using namespace boost;
|
41
|
+
|
42
|
+
|
43
|
+
class ChangeNotifier {
|
44
|
+
public:
|
45
|
+
typedef function<string (const StaticString &groupName, const StaticString &nodeName,
|
46
|
+
const StaticString &category)> GetLastPosFunction;
|
47
|
+
|
48
|
+
GetLastPosFunction getLastPos;
|
49
|
+
|
50
|
+
ChangeNotifier(struct ev_loop *_loop) { }
|
51
|
+
virtual ~ChangeNotifier() { }
|
52
|
+
|
53
|
+
virtual void addClient(const FileDescriptor &fd) { }
|
54
|
+
|
55
|
+
virtual void changed(const DataStoreId &dataStoreId) { }
|
56
|
+
};
|
57
|
+
|
58
|
+
typedef shared_ptr<ChangeNotifier> ChangeNotifierPtr;
|
59
|
+
|
60
|
+
|
61
|
+
} // namespace Passenger
|
62
|
+
|
63
|
+
#endif /* _PASSENGER_CHANGE_NOTIFIER_H_ */
|
@@ -0,0 +1,177 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - http://www.modrails.com/
|
3
|
+
* Copyright (c) 2010 Phusion
|
4
|
+
*
|
5
|
+
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
12
|
+
* furnished to do so, subject to the following conditions:
|
13
|
+
*
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
15
|
+
* all copies or substantial portions of the Software.
|
16
|
+
*
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
* THE SOFTWARE.
|
24
|
+
*/
|
25
|
+
#ifndef _PASSENGER_DATA_STORE_ID_H_
|
26
|
+
#define _PASSENGER_DATA_STORE_ID_H_
|
27
|
+
|
28
|
+
#include <cstring>
|
29
|
+
#include <climits>
|
30
|
+
#include <cassert>
|
31
|
+
#include "StaticString.h"
|
32
|
+
|
33
|
+
namespace Passenger {
|
34
|
+
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Efficient representation for a (groupName, nodeName, category) tuple.
|
38
|
+
*/
|
39
|
+
class DataStoreId {
|
40
|
+
private:
|
41
|
+
char *id;
|
42
|
+
unsigned short groupNameSize;
|
43
|
+
unsigned short nodeNameSize;
|
44
|
+
unsigned short categorySize;
|
45
|
+
|
46
|
+
size_t totalSize() const {
|
47
|
+
return groupNameSize + nodeNameSize + categorySize + 3;
|
48
|
+
}
|
49
|
+
|
50
|
+
StaticString toStaticString() const {
|
51
|
+
if (id == NULL) {
|
52
|
+
return StaticString();
|
53
|
+
} else {
|
54
|
+
return StaticString(id, totalSize());
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
public:
|
59
|
+
DataStoreId(const StaticString &groupName, const StaticString &nodeName,
|
60
|
+
const StaticString &category)
|
61
|
+
{
|
62
|
+
assert(groupName.size() <= USHRT_MAX);
|
63
|
+
assert(nodeName.size() <= USHRT_MAX);
|
64
|
+
assert(category.size() <= USHRT_MAX);
|
65
|
+
|
66
|
+
char *end;
|
67
|
+
|
68
|
+
id = new char[groupName.size() + nodeName.size() +
|
69
|
+
category.size() + 3];
|
70
|
+
end = id;
|
71
|
+
|
72
|
+
memcpy(end, groupName.c_str(), groupName.size());
|
73
|
+
groupNameSize = groupName.size();
|
74
|
+
end += groupName.size();
|
75
|
+
*end = '\0';
|
76
|
+
end++;
|
77
|
+
|
78
|
+
memcpy(end, nodeName.c_str(), nodeName.size());
|
79
|
+
nodeNameSize = nodeName.size();
|
80
|
+
end += nodeName.size();
|
81
|
+
*end = '\0';
|
82
|
+
end++;
|
83
|
+
|
84
|
+
memcpy(end, category.c_str(), category.size());
|
85
|
+
categorySize = category.size();
|
86
|
+
end += category.size();
|
87
|
+
*end = '\0';
|
88
|
+
}
|
89
|
+
|
90
|
+
DataStoreId() {
|
91
|
+
id = NULL;
|
92
|
+
}
|
93
|
+
|
94
|
+
DataStoreId(const DataStoreId &other) {
|
95
|
+
if (other.id == NULL) {
|
96
|
+
id = NULL;
|
97
|
+
} else {
|
98
|
+
id = new char[other.totalSize()];
|
99
|
+
memcpy(id, other.id, other.totalSize());
|
100
|
+
groupNameSize = other.groupNameSize;
|
101
|
+
nodeNameSize = other.nodeNameSize;
|
102
|
+
categorySize = other.categorySize;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
~DataStoreId() {
|
107
|
+
delete id;
|
108
|
+
}
|
109
|
+
|
110
|
+
DataStoreId &operator=(const DataStoreId &other) {
|
111
|
+
if (other.id == NULL) {
|
112
|
+
delete id;
|
113
|
+
id = NULL;
|
114
|
+
return *this;
|
115
|
+
} else {
|
116
|
+
if (totalSize() != other.totalSize()) {
|
117
|
+
delete id;
|
118
|
+
id = NULL;
|
119
|
+
}
|
120
|
+
if (id == NULL) {
|
121
|
+
id = new char[other.totalSize()];
|
122
|
+
}
|
123
|
+
memcpy(id, other.id, other.totalSize());
|
124
|
+
groupNameSize = other.groupNameSize;
|
125
|
+
nodeNameSize = other.nodeNameSize;
|
126
|
+
categorySize = other.categorySize;
|
127
|
+
return *this;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
bool operator<(const DataStoreId &other) const {
|
132
|
+
return toStaticString() < other.toStaticString();
|
133
|
+
}
|
134
|
+
|
135
|
+
bool operator==(const DataStoreId &other) const {
|
136
|
+
if (id == NULL) {
|
137
|
+
return other.id == NULL;
|
138
|
+
} else {
|
139
|
+
if (other.id == NULL) {
|
140
|
+
return false;
|
141
|
+
} else {
|
142
|
+
return toStaticString() == other.toStaticString();
|
143
|
+
}
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
StaticString getGroupName() const {
|
148
|
+
if (id != NULL) {
|
149
|
+
return StaticString(id, groupNameSize);
|
150
|
+
} else {
|
151
|
+
return StaticString();
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
StaticString getNodeName() const {
|
156
|
+
if (id != NULL) {
|
157
|
+
return StaticString(id + groupNameSize + 1,
|
158
|
+
nodeNameSize);
|
159
|
+
} else {
|
160
|
+
return StaticString();
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
StaticString getCategory() const {
|
165
|
+
if (id != NULL) {
|
166
|
+
return StaticString(id + groupNameSize + 1 + nodeNameSize + 1,
|
167
|
+
categorySize);
|
168
|
+
} else {
|
169
|
+
return StaticString();
|
170
|
+
}
|
171
|
+
}
|
172
|
+
};
|
173
|
+
|
174
|
+
|
175
|
+
} // namespace Passenger
|
176
|
+
|
177
|
+
#endif /* _PASSENGER_DATA_STORE_ID_H_ */
|
@@ -0,0 +1,1343 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - http://www.modrails.com/
|
3
|
+
* Copyright (c) 2010 Phusion
|
4
|
+
*
|
5
|
+
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
12
|
+
* furnished to do so, subject to the following conditions:
|
13
|
+
*
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
15
|
+
* all copies or substantial portions of the Software.
|
16
|
+
*
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
* THE SOFTWARE.
|
24
|
+
*/
|
25
|
+
#ifndef _PASSENGER_LOGGING_SERVER_H_
|
26
|
+
#define _PASSENGER_LOGGING_SERVER_H_
|
27
|
+
|
28
|
+
#include <oxt/system_calls.hpp>
|
29
|
+
#include <oxt/macros.hpp>
|
30
|
+
#include <boost/shared_ptr.hpp>
|
31
|
+
#include <string>
|
32
|
+
#include <ostream>
|
33
|
+
#include <sstream>
|
34
|
+
#include <map>
|
35
|
+
#include <ev++.h>
|
36
|
+
|
37
|
+
#include <sys/types.h>
|
38
|
+
#include <sys/time.h>
|
39
|
+
#include <sys/stat.h>
|
40
|
+
#include <grp.h>
|
41
|
+
#include <cstring>
|
42
|
+
#include <ctime>
|
43
|
+
#include <cassert>
|
44
|
+
|
45
|
+
#include "DataStoreId.h"
|
46
|
+
#include "RemoteSender.h"
|
47
|
+
#include "ChangeNotifier.h"
|
48
|
+
#include "../EventedMessageServer.h"
|
49
|
+
#include "../MessageReadersWriters.h"
|
50
|
+
#include "../StaticString.h"
|
51
|
+
#include "../Exceptions.h"
|
52
|
+
#include "../MessageChannel.h"
|
53
|
+
#include "../Constants.h"
|
54
|
+
#include "../Utils.h"
|
55
|
+
#include "../Utils/MD5.h"
|
56
|
+
#include "../Utils/IOUtils.h"
|
57
|
+
#include "../Utils/StrIntUtils.h"
|
58
|
+
|
59
|
+
|
60
|
+
namespace Passenger {
|
61
|
+
|
62
|
+
using namespace std;
|
63
|
+
using namespace boost;
|
64
|
+
using namespace oxt;
|
65
|
+
|
66
|
+
|
67
|
+
class LoggingServer: public EventedMessageServer {
|
68
|
+
private:
|
69
|
+
static const int MAX_LOG_SINK_CACHE_SIZE = 512;
|
70
|
+
static const int GARBAGE_COLLECTION_TIMEOUT = 1.25 * 60 * 60; // 1 hour 15 minutes
|
71
|
+
|
72
|
+
struct LogSink;
|
73
|
+
typedef shared_ptr<LogSink> LogSinkPtr;
|
74
|
+
typedef map<string, LogSinkPtr> LogSinkCache;
|
75
|
+
|
76
|
+
struct LogSink {
|
77
|
+
LoggingServer *server;
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Marks how many times this LogSink is currently opened, i.e. the
|
81
|
+
* number of Transaction objects currently referencing this LogSink.
|
82
|
+
* @invariant
|
83
|
+
* (opened == 0) == (this LogSink is in LoggingServer.inactiveLogSinks)
|
84
|
+
*/
|
85
|
+
int opened;
|
86
|
+
|
87
|
+
/** Last time this LogSink hit an open count of 0. */
|
88
|
+
ev_tstamp lastUsed;
|
89
|
+
|
90
|
+
/** Last time data was actually written to the underlying storage device. */
|
91
|
+
ev_tstamp lastFlushed;
|
92
|
+
|
93
|
+
/**
|
94
|
+
* This LogSink's iterator inside LoggingServer.logSinkCache.
|
95
|
+
*/
|
96
|
+
LogSinkCache::iterator cacheIterator;
|
97
|
+
|
98
|
+
/**
|
99
|
+
* This LogSink's iterator inside LoggingServer.inactiveLogSinks.
|
100
|
+
* Only valid when opened == 0.
|
101
|
+
*/
|
102
|
+
list<LogSinkPtr>::iterator inactiveLogSinksIterator;
|
103
|
+
|
104
|
+
LogSink(LoggingServer *_server) {
|
105
|
+
server = _server;
|
106
|
+
opened = 0;
|
107
|
+
lastUsed = ev_now(server->getLoop());
|
108
|
+
lastFlushed = 0;
|
109
|
+
}
|
110
|
+
|
111
|
+
virtual ~LogSink() {
|
112
|
+
// We really want to flush() here but can't call virtual
|
113
|
+
// functions in destructor. :(
|
114
|
+
}
|
115
|
+
|
116
|
+
virtual bool isRemote() const {
|
117
|
+
return false;
|
118
|
+
}
|
119
|
+
|
120
|
+
virtual void append(const DataStoreId &dataStoreId,
|
121
|
+
const StaticString &data) = 0;
|
122
|
+
virtual void flush() { }
|
123
|
+
virtual void dump(ostream &stream) const { }
|
124
|
+
};
|
125
|
+
|
126
|
+
struct LogFile: public LogSink {
|
127
|
+
static const unsigned int BUFFER_CAPACITY = 8 * 1024;
|
128
|
+
|
129
|
+
string filename;
|
130
|
+
FileDescriptor fd;
|
131
|
+
char buffer[BUFFER_CAPACITY];
|
132
|
+
unsigned int bufferSize;
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Contains every (groupName, nodeName, category) tuple for
|
136
|
+
* which their data is currently buffered in this sink.
|
137
|
+
*/
|
138
|
+
set<DataStoreId> dataStoreIds;
|
139
|
+
|
140
|
+
LogFile(LoggingServer *server, const string &filename, mode_t filePermissions)
|
141
|
+
: LogSink(server)
|
142
|
+
{
|
143
|
+
int ret;
|
144
|
+
|
145
|
+
bufferSize = 0;
|
146
|
+
|
147
|
+
this->filename = filename;
|
148
|
+
fd = syscalls::open(filename.c_str(),
|
149
|
+
O_CREAT | O_WRONLY | O_APPEND,
|
150
|
+
filePermissions);
|
151
|
+
if (fd == -1) {
|
152
|
+
int e = errno;
|
153
|
+
throw FileSystemException("Cannnot open file", e, filename);
|
154
|
+
}
|
155
|
+
do {
|
156
|
+
ret = fchmod(fd, filePermissions);
|
157
|
+
} while (ret == -1 && errno == EINTR);
|
158
|
+
}
|
159
|
+
|
160
|
+
virtual ~LogFile() {
|
161
|
+
flush();
|
162
|
+
}
|
163
|
+
|
164
|
+
void notifyChanges() {
|
165
|
+
if (server->changeNotifier != NULL) {
|
166
|
+
set<DataStoreId>::const_iterator it;
|
167
|
+
set<DataStoreId>::const_iterator end = dataStoreIds.end();
|
168
|
+
|
169
|
+
for (it = dataStoreIds.begin(); it != dataStoreIds.end(); it++) {
|
170
|
+
server->changeNotifier->changed(*it);
|
171
|
+
}
|
172
|
+
}
|
173
|
+
dataStoreIds.clear();
|
174
|
+
}
|
175
|
+
|
176
|
+
virtual void append(const DataStoreId &dataStoreId, const StaticString &data) {
|
177
|
+
if (server->changeNotifier != NULL) {
|
178
|
+
dataStoreIds.insert(dataStoreId);
|
179
|
+
}
|
180
|
+
if (bufferSize + data.size() > BUFFER_CAPACITY) {
|
181
|
+
StaticString data2[2];
|
182
|
+
data2[0] = StaticString(buffer, bufferSize);
|
183
|
+
data2[1] = data;
|
184
|
+
|
185
|
+
gatheredWrite(fd, data2, 2);
|
186
|
+
lastFlushed = ev_now(server->getLoop());
|
187
|
+
bufferSize = 0;
|
188
|
+
notifyChanges();
|
189
|
+
} else {
|
190
|
+
memcpy(buffer + bufferSize, data.data(), data.size());
|
191
|
+
bufferSize += data.size();
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
virtual void flush() {
|
196
|
+
if (bufferSize > 0) {
|
197
|
+
lastFlushed = ev_now(server->getLoop());
|
198
|
+
MessageChannel(fd).writeRaw(StaticString(buffer, bufferSize));
|
199
|
+
bufferSize = 0;
|
200
|
+
notifyChanges();
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
virtual void dump(ostream &stream) const {
|
205
|
+
stream << " Log file: file=" << filename << ", "
|
206
|
+
"opened=" << opened << ", "
|
207
|
+
"age=" << long(ev_now(server->getLoop()) - lastUsed) << "\n";
|
208
|
+
}
|
209
|
+
};
|
210
|
+
|
211
|
+
typedef shared_ptr<LogFile> LogFilePtr;
|
212
|
+
|
213
|
+
struct RemoteSink: public LogSink {
|
214
|
+
/* RemoteSender compresses the data with zlib before sending it
|
215
|
+
* to the server. Even including Base64 and URL encoding overhead,
|
216
|
+
* this compresses the data to about 25% of its original size.
|
217
|
+
* Therefore we set a buffer capacity of a little less than 4 times
|
218
|
+
* the TCP maximum segment size so that we can send as much
|
219
|
+
* data as possible to the server in a single TCP segment.
|
220
|
+
* With the "little less" we take into account:
|
221
|
+
* - HTTPS overhead. This can be as high as 2 KB.
|
222
|
+
* - The fact that RemoteSink.append() might try to flush the
|
223
|
+
* current buffer the current data. Empirical evidence has
|
224
|
+
* shown that the data for a request transaction is usually
|
225
|
+
* less than 5 KB.
|
226
|
+
*/
|
227
|
+
static const unsigned int BUFFER_CAPACITY =
|
228
|
+
4 * 64 * 1024 -
|
229
|
+
16 * 1024;
|
230
|
+
|
231
|
+
string unionStationKey;
|
232
|
+
string nodeName;
|
233
|
+
string category;
|
234
|
+
char buffer[BUFFER_CAPACITY];
|
235
|
+
unsigned int bufferSize;
|
236
|
+
|
237
|
+
RemoteSink(LoggingServer *server, const string &unionStationKey,
|
238
|
+
const string &nodeName, const string &category)
|
239
|
+
: LogSink(server)
|
240
|
+
{
|
241
|
+
this->unionStationKey = unionStationKey;
|
242
|
+
this->nodeName = nodeName;
|
243
|
+
this->category = category;
|
244
|
+
this->bufferSize = 0;
|
245
|
+
}
|
246
|
+
|
247
|
+
virtual ~RemoteSink() {
|
248
|
+
flush();
|
249
|
+
}
|
250
|
+
|
251
|
+
virtual bool isRemote() const {
|
252
|
+
return true;
|
253
|
+
}
|
254
|
+
|
255
|
+
virtual void append(const DataStoreId &dataStoreId, const StaticString &data) {
|
256
|
+
if (bufferSize + data.size() > BUFFER_CAPACITY) {
|
257
|
+
StaticString data2[2];
|
258
|
+
data2[0] = StaticString(buffer, bufferSize);
|
259
|
+
data2[1] = data;
|
260
|
+
|
261
|
+
server->remoteSender.schedule(unionStationKey, nodeName,
|
262
|
+
category, data2, 2);
|
263
|
+
lastFlushed = ev_now(server->getLoop());
|
264
|
+
bufferSize = 0;
|
265
|
+
} else {
|
266
|
+
memcpy(buffer + bufferSize, data.data(), data.size());
|
267
|
+
bufferSize += data.size();
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
virtual void flush() {
|
272
|
+
if (bufferSize > 0) {
|
273
|
+
lastFlushed = ev_now(server->getLoop());
|
274
|
+
StaticString data(buffer, bufferSize);
|
275
|
+
server->remoteSender.schedule(unionStationKey, nodeName,
|
276
|
+
category, &data, 1);
|
277
|
+
bufferSize = 0;
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
virtual void dump(ostream &stream) const {
|
282
|
+
stream << " Remote sink: "
|
283
|
+
"key=" << unionStationKey << ", "
|
284
|
+
"node=" << nodeName << ", "
|
285
|
+
"category=" << category << ", "
|
286
|
+
"opened=" << opened << ", "
|
287
|
+
"age=" << long(ev_now(server->getLoop()) - lastUsed) << ", "
|
288
|
+
"bufferSize=" << bufferSize <<
|
289
|
+
"\n";
|
290
|
+
}
|
291
|
+
};
|
292
|
+
|
293
|
+
struct Transaction {
|
294
|
+
LoggingServer *server;
|
295
|
+
LogSinkPtr logSink;
|
296
|
+
string txnId;
|
297
|
+
DataStoreId dataStoreId;
|
298
|
+
unsigned int writeCount;
|
299
|
+
int refcount;
|
300
|
+
bool crashProtect, discarded;
|
301
|
+
string data;
|
302
|
+
|
303
|
+
Transaction(LoggingServer *server) {
|
304
|
+
this->server = server;
|
305
|
+
data.reserve(8 * 1024);
|
306
|
+
}
|
307
|
+
|
308
|
+
~Transaction() {
|
309
|
+
if (logSink != NULL) {
|
310
|
+
if (!discarded) {
|
311
|
+
logSink->append(dataStoreId, data);
|
312
|
+
}
|
313
|
+
server->closeLogSink(logSink);
|
314
|
+
}
|
315
|
+
}
|
316
|
+
|
317
|
+
StaticString getGroupName() const {
|
318
|
+
return dataStoreId.getGroupName();
|
319
|
+
}
|
320
|
+
|
321
|
+
StaticString getNodeName() const {
|
322
|
+
return dataStoreId.getNodeName();
|
323
|
+
}
|
324
|
+
|
325
|
+
StaticString getCategory() const {
|
326
|
+
return dataStoreId.getCategory();
|
327
|
+
}
|
328
|
+
|
329
|
+
void discard() {
|
330
|
+
data.clear();
|
331
|
+
discarded = true;
|
332
|
+
}
|
333
|
+
|
334
|
+
void dump(ostream &stream) const {
|
335
|
+
stream << " Transaction " << txnId << ":\n";
|
336
|
+
stream << " Group : " << getGroupName() << "\n";
|
337
|
+
stream << " Node : " << getNodeName() << "\n";
|
338
|
+
stream << " Category: " << getCategory() << "\n";
|
339
|
+
stream << " Refcount: " << refcount << "\n";
|
340
|
+
}
|
341
|
+
};
|
342
|
+
|
343
|
+
typedef shared_ptr<Transaction> TransactionPtr;
|
344
|
+
|
345
|
+
enum ClientType {
|
346
|
+
UNINITIALIZED,
|
347
|
+
LOGGER,
|
348
|
+
WATCHER
|
349
|
+
};
|
350
|
+
|
351
|
+
struct Client: public EventedMessageClient {
|
352
|
+
string nodeName;
|
353
|
+
ClientType type;
|
354
|
+
char nodeId[MD5_HEX_SIZE];
|
355
|
+
/**
|
356
|
+
* Set of transaction IDs opened by this client.
|
357
|
+
* @invariant This is a subset of the transaction IDs in the 'transactions' member.
|
358
|
+
*/
|
359
|
+
set<string> openTransactions;
|
360
|
+
ScalarMessage dataReader;
|
361
|
+
TransactionPtr currentTransaction;
|
362
|
+
string currentTimestamp;
|
363
|
+
|
364
|
+
Client(struct ev_loop *loop, const FileDescriptor &fd)
|
365
|
+
: EventedMessageClient(loop, fd)
|
366
|
+
{
|
367
|
+
type = UNINITIALIZED;
|
368
|
+
dataReader.setMaxSize(1024 * 128);
|
369
|
+
}
|
370
|
+
};
|
371
|
+
|
372
|
+
typedef shared_ptr<Client> ClientPtr;
|
373
|
+
typedef map<string, TransactionPtr> TransactionMap;
|
374
|
+
|
375
|
+
string dir;
|
376
|
+
gid_t gid;
|
377
|
+
string dirPermissions;
|
378
|
+
mode_t filePermissions;
|
379
|
+
RemoteSender remoteSender;
|
380
|
+
ChangeNotifierPtr changeNotifier;
|
381
|
+
ev::timer garbageCollectionTimer;
|
382
|
+
ev::timer sinkFlushingTimer;
|
383
|
+
ev::timer exitTimer;
|
384
|
+
TransactionMap transactions;
|
385
|
+
LogSinkCache logSinkCache;
|
386
|
+
/**
|
387
|
+
* @invariant
|
388
|
+
* inactiveLogSinks is sorted from oldest to youngest (by lastTime member).
|
389
|
+
* for all s in inactiveLogSinks:
|
390
|
+
* s.opened == 0
|
391
|
+
* inactiveLogSinks.size() == inactiveLogSinksCount
|
392
|
+
*/
|
393
|
+
list<LogSinkPtr> inactiveLogSinks;
|
394
|
+
int inactiveLogSinksCount;
|
395
|
+
RandomGenerator randomGenerator;
|
396
|
+
bool refuseNewConnections;
|
397
|
+
bool exitRequested;
|
398
|
+
unsigned long long exitBeginTime;
|
399
|
+
|
400
|
+
void sendErrorToClient(Client *client, const string &message) {
|
401
|
+
client->writeArrayMessage("error", message.c_str(), NULL);
|
402
|
+
logError(client, message);
|
403
|
+
}
|
404
|
+
|
405
|
+
bool expectingArgumentsCount(Client *client, const vector<StaticString> &args, unsigned int size) {
|
406
|
+
if (args.size() == size) {
|
407
|
+
return true;
|
408
|
+
} else {
|
409
|
+
sendErrorToClient(client, "Invalid number of arguments");
|
410
|
+
client->disconnect();
|
411
|
+
return false;
|
412
|
+
}
|
413
|
+
}
|
414
|
+
|
415
|
+
bool expectingLoggerType(Client *client) {
|
416
|
+
if (client->type == LOGGER) {
|
417
|
+
return true;
|
418
|
+
} else {
|
419
|
+
sendErrorToClient(client, "Client not initialized as logger");
|
420
|
+
client->disconnect();
|
421
|
+
return false;
|
422
|
+
}
|
423
|
+
}
|
424
|
+
|
425
|
+
bool checkWhetherConnectionAreAcceptable(Client *client) {
|
426
|
+
if (refuseNewConnections) {
|
427
|
+
client->writeArrayMessage("server shutting down", NULL);
|
428
|
+
client->disconnect();
|
429
|
+
return false;
|
430
|
+
} else {
|
431
|
+
return true;
|
432
|
+
}
|
433
|
+
}
|
434
|
+
|
435
|
+
bool validTxnId(const StaticString &txnId) const {
|
436
|
+
// must contain timestamp
|
437
|
+
// must contain separator
|
438
|
+
// must contain random id
|
439
|
+
// must not be too large
|
440
|
+
return !txnId.empty();
|
441
|
+
}
|
442
|
+
|
443
|
+
bool validUnionStationKey(const StaticString &key) const {
|
444
|
+
// must be hexadecimal
|
445
|
+
// must not be too large
|
446
|
+
return !key.empty();
|
447
|
+
}
|
448
|
+
|
449
|
+
bool validLogContent(const StaticString &data) const {
|
450
|
+
const char *current = data.c_str();
|
451
|
+
const char *end = current + data.size();
|
452
|
+
while (current < end) {
|
453
|
+
char c = *current;
|
454
|
+
if ((c < 1 && c > 126) || c == '\n' || c == '\r') {
|
455
|
+
return false;
|
456
|
+
}
|
457
|
+
current++;
|
458
|
+
}
|
459
|
+
return true;
|
460
|
+
}
|
461
|
+
|
462
|
+
bool validTimestamp(const StaticString ×tamp) const {
|
463
|
+
// must be hexadecimal
|
464
|
+
// must not be too large
|
465
|
+
return true;
|
466
|
+
}
|
467
|
+
|
468
|
+
bool supportedCategory(const StaticString &category) const {
|
469
|
+
return category == "requests" || category == "processes" || category == "exceptions";
|
470
|
+
}
|
471
|
+
|
472
|
+
time_t extractTimestamp(const StaticString &txnId) const {
|
473
|
+
const char *timestampEnd = (const char *) memchr(txnId.c_str(), '-', txnId.size());
|
474
|
+
if (timestampEnd == NULL) {
|
475
|
+
return 0;
|
476
|
+
} else {
|
477
|
+
time_t timestamp = hexatriToULL(
|
478
|
+
StaticString(txnId.c_str(), timestampEnd - txnId.c_str())
|
479
|
+
);
|
480
|
+
return timestamp * 60;
|
481
|
+
}
|
482
|
+
}
|
483
|
+
|
484
|
+
void appendVersionAndGroupId(string &output, const StaticString &groupName) const {
|
485
|
+
md5_state_t state;
|
486
|
+
md5_byte_t digest[MD5_SIZE];
|
487
|
+
char checksum[MD5_HEX_SIZE];
|
488
|
+
|
489
|
+
output.append("/1/", 3);
|
490
|
+
|
491
|
+
md5_init(&state);
|
492
|
+
md5_append(&state, (const md5_byte_t *) groupName.data(), groupName.size());
|
493
|
+
md5_finish(&state, digest);
|
494
|
+
toHex(StaticString((const char *) digest, MD5_SIZE), checksum);
|
495
|
+
output.append(checksum, MD5_HEX_SIZE);
|
496
|
+
}
|
497
|
+
|
498
|
+
string determineFilename(const StaticString &groupName, const char *nodeId,
|
499
|
+
const StaticString &category, const StaticString &txnId = "") const
|
500
|
+
{
|
501
|
+
time_t timestamp;
|
502
|
+
struct tm tm;
|
503
|
+
char time_str[14];
|
504
|
+
|
505
|
+
if (!txnId.empty()) {
|
506
|
+
timestamp = extractTimestamp(txnId);
|
507
|
+
gmtime_r(×tamp, &tm);
|
508
|
+
strftime(time_str, sizeof(time_str), "%Y/%m/%d/%H", &tm);
|
509
|
+
}
|
510
|
+
|
511
|
+
string filename;
|
512
|
+
filename.reserve(dir.size()
|
513
|
+
+ (3 + MD5_HEX_SIZE) // version and group ID
|
514
|
+
+ 1 // "/"
|
515
|
+
+ MD5_HEX_SIZE // node ID
|
516
|
+
+ 1 // "/"
|
517
|
+
+ category.size()
|
518
|
+
+ 1 // "/"
|
519
|
+
+ sizeof(time_str) // including null terminator, which we use as space for "/"
|
520
|
+
+ sizeof("log.txt")
|
521
|
+
);
|
522
|
+
filename.append(dir);
|
523
|
+
appendVersionAndGroupId(filename, groupName);
|
524
|
+
filename.append(1, '/');
|
525
|
+
filename.append(nodeId, MD5_HEX_SIZE);
|
526
|
+
filename.append(1, '/');
|
527
|
+
filename.append(category.c_str(), category.size());
|
528
|
+
if (!txnId.empty()) {
|
529
|
+
filename.append(1, '/');
|
530
|
+
filename.append(time_str);
|
531
|
+
filename.append("/log.txt");
|
532
|
+
}
|
533
|
+
return filename;
|
534
|
+
}
|
535
|
+
|
536
|
+
void setupGroupAndNodeDir(const StaticString &groupName, const StaticString &nodeName,
|
537
|
+
const char *nodeId)
|
538
|
+
{
|
539
|
+
string filename, groupDir, nodeDir;
|
540
|
+
|
541
|
+
filename.append(dir);
|
542
|
+
appendVersionAndGroupId(filename, groupName);
|
543
|
+
groupDir = filename;
|
544
|
+
|
545
|
+
filename.append("/");
|
546
|
+
filename.append(nodeId, MD5_HEX_SIZE);
|
547
|
+
nodeDir = filename;
|
548
|
+
|
549
|
+
createFile(groupDir + "/group_name.txt", groupName,
|
550
|
+
filePermissions, USER_NOT_GIVEN, GROUP_NOT_GIVEN,
|
551
|
+
false);
|
552
|
+
if (getFileType(groupDir + "/uuid.txt") == FT_NONEXISTANT) {
|
553
|
+
createFile(groupDir + "/uuid.txt",
|
554
|
+
randomGenerator.generateAsciiString(24),
|
555
|
+
filePermissions, USER_NOT_GIVEN, GROUP_NOT_GIVEN,
|
556
|
+
false);
|
557
|
+
}
|
558
|
+
|
559
|
+
createFile(nodeDir + "/node_name.txt", nodeName,
|
560
|
+
filePermissions, USER_NOT_GIVEN, GROUP_NOT_GIVEN,
|
561
|
+
false);
|
562
|
+
if (getFileType(nodeDir + "/uuid.txt") == FT_NONEXISTANT) {
|
563
|
+
createFile(nodeDir + "/uuid.txt",
|
564
|
+
randomGenerator.generateAsciiString(24),
|
565
|
+
filePermissions, USER_NOT_GIVEN, GROUP_NOT_GIVEN,
|
566
|
+
false);
|
567
|
+
}
|
568
|
+
}
|
569
|
+
|
570
|
+
bool openLogFileWithCache(const string &filename, LogSinkPtr &theLogSink) {
|
571
|
+
string cacheKey = "file:" + filename;
|
572
|
+
LogSinkCache::iterator it = logSinkCache.find(cacheKey);
|
573
|
+
if (it == logSinkCache.end()) {
|
574
|
+
trimLogSinkCache(MAX_LOG_SINK_CACHE_SIZE - 1);
|
575
|
+
makeDirTree(extractDirName(filename), dirPermissions,
|
576
|
+
USER_NOT_GIVEN, gid);
|
577
|
+
theLogSink.reset(new LogFile(this, filename, filePermissions));
|
578
|
+
pair<LogSinkCache::iterator, bool> p =
|
579
|
+
logSinkCache.insert(make_pair(cacheKey, theLogSink));
|
580
|
+
theLogSink->cacheIterator = p.first;
|
581
|
+
theLogSink->opened = 1;
|
582
|
+
return false;
|
583
|
+
} else {
|
584
|
+
theLogSink = it->second;
|
585
|
+
theLogSink->opened++;
|
586
|
+
if (theLogSink->opened == 1) {
|
587
|
+
inactiveLogSinks.erase(theLogSink->inactiveLogSinksIterator);
|
588
|
+
inactiveLogSinksCount--;
|
589
|
+
}
|
590
|
+
return true;
|
591
|
+
}
|
592
|
+
}
|
593
|
+
|
594
|
+
void openRemoteSink(const StaticString &unionStationKey, const string &nodeName,
|
595
|
+
const string &category, LogSinkPtr &theLogSink)
|
596
|
+
{
|
597
|
+
string cacheKey = "remote:";
|
598
|
+
cacheKey.append(unionStationKey.c_str(), unionStationKey.size());
|
599
|
+
cacheKey.append(1, '\0');
|
600
|
+
cacheKey.append(nodeName);
|
601
|
+
cacheKey.append(1, '\0');
|
602
|
+
cacheKey.append(category);
|
603
|
+
|
604
|
+
LogSinkCache::iterator it = logSinkCache.find(cacheKey);
|
605
|
+
if (it == logSinkCache.end()) {
|
606
|
+
trimLogSinkCache(MAX_LOG_SINK_CACHE_SIZE - 1);
|
607
|
+
theLogSink.reset(new RemoteSink(this, unionStationKey,
|
608
|
+
nodeName, category));
|
609
|
+
pair<LogSinkCache::iterator, bool> p =
|
610
|
+
logSinkCache.insert(make_pair(cacheKey, theLogSink));
|
611
|
+
theLogSink->cacheIterator = p.first;
|
612
|
+
theLogSink->opened = 1;
|
613
|
+
} else {
|
614
|
+
theLogSink = it->second;
|
615
|
+
theLogSink->opened++;
|
616
|
+
if (theLogSink->opened == 1) {
|
617
|
+
inactiveLogSinks.erase(theLogSink->inactiveLogSinksIterator);
|
618
|
+
inactiveLogSinksCount--;
|
619
|
+
}
|
620
|
+
}
|
621
|
+
}
|
622
|
+
|
623
|
+
/**
|
624
|
+
* 'Closes' the given log sink. It's not actually deleted from memory;
|
625
|
+
* instead it's marked as inactive and cached for later use. May be
|
626
|
+
* deleted later when resources are low.
|
627
|
+
*
|
628
|
+
* No need to call this manually. Automatically called by Transaction's
|
629
|
+
* destructor.
|
630
|
+
*/
|
631
|
+
void closeLogSink(const LogSinkPtr &logSink) {
|
632
|
+
logSink->opened--;
|
633
|
+
assert(logSink->opened >= 0);
|
634
|
+
logSink->lastUsed = ev_now(getLoop());
|
635
|
+
if (logSink->opened == 0) {
|
636
|
+
inactiveLogSinks.push_back(logSink);
|
637
|
+
logSink->inactiveLogSinksIterator = inactiveLogSinks.end();
|
638
|
+
logSink->inactiveLogSinksIterator--;
|
639
|
+
inactiveLogSinksCount++;
|
640
|
+
trimLogSinkCache(MAX_LOG_SINK_CACHE_SIZE);
|
641
|
+
}
|
642
|
+
}
|
643
|
+
|
644
|
+
/** Try to reduce the log sink cache size to the given size. */
|
645
|
+
void trimLogSinkCache(unsigned int size) {
|
646
|
+
while (!inactiveLogSinks.empty() && logSinkCache.size() > size) {
|
647
|
+
const LogSinkPtr logSink = inactiveLogSinks.front();
|
648
|
+
inactiveLogSinks.pop_front();
|
649
|
+
inactiveLogSinksCount--;
|
650
|
+
logSinkCache.erase(logSink->cacheIterator);
|
651
|
+
}
|
652
|
+
}
|
653
|
+
|
654
|
+
bool writeLogEntry(Client *client, const TransactionPtr &transaction,
|
655
|
+
const StaticString ×tamp, const StaticString &data)
|
656
|
+
{
|
657
|
+
if (transaction->discarded) {
|
658
|
+
return true;
|
659
|
+
}
|
660
|
+
if (OXT_UNLIKELY( !validLogContent(data) )) {
|
661
|
+
if (client != NULL) {
|
662
|
+
sendErrorToClient(client, "Log entry data contains an invalid character.");
|
663
|
+
client->disconnect();
|
664
|
+
}
|
665
|
+
return false;
|
666
|
+
}
|
667
|
+
if (OXT_UNLIKELY( !validTimestamp(timestamp) )) {
|
668
|
+
if (client != NULL) {
|
669
|
+
sendErrorToClient(client, "Log entry timestamp is invalid.");
|
670
|
+
client->disconnect();
|
671
|
+
}
|
672
|
+
return false;
|
673
|
+
}
|
674
|
+
|
675
|
+
char writeCountStr[sizeof(unsigned int) * 2 + 1];
|
676
|
+
integerToHexatri(transaction->writeCount, writeCountStr);
|
677
|
+
transaction->writeCount++;
|
678
|
+
transaction->data.reserve(transaction->data.size() +
|
679
|
+
transaction->txnId.size() +
|
680
|
+
1 +
|
681
|
+
timestamp.size() +
|
682
|
+
1 +
|
683
|
+
strlen(writeCountStr) +
|
684
|
+
1 +
|
685
|
+
data.size() +
|
686
|
+
1);
|
687
|
+
transaction->data.append(transaction->txnId);
|
688
|
+
transaction->data.append(" ");
|
689
|
+
transaction->data.append(timestamp);
|
690
|
+
transaction->data.append(" ");
|
691
|
+
transaction->data.append(writeCountStr);
|
692
|
+
transaction->data.append(" ");
|
693
|
+
transaction->data.append(data);
|
694
|
+
transaction->data.append("\n");
|
695
|
+
return true;
|
696
|
+
}
|
697
|
+
|
698
|
+
void writeDetachEntry(Client *client, const TransactionPtr &transaction) {
|
699
|
+
char timestamp[2 * sizeof(unsigned long long) + 1];
|
700
|
+
// Must use System::getUsec() here instead of ev_now() because the
|
701
|
+
// precision of the time is very important.
|
702
|
+
integerToHexatri<unsigned long long>(SystemTime::getUsec(), timestamp);
|
703
|
+
writeDetachEntry(client, transaction, timestamp);
|
704
|
+
}
|
705
|
+
|
706
|
+
void writeDetachEntry(Client *client, const TransactionPtr &transaction,
|
707
|
+
const StaticString ×tamp)
|
708
|
+
{
|
709
|
+
writeLogEntry(client, transaction, timestamp, "DETACH");
|
710
|
+
}
|
711
|
+
|
712
|
+
bool requireRights(Client *client, Account::Rights rights) {
|
713
|
+
if (client->messageServer.account->hasRights(rights)) {
|
714
|
+
return true;
|
715
|
+
} else {
|
716
|
+
P_TRACE(2, "Security error: insufficient rights to execute this command.");
|
717
|
+
client->writeArrayMessage("SecurityException",
|
718
|
+
"Insufficient rights to execute this command.",
|
719
|
+
NULL);
|
720
|
+
client->disconnect();
|
721
|
+
return false;
|
722
|
+
}
|
723
|
+
}
|
724
|
+
|
725
|
+
bool isDirectory(const string &dir, struct dirent *entry) const {
|
726
|
+
#ifdef __sun__
|
727
|
+
string path = dir;
|
728
|
+
path.append("/");
|
729
|
+
path.append(entry->d_name);
|
730
|
+
return getFileType(path) == FT_DIRECTORY;
|
731
|
+
#else
|
732
|
+
return entry->d_type == DT_DIR;
|
733
|
+
#endif
|
734
|
+
}
|
735
|
+
|
736
|
+
bool looksLikeNumber(const char *str) const {
|
737
|
+
const char *current = str;
|
738
|
+
while (*current != '\0') {
|
739
|
+
char c = *current;
|
740
|
+
if (!(c >= '0' && c <= '9')) {
|
741
|
+
return false;
|
742
|
+
}
|
743
|
+
current++;
|
744
|
+
}
|
745
|
+
return true;
|
746
|
+
}
|
747
|
+
|
748
|
+
bool getLastEntryInDirectory(const string &path, string &result) const {
|
749
|
+
DIR *dir = opendir(path.c_str());
|
750
|
+
struct dirent *entry;
|
751
|
+
vector<string> subdirs;
|
752
|
+
|
753
|
+
if (dir == NULL) {
|
754
|
+
int e = errno;
|
755
|
+
throw FileSystemException("Cannot open directory " + path,
|
756
|
+
e, path);
|
757
|
+
}
|
758
|
+
while ((entry = readdir(dir)) != NULL) {
|
759
|
+
if (isDirectory(path, entry) && looksLikeNumber(entry->d_name)) {
|
760
|
+
subdirs.push_back(entry->d_name);
|
761
|
+
}
|
762
|
+
}
|
763
|
+
closedir(dir);
|
764
|
+
|
765
|
+
if (subdirs.empty()) {
|
766
|
+
return false;
|
767
|
+
}
|
768
|
+
|
769
|
+
vector<string>::const_iterator it = subdirs.begin();
|
770
|
+
vector<string>::const_iterator end = subdirs.end();
|
771
|
+
vector<string>::const_iterator largest_it = subdirs.begin();
|
772
|
+
int largest = atoi(subdirs[0]);
|
773
|
+
for (it++; it != end; it++) {
|
774
|
+
const string &subdir = *it;
|
775
|
+
int number = atoi(subdir.c_str());
|
776
|
+
if (number > largest) {
|
777
|
+
largest_it = it;
|
778
|
+
largest = number;
|
779
|
+
}
|
780
|
+
}
|
781
|
+
result = *largest_it;
|
782
|
+
return true;
|
783
|
+
}
|
784
|
+
|
785
|
+
static void pendingDataFlushed(EventedClient *_client) {
|
786
|
+
Client *client = (Client *) _client;
|
787
|
+
LoggingServer *self = (LoggingServer *) client->userData;
|
788
|
+
|
789
|
+
client->onPendingDataFlushed = NULL;
|
790
|
+
if (OXT_UNLIKELY( client->type != WATCHER )) {
|
791
|
+
P_WARN("BUG: pendingDataFlushed() called even though client type is not WATCHER.");
|
792
|
+
client->disconnect();
|
793
|
+
} else if (self->changeNotifier != NULL) {
|
794
|
+
self->changeNotifier->addClient(client->detach());
|
795
|
+
} else {
|
796
|
+
client->disconnect();
|
797
|
+
}
|
798
|
+
}
|
799
|
+
|
800
|
+
/* Release all inactive log sinks that have been inactive for more than
|
801
|
+
* GARBAGE_COLLECTION_TIMEOUT seconds.
|
802
|
+
*/
|
803
|
+
void releaseInactiveLogSinks(ev_tstamp now) {
|
804
|
+
bool done = false;
|
805
|
+
|
806
|
+
while (!done && !inactiveLogSinks.empty()) {
|
807
|
+
const LogSinkPtr logSink = inactiveLogSinks.front();
|
808
|
+
if (now - logSink->lastUsed >= GARBAGE_COLLECTION_TIMEOUT) {
|
809
|
+
inactiveLogSinks.pop_front();
|
810
|
+
inactiveLogSinksCount--;
|
811
|
+
logSinkCache.erase(logSink->cacheIterator);
|
812
|
+
} else {
|
813
|
+
done = true;
|
814
|
+
}
|
815
|
+
}
|
816
|
+
}
|
817
|
+
|
818
|
+
void garbageCollect(ev::timer &timer, int revents) {
|
819
|
+
P_DEBUG("Garbage collection time");
|
820
|
+
releaseInactiveLogSinks(ev_now(getLoop()));
|
821
|
+
}
|
822
|
+
|
823
|
+
void sinkFlushTimeout(ev::timer &timer, int revents) {
|
824
|
+
P_TRACE(2, "Flushing all sinks (periodic action)");
|
825
|
+
LogSinkCache::iterator it;
|
826
|
+
LogSinkCache::iterator end = logSinkCache.end();
|
827
|
+
ev_tstamp now = ev_now(getLoop());
|
828
|
+
|
829
|
+
for (it = logSinkCache.begin(); it != end; it++) {
|
830
|
+
LogSink *sink = it->second.get();
|
831
|
+
|
832
|
+
// Flush log file sinks every 15 seconds,
|
833
|
+
// remote sinks every 60 seconds.
|
834
|
+
if (sink->isRemote()) {
|
835
|
+
if (now - sink->lastFlushed >= 60) {
|
836
|
+
sink->flush();
|
837
|
+
}
|
838
|
+
} else {
|
839
|
+
sink->flush();
|
840
|
+
}
|
841
|
+
}
|
842
|
+
}
|
843
|
+
|
844
|
+
void flushAllSinks() {
|
845
|
+
P_TRACE(2, "Flushing all sinks");
|
846
|
+
LogSinkCache::iterator it;
|
847
|
+
LogSinkCache::iterator end = logSinkCache.end();
|
848
|
+
|
849
|
+
for (it = logSinkCache.begin(); it != end; it++) {
|
850
|
+
LogSink *sink = it->second.get();
|
851
|
+
sink->flush();
|
852
|
+
}
|
853
|
+
}
|
854
|
+
|
855
|
+
void exitTimerTimeout(ev::timer &timer, int revents) {
|
856
|
+
if (SystemTime::getMsec() >= exitBeginTime + 5000) {
|
857
|
+
exitTimer.stop();
|
858
|
+
exitRequested = false;
|
859
|
+
refuseNewConnections = false;
|
860
|
+
ev_unloop(getLoop(), EVUNLOOP_ONE);
|
861
|
+
}
|
862
|
+
}
|
863
|
+
|
864
|
+
protected:
|
865
|
+
virtual EventedClient *createClient(const FileDescriptor &fd) {
|
866
|
+
return new Client(getLoop(), fd);
|
867
|
+
}
|
868
|
+
|
869
|
+
virtual bool onMessageReceived(EventedMessageClient *_client, const vector<StaticString> &args) {
|
870
|
+
Client *client = (Client *) _client;
|
871
|
+
|
872
|
+
if (args[0] == "log") {
|
873
|
+
if (OXT_UNLIKELY( !expectingArgumentsCount(client, args, 3)
|
874
|
+
|| !expectingLoggerType(client) )) {
|
875
|
+
return true;
|
876
|
+
}
|
877
|
+
|
878
|
+
string txnId = args[1];
|
879
|
+
string timestamp = args[2];
|
880
|
+
|
881
|
+
TransactionMap::iterator it = transactions.find(txnId);
|
882
|
+
if (OXT_UNLIKELY( it == transactions.end() )) {
|
883
|
+
sendErrorToClient(client, "Cannot log data: transaction does not exist");
|
884
|
+
client->disconnect();
|
885
|
+
} else {
|
886
|
+
set<string>::iterator sit = client->openTransactions.find(txnId);
|
887
|
+
if (OXT_UNLIKELY( sit == client->openTransactions.end() )) {
|
888
|
+
sendErrorToClient(client,
|
889
|
+
"Cannot log data: transaction not opened in this connection");
|
890
|
+
client->disconnect();
|
891
|
+
return true;
|
892
|
+
}
|
893
|
+
// Expecting the log data in a scalar message.
|
894
|
+
client->currentTransaction = it->second;
|
895
|
+
client->currentTimestamp = timestamp;
|
896
|
+
return false;
|
897
|
+
}
|
898
|
+
|
899
|
+
} else if (args[0] == "openTransaction") {
|
900
|
+
if (OXT_UNLIKELY( !expectingArgumentsCount(client, args, 8)
|
901
|
+
|| !expectingLoggerType(client) )) {
|
902
|
+
return true;
|
903
|
+
}
|
904
|
+
|
905
|
+
string txnId = args[1];
|
906
|
+
StaticString groupName = args[2];
|
907
|
+
StaticString nodeName = args[3];
|
908
|
+
StaticString category = args[4];
|
909
|
+
StaticString timestamp = args[5];
|
910
|
+
StaticString unionStationKey = args[6];
|
911
|
+
bool crashProtect = args[7] == "true";
|
912
|
+
|
913
|
+
if (OXT_UNLIKELY( !validTxnId(txnId) )) {
|
914
|
+
sendErrorToClient(client, "Invalid transaction ID format");
|
915
|
+
client->disconnect();
|
916
|
+
return true;
|
917
|
+
}
|
918
|
+
if (!unionStationKey.empty()
|
919
|
+
&& OXT_UNLIKELY( !validUnionStationKey(unionStationKey) )) {
|
920
|
+
sendErrorToClient(client, "Invalid Union Station key format");
|
921
|
+
client->disconnect();
|
922
|
+
return true;
|
923
|
+
}
|
924
|
+
if (OXT_UNLIKELY( client->openTransactions.find(txnId) !=
|
925
|
+
client->openTransactions.end() ))
|
926
|
+
{
|
927
|
+
sendErrorToClient(client, "Cannot open transaction: transaction already opened in this connection");
|
928
|
+
client->disconnect();
|
929
|
+
return true;
|
930
|
+
}
|
931
|
+
|
932
|
+
const char *nodeId;
|
933
|
+
|
934
|
+
if (nodeName.empty()) {
|
935
|
+
nodeName = client->nodeName;
|
936
|
+
nodeId = client->nodeId;
|
937
|
+
} else {
|
938
|
+
nodeId = NULL;
|
939
|
+
}
|
940
|
+
|
941
|
+
TransactionMap::iterator it = transactions.find(txnId);
|
942
|
+
TransactionPtr transaction;
|
943
|
+
if (it == transactions.end()) {
|
944
|
+
if (OXT_UNLIKELY( !supportedCategory(category) )) {
|
945
|
+
sendErrorToClient(client, "Unsupported category");
|
946
|
+
client->disconnect();
|
947
|
+
return true;
|
948
|
+
}
|
949
|
+
|
950
|
+
transaction.reset(new Transaction(this));
|
951
|
+
if (unionStationKey.empty()) {
|
952
|
+
char tempNodeId[MD5_HEX_SIZE];
|
953
|
+
|
954
|
+
if (nodeId == NULL) {
|
955
|
+
md5_state_t state;
|
956
|
+
md5_byte_t digest[MD5_SIZE];
|
957
|
+
|
958
|
+
md5_init(&state);
|
959
|
+
md5_append(&state,
|
960
|
+
(const md5_byte_t *) nodeName.data(),
|
961
|
+
nodeName.size());
|
962
|
+
md5_finish(&state, digest);
|
963
|
+
toHex(StaticString((const char *) digest, MD5_SIZE),
|
964
|
+
tempNodeId);
|
965
|
+
nodeId = tempNodeId;
|
966
|
+
}
|
967
|
+
|
968
|
+
string filename = determineFilename(groupName, nodeId,
|
969
|
+
category, txnId);
|
970
|
+
if (!openLogFileWithCache(filename, transaction->logSink)) {
|
971
|
+
setupGroupAndNodeDir(groupName, nodeName, nodeId);
|
972
|
+
}
|
973
|
+
} else {
|
974
|
+
openRemoteSink(unionStationKey, client->nodeName,
|
975
|
+
category, transaction->logSink);
|
976
|
+
}
|
977
|
+
transaction->txnId = txnId;
|
978
|
+
transaction->dataStoreId = DataStoreId(groupName,
|
979
|
+
nodeName, category);
|
980
|
+
transaction->writeCount = 0;
|
981
|
+
transaction->refcount = 0;
|
982
|
+
transaction->crashProtect = crashProtect;
|
983
|
+
transaction->discarded = false;
|
984
|
+
transactions.insert(make_pair(txnId, transaction));
|
985
|
+
} else {
|
986
|
+
transaction = it->second;
|
987
|
+
if (OXT_UNLIKELY( transaction->getGroupName() != groupName )) {
|
988
|
+
sendErrorToClient(client,
|
989
|
+
"Cannot open transaction: transaction already opened with a different group name");
|
990
|
+
client->disconnect();
|
991
|
+
return true;
|
992
|
+
}
|
993
|
+
if (OXT_UNLIKELY( transaction->getNodeName() != nodeName )) {
|
994
|
+
sendErrorToClient(client,
|
995
|
+
"Cannot open transaction: transaction already opened with a different node name");
|
996
|
+
client->disconnect();
|
997
|
+
return true;
|
998
|
+
}
|
999
|
+
if (OXT_UNLIKELY( transaction->getCategory() != category )) {
|
1000
|
+
sendErrorToClient(client,
|
1001
|
+
"Cannot open transaction: transaction already opened with a different category name");
|
1002
|
+
client->disconnect();
|
1003
|
+
return true;
|
1004
|
+
}
|
1005
|
+
}
|
1006
|
+
|
1007
|
+
client->openTransactions.insert(txnId);
|
1008
|
+
transaction->refcount++;
|
1009
|
+
writeLogEntry(client, transaction, timestamp, "ATTACH");
|
1010
|
+
|
1011
|
+
} else if (args[0] == "closeTransaction") {
|
1012
|
+
if (OXT_UNLIKELY( !expectingArgumentsCount(client, args, 3)
|
1013
|
+
|| !expectingLoggerType(client) )) {
|
1014
|
+
return true;
|
1015
|
+
}
|
1016
|
+
|
1017
|
+
string txnId = args[1];
|
1018
|
+
StaticString timestamp = args[2];
|
1019
|
+
|
1020
|
+
TransactionMap::iterator it = transactions.find(txnId);
|
1021
|
+
if (OXT_UNLIKELY( it == transactions.end() )) {
|
1022
|
+
sendErrorToClient(client,
|
1023
|
+
"Cannot close transaction " + txnId +
|
1024
|
+
": transaction does not exist");
|
1025
|
+
client->disconnect();
|
1026
|
+
} else {
|
1027
|
+
TransactionPtr &transaction = it->second;
|
1028
|
+
|
1029
|
+
set<string>::const_iterator sit = client->openTransactions.find(txnId);
|
1030
|
+
if (OXT_UNLIKELY( sit == client->openTransactions.end() )) {
|
1031
|
+
sendErrorToClient(client,
|
1032
|
+
"Cannot close transaction " + txnId +
|
1033
|
+
": transaction not opened in this connection");
|
1034
|
+
client->disconnect();
|
1035
|
+
return true;
|
1036
|
+
} else {
|
1037
|
+
client->openTransactions.erase(sit);
|
1038
|
+
}
|
1039
|
+
|
1040
|
+
writeDetachEntry(client, transaction, timestamp);
|
1041
|
+
transaction->refcount--;
|
1042
|
+
assert(transaction->refcount >= 0);
|
1043
|
+
if (transaction->refcount == 0) {
|
1044
|
+
transactions.erase(it);
|
1045
|
+
}
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
} else if (args[0] == "init") {
|
1049
|
+
if (OXT_UNLIKELY( client->type != UNINITIALIZED )) {
|
1050
|
+
sendErrorToClient(client, "Already initialized");
|
1051
|
+
client->disconnect();
|
1052
|
+
return true;
|
1053
|
+
}
|
1054
|
+
if (OXT_UNLIKELY( !expectingArgumentsCount(client, args, 2) )) {
|
1055
|
+
return true;
|
1056
|
+
}
|
1057
|
+
if (OXT_UNLIKELY( !checkWhetherConnectionAreAcceptable(client) )) {
|
1058
|
+
return true;
|
1059
|
+
}
|
1060
|
+
|
1061
|
+
StaticString nodeName = args[1];
|
1062
|
+
client->nodeName = nodeName;
|
1063
|
+
|
1064
|
+
md5_state_t state;
|
1065
|
+
md5_byte_t digest[MD5_SIZE];
|
1066
|
+
md5_init(&state);
|
1067
|
+
md5_append(&state, (const md5_byte_t *) nodeName.data(), nodeName.size());
|
1068
|
+
md5_finish(&state, digest);
|
1069
|
+
toHex(StaticString((const char *) digest, MD5_SIZE), client->nodeId);
|
1070
|
+
|
1071
|
+
client->type = LOGGER;
|
1072
|
+
client->writeArrayMessage("ok", NULL);
|
1073
|
+
|
1074
|
+
} else if (args[0] == "watchChanges") {
|
1075
|
+
if (OXT_UNLIKELY( !checkWhetherConnectionAreAcceptable(client) )) {
|
1076
|
+
return true;
|
1077
|
+
}
|
1078
|
+
if (OXT_UNLIKELY( client->type != UNINITIALIZED )) {
|
1079
|
+
sendErrorToClient(client, "This command cannot be invoked "
|
1080
|
+
"if the 'init' command is already invoked.");
|
1081
|
+
client->disconnect();
|
1082
|
+
return true;
|
1083
|
+
}
|
1084
|
+
|
1085
|
+
client->type = WATCHER;
|
1086
|
+
client->notifyReads(false);
|
1087
|
+
discardReadData();
|
1088
|
+
|
1089
|
+
// Add to the change notifier after all pending data
|
1090
|
+
// has been written out.
|
1091
|
+
client->onPendingDataFlushed = pendingDataFlushed;
|
1092
|
+
client->writeArrayMessage("ok", NULL);
|
1093
|
+
|
1094
|
+
} else if (args[0] == "flush") {
|
1095
|
+
flushAllSinks();
|
1096
|
+
client->writeArrayMessage("ok", NULL);
|
1097
|
+
|
1098
|
+
} else if (args[0] == "info") {
|
1099
|
+
stringstream stream;
|
1100
|
+
dump(stream);
|
1101
|
+
client->writeArrayMessage("info", stream.str().c_str(), NULL);
|
1102
|
+
|
1103
|
+
} else if (args[0] == "ping") {
|
1104
|
+
client->writeArrayMessage("pong", NULL);
|
1105
|
+
|
1106
|
+
} else if (args[0] == "exit") {
|
1107
|
+
if (!requireRights(client, Account::EXIT)) {
|
1108
|
+
client->disconnect();
|
1109
|
+
return true;
|
1110
|
+
}
|
1111
|
+
if (args.size() == 2 && args[1] == "immediately") {
|
1112
|
+
// Immediate exit.
|
1113
|
+
ev_unloop(getLoop(), EVUNLOOP_ONE);
|
1114
|
+
} else if (args.size() == 2 && args[1] == "semi-gracefully") {
|
1115
|
+
// Semi-graceful exit: refuse new connections, shut down
|
1116
|
+
// a few seconds after the last client has disconnected.
|
1117
|
+
refuseNewConnections = true;
|
1118
|
+
exitRequested = true;
|
1119
|
+
} else {
|
1120
|
+
// Graceful exit: shut down a few seconds after the
|
1121
|
+
// last client has disconnected.
|
1122
|
+
client->writeArrayMessage("Passed security", NULL);
|
1123
|
+
client->writeArrayMessage("exit command received", NULL);
|
1124
|
+
exitRequested = true;
|
1125
|
+
}
|
1126
|
+
client->disconnect();
|
1127
|
+
|
1128
|
+
} else {
|
1129
|
+
sendErrorToClient(client, "Unknown command '" + args[0] + "'");
|
1130
|
+
client->disconnect();
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
return true;
|
1134
|
+
}
|
1135
|
+
|
1136
|
+
virtual pair<size_t, bool> onOtherDataReceived(EventedMessageClient *_client,
|
1137
|
+
const char *data, size_t size)
|
1138
|
+
{
|
1139
|
+
// In here we read the scalar message that's expected to come
|
1140
|
+
// after the "log" command.
|
1141
|
+
Client *client = (Client *) _client;
|
1142
|
+
size_t consumed = client->dataReader.feed(data, size);
|
1143
|
+
if (client->dataReader.done()) {
|
1144
|
+
writeLogEntry(client,
|
1145
|
+
client->currentTransaction,
|
1146
|
+
client->currentTimestamp,
|
1147
|
+
client->dataReader.value());
|
1148
|
+
client->currentTransaction.reset();
|
1149
|
+
client->dataReader.reset();
|
1150
|
+
return make_pair(consumed, true);
|
1151
|
+
} else {
|
1152
|
+
return make_pair(consumed, false);
|
1153
|
+
}
|
1154
|
+
}
|
1155
|
+
|
1156
|
+
virtual void onNewClient(EventedClient *client) {
|
1157
|
+
if (exitRequested && exitTimer.is_active()) {
|
1158
|
+
exitTimer.stop();
|
1159
|
+
}
|
1160
|
+
EventedMessageServer::onNewClient(client);
|
1161
|
+
}
|
1162
|
+
|
1163
|
+
virtual void onClientDisconnected(EventedClient *_client) {
|
1164
|
+
EventedMessageServer::onClientDisconnected(_client);
|
1165
|
+
Client *client = (Client *) _client;
|
1166
|
+
set<string>::const_iterator sit;
|
1167
|
+
set<string>::const_iterator send = client->openTransactions.end();
|
1168
|
+
|
1169
|
+
// Close any transactions that this client had opened.
|
1170
|
+
for (sit = client->openTransactions.begin(); sit != send; sit++) {
|
1171
|
+
const string &txnId = *sit;
|
1172
|
+
TransactionMap::iterator it = transactions.find(txnId);
|
1173
|
+
if (OXT_UNLIKELY( it == transactions.end() )) {
|
1174
|
+
P_ERROR("Bug: client->openTransactions is not a subset of this->transactions!");
|
1175
|
+
abort();
|
1176
|
+
}
|
1177
|
+
|
1178
|
+
TransactionPtr &transaction = it->second;
|
1179
|
+
if (transaction->crashProtect) {
|
1180
|
+
writeDetachEntry(client, transaction);
|
1181
|
+
} else {
|
1182
|
+
transaction->discard();
|
1183
|
+
}
|
1184
|
+
transaction->refcount--;
|
1185
|
+
assert(transaction->refcount >= 0);
|
1186
|
+
if (transaction->refcount == 0) {
|
1187
|
+
transactions.erase(it);
|
1188
|
+
}
|
1189
|
+
}
|
1190
|
+
client->openTransactions.clear();
|
1191
|
+
|
1192
|
+
// Possibly start exit timer.
|
1193
|
+
if (exitRequested && getClients().empty()) {
|
1194
|
+
exitTimer.start();
|
1195
|
+
/* Using SystemTime here instead of setting a correct
|
1196
|
+
* timeout directly on the timer, so that we can
|
1197
|
+
* manipulate the clock in LoggingServer unit tests.
|
1198
|
+
*/
|
1199
|
+
exitBeginTime = SystemTime::getMsec();
|
1200
|
+
}
|
1201
|
+
}
|
1202
|
+
|
1203
|
+
public:
|
1204
|
+
LoggingServer(struct ev_loop *loop,
|
1205
|
+
FileDescriptor fd,
|
1206
|
+
const AccountsDatabasePtr &accountsDatabase,
|
1207
|
+
const string &dir,
|
1208
|
+
const string &permissions = DEFAULT_ANALYTICS_LOG_PERMISSIONS,
|
1209
|
+
gid_t gid = GROUP_NOT_GIVEN,
|
1210
|
+
const string &unionStationGatewayAddress = DEFAULT_UNION_STATION_GATEWAY_ADDRESS,
|
1211
|
+
unsigned short unionStationGatewayPort = DEFAULT_UNION_STATION_GATEWAY_PORT,
|
1212
|
+
const string &unionStationGatewayCert = "")
|
1213
|
+
: EventedMessageServer(loop, fd, accountsDatabase),
|
1214
|
+
remoteSender(unionStationGatewayAddress,
|
1215
|
+
unionStationGatewayPort,
|
1216
|
+
unionStationGatewayCert),
|
1217
|
+
garbageCollectionTimer(loop),
|
1218
|
+
sinkFlushingTimer(loop),
|
1219
|
+
exitTimer(loop)
|
1220
|
+
{
|
1221
|
+
this->dir = dir;
|
1222
|
+
this->gid = gid;
|
1223
|
+
dirPermissions = permissions;
|
1224
|
+
filePermissions = parseModeString(permissions) & ~(S_IXUSR | S_IXGRP | S_IXOTH);
|
1225
|
+
garbageCollectionTimer.set<LoggingServer, &LoggingServer::garbageCollect>(this);
|
1226
|
+
garbageCollectionTimer.start(GARBAGE_COLLECTION_TIMEOUT, GARBAGE_COLLECTION_TIMEOUT);
|
1227
|
+
sinkFlushingTimer.set<LoggingServer, &LoggingServer::sinkFlushTimeout>(this);
|
1228
|
+
sinkFlushingTimer.start(15, 15);
|
1229
|
+
exitTimer.set<LoggingServer, &LoggingServer::exitTimerTimeout>(this);
|
1230
|
+
exitTimer.set(0.05, 0.05);
|
1231
|
+
refuseNewConnections = false;
|
1232
|
+
exitRequested = false;
|
1233
|
+
inactiveLogSinksCount = 0;
|
1234
|
+
}
|
1235
|
+
|
1236
|
+
~LoggingServer() {
|
1237
|
+
TransactionMap::iterator it, end = transactions.end();
|
1238
|
+
for (it = transactions.begin(); it != end; it++) {
|
1239
|
+
TransactionPtr &transaction = it->second;
|
1240
|
+
if (transaction->crashProtect) {
|
1241
|
+
writeDetachEntry(NULL, transaction);
|
1242
|
+
} else {
|
1243
|
+
transaction->discard();
|
1244
|
+
}
|
1245
|
+
}
|
1246
|
+
|
1247
|
+
// Invoke destructors, causing all transactions and log sinks to
|
1248
|
+
// be flushed before RemoteSender and ChangeNotifier are being
|
1249
|
+
// destroyed.
|
1250
|
+
transactions.clear();
|
1251
|
+
logSinkCache.clear();
|
1252
|
+
inactiveLogSinks.clear();
|
1253
|
+
}
|
1254
|
+
|
1255
|
+
void setChangeNotifier(const ChangeNotifierPtr &_changeNotifier) {
|
1256
|
+
changeNotifier = _changeNotifier;
|
1257
|
+
changeNotifier->getLastPos = boost::bind(&LoggingServer::getLastPos,
|
1258
|
+
this, _1, _2, _3);
|
1259
|
+
}
|
1260
|
+
|
1261
|
+
string getLastPos(const StaticString &groupName, const StaticString &nodeName,
|
1262
|
+
const StaticString &category) const
|
1263
|
+
{
|
1264
|
+
md5_state_t state;
|
1265
|
+
md5_byte_t digest[MD5_SIZE];
|
1266
|
+
char nodeId[MD5_HEX_SIZE];
|
1267
|
+
md5_init(&state);
|
1268
|
+
md5_append(&state, (const md5_byte_t *) nodeName.data(), nodeName.size());
|
1269
|
+
md5_finish(&state, digest);
|
1270
|
+
toHex(StaticString((const char *) digest, MD5_SIZE), nodeId);
|
1271
|
+
|
1272
|
+
string dir = determineFilename(groupName, nodeId, category);
|
1273
|
+
string subdir, component;
|
1274
|
+
subdir.reserve(13); // It's a string that looks like: "2010/06/24/12"
|
1275
|
+
|
1276
|
+
try {
|
1277
|
+
// Loop 4 times to process year, month, day, hour.
|
1278
|
+
for (int i = 0; i < 4; i++) {
|
1279
|
+
bool found = getLastEntryInDirectory(dir, component);
|
1280
|
+
if (!found) {
|
1281
|
+
return string();
|
1282
|
+
}
|
1283
|
+
dir.append("/");
|
1284
|
+
dir.append(component);
|
1285
|
+
if (i != 0) {
|
1286
|
+
subdir.append("/");
|
1287
|
+
}
|
1288
|
+
subdir.append(component);
|
1289
|
+
}
|
1290
|
+
// After the loop, new dir == old dir + "/" + subdir
|
1291
|
+
} catch (const SystemException &e) {
|
1292
|
+
if (e.code() == ENOENT) {
|
1293
|
+
return string();
|
1294
|
+
} else {
|
1295
|
+
throw;
|
1296
|
+
}
|
1297
|
+
}
|
1298
|
+
|
1299
|
+
string &filename = dir;
|
1300
|
+
filename.append("/log.txt");
|
1301
|
+
|
1302
|
+
struct stat buf;
|
1303
|
+
if (stat(filename.c_str(), &buf) == -1) {
|
1304
|
+
if (errno == ENOENT) {
|
1305
|
+
return string();
|
1306
|
+
} else {
|
1307
|
+
int e = errno;
|
1308
|
+
throw FileSystemException("Cannot stat() " + filename, e,
|
1309
|
+
filename);
|
1310
|
+
}
|
1311
|
+
} else {
|
1312
|
+
return subdir + "/" + toString(buf.st_size);
|
1313
|
+
}
|
1314
|
+
}
|
1315
|
+
|
1316
|
+
void dump(ostream &stream) const {
|
1317
|
+
TransactionMap::const_iterator it;
|
1318
|
+
TransactionMap::const_iterator end = transactions.end();
|
1319
|
+
|
1320
|
+
stream << "Number of clients: " << getClients().size() << "\n";
|
1321
|
+
stream << "Open transactions: " << transactions.size() << "\n";
|
1322
|
+
for (it = transactions.begin(); it != end; it++) {
|
1323
|
+
const TransactionPtr &transaction = it->second;
|
1324
|
+
transaction->dump(stream);
|
1325
|
+
}
|
1326
|
+
|
1327
|
+
LogSinkCache::const_iterator sit;
|
1328
|
+
LogSinkCache::const_iterator send = logSinkCache.end();
|
1329
|
+
stream << "Log sinks: " << logSinkCache.size() <<
|
1330
|
+
" (" << inactiveLogSinksCount << " inactive)\n";
|
1331
|
+
for (sit = logSinkCache.begin(); sit != send; sit++) {
|
1332
|
+
const LogSinkPtr &logSink = sit->second;
|
1333
|
+
logSink->dump(stream);
|
1334
|
+
}
|
1335
|
+
}
|
1336
|
+
};
|
1337
|
+
|
1338
|
+
typedef shared_ptr<LoggingServer> LoggingServerPtr;
|
1339
|
+
|
1340
|
+
|
1341
|
+
} // namespace Passenger
|
1342
|
+
|
1343
|
+
#endif /* _PASSENGER_LOGGING_SERVER_H_ */
|