From e8ea40668b1f2dcc0d61760ad3bccd98e0d77b8c Mon Sep 17 00:00:00 2001 From: Eric Milkie Date: Thu, 18 Apr 2013 11:33:22 -0400 Subject: SERVER-4739 use a thread for logRotate signal instead of a signal handler --- src/mongo/db/cmdline.cpp | 5 ----- src/mongo/db/db.cpp | 25 +++++++++++++++++++------ src/mongo/s/server.cpp | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/mongo/db/cmdline.cpp b/src/mongo/db/cmdline.cpp index c070d6165b2..b40400d17e6 100644 --- a/src/mongo/db/cmdline.cpp +++ b/src/mongo/db/cmdline.cpp @@ -520,13 +520,8 @@ namespace mongo { void ignoreSignal( int sig ) {} - static void rotateLogsOrDie(int sig) { - fassert(16176, rotateLogs()); - } - void setupCoreSignals() { #if !defined(_WIN32) - verify( signal(SIGUSR1 , rotateLogsOrDie ) != SIG_ERR ); verify( signal(SIGHUP , ignoreSignal ) != SIG_ERR ); #endif } diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index e870e3793ed..fb3b9e28e53 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -1205,12 +1205,24 @@ namespace mongo { // The above signals will be processed by this thread only, in order to // ensure the db and log mutexes aren't held. void interruptThread() { - int actualSignal; - sigwait( &asyncSignals, &actualSignal ); - log() << "got signal " << actualSignal << " (" << strsignal( actualSignal ) - << "), will terminate after current cmd ends" << endl; - Client::initThread( "interruptThread" ); - exitCleanly( EXIT_CLEAN ); + while (true) { + int actualSignal = 0; + int status = sigwait( &asyncSignals, &actualSignal ); + fassert(16781, status == 0); + switch (actualSignal) { + case SIGUSR1: + // log rotate signal + fassert(16782, rotateLogs()); + break; + default: + // interrupt/terminate signal + Client::initThread( "signalProcessingThread" ); + log() << "got signal " << actualSignal << " (" << strsignal( actualSignal ) + << "), will terminate after current cmd ends" << endl; + exitCleanly( EXIT_CLEAN ); + break; + } + } } // this will be called in certain c++ error cases, for example if there are two active @@ -1256,6 +1268,7 @@ namespace mongo { sigemptyset( &asyncSignals ); sigaddset( &asyncSignals, SIGINT ); sigaddset( &asyncSignals, SIGTERM ); + sigaddset( &asyncSignals, SIGUSR1 ); verify( pthread_sigmask( SIG_SETMASK, &asyncSignals, 0 ) == 0 ); boost::thread it( interruptThread ); } diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp index 1fe98e05e97..b7c368e13d6 100644 --- a/src/mongo/s/server.cpp +++ b/src/mongo/s/server.cpp @@ -45,6 +45,7 @@ #include "../util/processinfo.h" #include "mongo/db/lasterror.h" #include "mongo/util/stacktrace.h" +#include "mongo/util/log.h" #if defined(_WIN32) # include "../util/ntservice.h" @@ -151,6 +152,33 @@ namespace mongo { ::_exit(EXIT_ABRUPT); } +#ifndef _WIN32 + sigset_t asyncSignals; + + void signalProcessingThread() { + while (true) { + int actualSignal = 0; + int status = sigwait( &asyncSignals, &actualSignal ); + fassert(16779, status == 0); + switch (actualSignal) { + case SIGUSR1: + // log rotate signal + fassert(16780, rotateLogs()); + break; + default: + // no one else should be here + fassertFailed(16778); + break; + } + } + } + + void startSignalProcessingThread() { + verify( pthread_sigmask( SIG_SETMASK, &asyncSignals, 0 ) == 0 ); + boost::thread it( signalProcessingThread ); + } +#endif + void setupSignals( bool inFork ) { signal(SIGTERM, sighandler); signal(SIGINT, sighandler); @@ -167,7 +195,11 @@ namespace mongo { #if defined(SIGPIPE) signal( SIGPIPE , SIG_IGN ); #endif - +#ifndef _WIN32 + sigemptyset( &asyncSignals ); + sigaddset( &asyncSignals, SIGUSR1 ); + startSignalProcessingThread(); +#endif set_new_handler( my_new_handler ); } -- cgit v1.2.1