summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/db.cpp40
-rw-r--r--db/instance.cpp9
-rw-r--r--pch.h1
-rw-r--r--util/ntservice.cpp20
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);
diff --git a/pch.h b/pch.h
index 1211e26adc6..6cf2f462876 100644
--- a/pch.h
+++ b/pch.h
@@ -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;
}
}