diff options
-rw-r--r-- | db/db.cpp | 40 | ||||
-rw-r--r-- | db/instance.cpp | 9 | ||||
-rw-r--r-- | pch.h | 1 | ||||
-rw-r--r-- | util/ntservice.cpp | 20 |
4 files changed, 51 insertions, 19 deletions
diff --git a/db/db.cpp b/db/db.cpp index 0a21f4d19af..2a08ff3db3e 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -1154,31 +1154,41 @@ namespace mongo { } #else - void ctrlCTerminate() { - log() << "got kill or ctrl-c signal, will terminate after current cmd ends" << endl; - Client::initThread( "ctrlCTerminate" ); + void consoleTerminate( const char* controlCodeName ) { + Client::initThread( "consoleTerminate" ); + log() << "got " << controlCodeName << ", will terminate after current cmd ends" << endl; exitCleanly( EXIT_KILL ); } + BOOL CtrlHandler( DWORD fdwCtrlType ) { + switch( fdwCtrlType ) { + case CTRL_C_EVENT: - rawOut("Ctrl-C signal"); - ctrlCTerminate(); - return( TRUE ); + rawOut( "Ctrl-C signal" ); + consoleTerminate( "CTRL_C_EVENT" ); + return TRUE ; + case CTRL_CLOSE_EVENT: - rawOut("CTRL_CLOSE_EVENT signal"); - ctrlCTerminate(); - return( TRUE ); + rawOut( "CTRL_CLOSE_EVENT signal" ); + consoleTerminate( "CTRL_CLOSE_EVENT" ); + return TRUE ; + case CTRL_BREAK_EVENT: - rawOut("CTRL_BREAK_EVENT signal"); - ctrlCTerminate(); + rawOut( "CTRL_BREAK_EVENT signal" ); + consoleTerminate( "CTRL_BREAK_EVENT" ); return TRUE; + case CTRL_LOGOFF_EVENT: - rawOut("CTRL_LOGOFF_EVENT signal (ignored)"); - return FALSE; + rawOut( "CTRL_LOGOFF_EVENT signal" ); + consoleTerminate( "CTRL_LOGOFF_EVENT" ); + return TRUE; + case CTRL_SHUTDOWN_EVENT: - rawOut("CTRL_SHUTDOWN_EVENT signal (ignored)"); - return FALSE; + rawOut( "CTRL_SHUTDOWN_EVENT signal" ); + consoleTerminate( "CTRL_SHUTDOWN_EVENT" ); + return TRUE; + default: return FALSE; } diff --git a/db/instance.cpp b/db/instance.cpp index 1d5d58921d4..d51886dd9d8 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -874,6 +874,15 @@ namespace mongo { } catch (...) { } +#ifdef _WIN32 + // Windows Service Controller wants to be told when we are down, + // so don't call ::exit() yet, or say "really exiting now" + // + if ( rc == EXIT_WINDOWS_SERVICE_STOP ) { + if ( c ) c->shutdown(); + return; + } +#endif tryToOutputFatal( "dbexit: really exiting now" ); if ( c ) c->shutdown(); ::exit(rc); @@ -129,6 +129,7 @@ namespace mongo { EXIT_FS = 45 , EXIT_CLOCK_SKEW = 47 , EXIT_NET_ERROR = 48 , + EXIT_WINDOWS_SERVICE_STOP = 49 , EXIT_POSSIBLE_CORRUPTION = 60 , // this means we detected a possible corruption situation, like a buf overflow EXIT_UNCAUGHT = 100 , // top level exception that wasn't caught EXIT_TEST = 101 , diff --git a/util/ntservice.cpp b/util/ntservice.cpp index 4b21b8caecf..03c159ebe1d 100644 --- a/util/ntservice.cpp +++ b/util/ntservice.cpp @@ -17,6 +17,7 @@ #include "pch.h" #include "ntservice.h" +#include "../db/client.h" #include "winutil.h" #include "text.h" #include <direct.h> @@ -348,14 +349,25 @@ namespace mongo { reportStatus( SERVICE_STOPPED ); } + static void serviceShutdown( const char* controlCodeName ) { + Client::initThread( "serviceShutdown" ); + log() << "got " << controlCodeName << " request from Windows Service Controller, " << + ( inShutdown() ? "already in shutdown" : "will terminate after current cmd ends" ) << endl; + ServiceController::reportStatus( SERVICE_STOP_PENDING ); + if ( ! inShutdown() ) { + exitCleanly( EXIT_WINDOWS_SERVICE_STOP ); + ServiceController::reportStatus( SERVICE_STOPPED ); + } + } + void WINAPI ServiceController::serviceCtrl( DWORD ctrlCode ) { switch ( ctrlCode ) { case SERVICE_CONTROL_STOP: + serviceShutdown( "SERVICE_CONTROL_STOP" ); + break; case SERVICE_CONTROL_SHUTDOWN: - reportStatus( SERVICE_STOP_PENDING ); - shutdownServer(); - reportStatus( SERVICE_STOPPED ); - return; + serviceShutdown( "SERVICE_CONTROL_SHUTDOWN" ); + break; } } |