From: Timo Sirainen Date: Tue, 14 Sep 2010 16:38:08 +0000 (+0100) Subject: Added signal_term_counter that keeps track of how many terminal signals have been... X-Git-Tag: 2.0.3~15 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4c5004b5348c8d6122d90ae296c563bf4d32a644;p=thirdparty%2Fdovecot%2Fcore.git Added signal_term_counter that keeps track of how many terminal signals have been received. --- diff --git a/src/lib/lib-signals.c b/src/lib/lib-signals.c index 803dd24588..777c3ff45d 100644 --- a/src/lib/lib-signals.c +++ b/src/lib/lib-signals.c @@ -11,6 +11,9 @@ #define MAX_SIGNAL_VALUE 31 +#define SIGNAL_IS_TERMINAL(signo) \ + ((signo) == SIGINT || (signo) == SIGQUIT || (signo) == SIGTERM) + #if !defined(SA_SIGINFO) && !defined(SI_NOINFO) /* without SA_SIGINFO we don't know what the real code is. we need SI_NOINFO to make sure lib_signal_code_to_str() returns "". */ @@ -25,6 +28,8 @@ struct signal_handler { struct signal_handler *next; }; +volatile unsigned int signal_term_counter = 0; + /* Remember that these are accessed inside signal handler which may be called even while we're initializing/deinitializing. Try hard to keep everything in consistent state. */ @@ -112,6 +117,9 @@ static void sig_handler(int signo) if (signo < 0 || signo > MAX_SIGNAL_VALUE) return; + if (SIGNAL_IS_TERMINAL(signo)) + signal_term_counter++; + /* remember that we're inside a signal handler which might have been called at any time. don't do anything that's unsafe. we might also get interrupted by another signal while inside this handler. */ diff --git a/src/lib/lib-signals.h b/src/lib/lib-signals.h index 6da0c7de29..bf57172e62 100644 --- a/src/lib/lib-signals.h +++ b/src/lib/lib-signals.h @@ -5,6 +5,17 @@ typedef void signal_handler_t(const siginfo_t *si, void *context); +/* Number of times a "termination signal" has been received. + These signals are SIGINT, SIGQUIT and SIGTERM. Callers can compare this to + their saved previous value to see if a syscall returning EINTR should be + treated as someone wanting to end the process or just some internal signal + that should be ignored, such as SIGCHLD. + + This is marked as volatile so that compiler won't optimize away its + comparisons. It may not work perfectly everywhere, such as when accessing it + isn't atomic, so you shouldn't heavily rely on its actual value. */ +extern volatile unsigned int signal_term_counter; + /* Convert si_code to string */ const char *lib_signal_code_to_str(int signo, int sicode);