Permalink
Browse files

SERVER-2833 -- shut down cleanly on OS or Service Controller shutdown…

… event

Added code to log shutdown events from the Windows Service Controller
and to respond correctly to those events.  Shutdown from the console
on logoff or shutdown callbacks (stop ignoring them).
  • Loading branch information...
1 parent ef11f57 commit e1504ed07ff7c4b0f1c96da32c36ecf607ac0229 @tadmarshall tadmarshall committed Jun 10, 2012
Showing with 51 additions and 19 deletions.
  1. +25 −15 db/db.cpp
  2. +9 −0 db/instance.cpp
  3. +1 −0 pch.h
  4. +16 −4 util/ntservice.cpp
View
@@ -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;
}
View
@@ -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);
View
1 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 ,
View
@@ -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;
}
}

0 comments on commit e1504ed

Please sign in to comment.