diff options
Diffstat (limited to 'src/mongo/util/signal_handlers.cpp')
-rw-r--r-- | src/mongo/util/signal_handlers.cpp | 214 |
1 files changed, 106 insertions, 108 deletions
diff --git a/src/mongo/util/signal_handlers.cpp b/src/mongo/util/signal_handlers.cpp index ab34d0033f1..72c720a8900 100644 --- a/src/mongo/util/signal_handlers.cpp +++ b/src/mongo/util/signal_handlers.cpp @@ -53,63 +53,63 @@ #if defined(_WIN32) namespace { - const char* strsignal(int signalNum) { - // should only see SIGABRT on windows - switch (signalNum) { - case SIGABRT: return "SIGABRT"; - default: return "UNKNOWN"; - } +const char* strsignal(int signalNum) { + // should only see SIGABRT on windows + switch (signalNum) { + case SIGABRT: + return "SIGABRT"; + default: + return "UNKNOWN"; } } +} #endif namespace mongo { - using std::endl; - - /* - * WARNING: PLEASE READ BEFORE CHANGING THIS MODULE - * - * All code in this module must be signal-friendly. Before adding any system - * call or other dependency, please make sure that this still holds. - * - * All code in this file follows this pattern: - * Generic code - * #ifdef _WIN32 - * Windows code - * #else - * Posix code - * #endif - * - */ +using std::endl; + +/* + * WARNING: PLEASE READ BEFORE CHANGING THIS MODULE + * + * All code in this module must be signal-friendly. Before adding any system + * call or other dependency, please make sure that this still holds. + * + * All code in this file follows this pattern: + * Generic code + * #ifdef _WIN32 + * Windows code + * #else + * Posix code + * #endif + * + */ namespace { #ifdef _WIN32 - void consoleTerminate( const char* controlCodeName ) { - Client::initThread( "consoleTerminate" ); - - log() << "got " << controlCodeName << ", will terminate after current cmd ends" << endl; - exitCleanly( EXIT_KILL ); - } - - BOOL WINAPI CtrlHandler( DWORD fdwCtrlType ) { +void consoleTerminate(const char* controlCodeName) { + Client::initThread("consoleTerminate"); - switch( fdwCtrlType ) { + log() << "got " << controlCodeName << ", will terminate after current cmd ends" << endl; + exitCleanly(EXIT_KILL); +} +BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { + switch (fdwCtrlType) { case CTRL_C_EVENT: log() << "Ctrl-C signal"; - consoleTerminate( "CTRL_C_EVENT" ); - return TRUE ; + consoleTerminate("CTRL_C_EVENT"); + return TRUE; case CTRL_CLOSE_EVENT: log() << "CTRL_CLOSE_EVENT signal"; - consoleTerminate( "CTRL_CLOSE_EVENT" ); - return TRUE ; + consoleTerminate("CTRL_CLOSE_EVENT"); + return TRUE; case CTRL_BREAK_EVENT: log() << "CTRL_BREAK_EVENT signal"; - consoleTerminate( "CTRL_BREAK_EVENT" ); + consoleTerminate("CTRL_BREAK_EVENT"); return TRUE; case CTRL_LOGOFF_EVENT: @@ -118,60 +118,58 @@ namespace { case CTRL_SHUTDOWN_EVENT: log() << "CTRL_SHUTDOWN_EVENT signal"; - consoleTerminate( "CTRL_SHUTDOWN_EVENT" ); + consoleTerminate("CTRL_SHUTDOWN_EVENT"); return TRUE; default: return FALSE; - } } +} - void eventProcessingThread() { - std::string eventName = getShutdownSignalName(ProcessId::getCurrent().asUInt32()); +void eventProcessingThread() { + std::string eventName = getShutdownSignalName(ProcessId::getCurrent().asUInt32()); - HANDLE event = CreateEventA(NULL, TRUE, FALSE, eventName.c_str()); - if (event == NULL) { - warning() << "eventProcessingThread CreateEvent failed: " - << errnoWithDescription(); - return; - } + HANDLE event = CreateEventA(NULL, TRUE, FALSE, eventName.c_str()); + if (event == NULL) { + warning() << "eventProcessingThread CreateEvent failed: " << errnoWithDescription(); + return; + } + + ON_BLOCK_EXIT(CloseHandle, event); - ON_BLOCK_EXIT(CloseHandle, event); - - int returnCode = WaitForSingleObject(event, INFINITE); - if (returnCode != WAIT_OBJECT_0) { - if (returnCode == WAIT_FAILED) { - warning() << "eventProcessingThread WaitForSingleObject failed: " - << errnoWithDescription(); - return; - } - else { - warning() << "eventProcessingThread WaitForSingleObject failed: " - << errnoWithDescription(returnCode); - return; - } + int returnCode = WaitForSingleObject(event, INFINITE); + if (returnCode != WAIT_OBJECT_0) { + if (returnCode == WAIT_FAILED) { + warning() << "eventProcessingThread WaitForSingleObject failed: " + << errnoWithDescription(); + return; + } else { + warning() << "eventProcessingThread WaitForSingleObject failed: " + << errnoWithDescription(returnCode); + return; } + } - Client::initThread("eventTerminate"); + Client::initThread("eventTerminate"); - log() << "shutdown event signaled, will terminate after current cmd ends"; - exitCleanly(EXIT_CLEAN); - } + log() << "shutdown event signaled, will terminate after current cmd ends"; + exitCleanly(EXIT_CLEAN); +} #else - // The signals in asyncSignals will be processed by this thread only, in order to - // ensure the db and log mutexes aren't held. Because this is run in a different thread, it does - // not need to be safe to call in signal context. - sigset_t asyncSignals; - void signalProcessingThread() { - Client::initThread( "signalProcessingThread" ); - - while (true) { - int actualSignal = 0; - int status = sigwait( &asyncSignals, &actualSignal ); - fassert(16781, status == 0); - switch (actualSignal) { +// The signals in asyncSignals will be processed by this thread only, in order to +// ensure the db and log mutexes aren't held. Because this is run in a different thread, it does +// not need to be safe to call in signal context. +sigset_t asyncSignals; +void signalProcessingThread() { + Client::initThread("signalProcessingThread"); + + while (true) { + int actualSignal = 0; + int status = sigwait(&asyncSignals, &actualSignal); + fassert(16781, status == 0); + switch (actualSignal) { case SIGUSR1: // log rotate signal fassert(16782, rotateLogs(serverGlobalParams.logRenameOnRotate)); @@ -179,55 +177,55 @@ namespace { break; default: // interrupt/terminate signal - log() << "got signal " << actualSignal << " (" << strsignal( actualSignal ) + log() << "got signal " << actualSignal << " (" << strsignal(actualSignal) << "), will terminate after current cmd ends" << endl; - exitCleanly( EXIT_CLEAN ); + exitCleanly(EXIT_CLEAN); break; - } } } +} #endif -} // namespace +} // namespace - void setupSignalHandlers(bool handleControlC) { - setupSynchronousSignalHandlers(); +void setupSignalHandlers(bool handleControlC) { + setupSynchronousSignalHandlers(); #ifdef _WIN32 - if (!handleControlC) { - massert(10297, + if (!handleControlC) { + massert(10297, "Couldn't register Windows Ctrl-C handler", SetConsoleCtrlHandler(static_cast<PHANDLER_ROUTINE>(CtrlHandler), TRUE)); - } + } #else - // asyncSignals is a global variable listing the signals that should be handled by the - // interrupt thread, once it is started via startSignalProcessingThread(). - sigemptyset( &asyncSignals ); - sigaddset( &asyncSignals, SIGHUP ); - if (!handleControlC) { - sigaddset( &asyncSignals, SIGINT ); - } - sigaddset( &asyncSignals, SIGTERM ); - sigaddset( &asyncSignals, SIGUSR1 ); - sigaddset( &asyncSignals, SIGXCPU ); -#endif + // asyncSignals is a global variable listing the signals that should be handled by the + // interrupt thread, once it is started via startSignalProcessingThread(). + sigemptyset(&asyncSignals); + sigaddset(&asyncSignals, SIGHUP); + if (!handleControlC) { + sigaddset(&asyncSignals, SIGINT); } + sigaddset(&asyncSignals, SIGTERM); + sigaddset(&asyncSignals, SIGUSR1); + sigaddset(&asyncSignals, SIGXCPU); +#endif +} - void startSignalProcessingThread() { +void startSignalProcessingThread() { #ifdef _WIN32 - stdx::thread(eventProcessingThread).detach(); + stdx::thread(eventProcessingThread).detach(); #else - // Mask signals in the current (only) thread. All new threads will inherit this mask. - invariant( pthread_sigmask( SIG_SETMASK, &asyncSignals, 0 ) == 0 ); - // Spawn a thread to capture the signals we just masked off. - stdx::thread( signalProcessingThread ).detach(); + // Mask signals in the current (only) thread. All new threads will inherit this mask. + invariant(pthread_sigmask(SIG_SETMASK, &asyncSignals, 0) == 0); + // Spawn a thread to capture the signals we just masked off. + stdx::thread(signalProcessingThread).detach(); #endif - } +} #ifdef _WIN32 - void removeControlCHandler() { - massert(28600, +void removeControlCHandler() { + massert(28600, "Couldn't unregister Windows Ctrl-C handler", SetConsoleCtrlHandler(static_cast<PHANDLER_ROUTINE>(CtrlHandler), FALSE)); - } +} #endif -} // namespace mongo +} // namespace mongo |