From edc71f54aec880b2f686de6488acac70eda8a92e Mon Sep 17 00:00:00 2001 From: alexpeshkoff Date: Fri, 22 Aug 2008 13:17:55 +0000 Subject: [PATCH] Backported fix for CORE-2049: Performance regression - too many sigprocmask() system calls --- src/jrd/os/isc_i_proto.h | 5 +-- src/jrd/os/posix/isc_ipc.cpp | 70 +++++++++++++++++++++++++----------- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/jrd/os/isc_i_proto.h b/src/jrd/os/isc_i_proto.h index 0271a9e002..54c23d38be 100644 --- a/src/jrd/os/isc_i_proto.h +++ b/src/jrd/os/isc_i_proto.h @@ -67,10 +67,11 @@ public: void enable() throw() { } #endif private: - // Forbid copy constructor + // Forbid copy constructor & assignment SignalInhibit(const SignalInhibit&); + SignalInhibit& operator=(const SignalInhibit&); #ifndef WIN_NT - bool enabled; + bool locked; #endif }; diff --git a/src/jrd/os/posix/isc_ipc.cpp b/src/jrd/os/posix/isc_ipc.cpp index f44fea5e14..16d855aa1c 100644 --- a/src/jrd/os/posix/isc_ipc.cpp +++ b/src/jrd/os/posix/isc_ipc.cpp @@ -36,7 +36,7 @@ * */ - /* $Id: isc_ipc.cpp,v 1.17.4.3 2008-06-27 11:28:48 alexpeshkoff Exp $ */ + /* $Id: isc_ipc.cpp,v 1.17.4.4 2008-08-22 13:17:55 alexpeshkoff Exp $ */ #include "firebird.h" #include @@ -168,42 +168,48 @@ void ISC_enter(void) } namespace { - volatile sig_atomic_t inhibit_counter = 0; - sigset_t saved_sigmask; + volatile sig_atomic_t inhibitCounter = 0; Firebird::Mutex inhibitMutex; + volatile bool inSignalHandler = false; + volatile FB_UINT64 pendingSignals = 0; } SignalInhibit::SignalInhibit() throw() - : enabled(false) + : locked(!inSignalHandler) // When called from signal handler, no need + // to care - signals are already inhibited. { + if (!locked) + return; + Firebird::MutexLockGuard lock(inhibitMutex); - if (inhibit_counter == 0) { - sigset_t set, oset; - sigfillset(&set); - sigprocmask(SIG_BLOCK, &set, &saved_sigmask); - } - inhibit_counter++; + ++inhibitCounter; } - void SignalInhibit::enable() throw() { - if (enabled) + if (!locked) return; - enabled = true; + locked = false; Firebird::MutexLockGuard lock(inhibitMutex); - fb_assert(inhibit_counter > 0); - inhibit_counter--; - if (inhibit_counter == 0) { - // Return to the mask as it were before the first recursive - // call to ISC_inhibit - sigprocmask(SIG_SETMASK, &saved_sigmask, NULL); + fb_assert(inhibitCounter > 0); + if (--inhibitCounter == 0) { + while (pendingSignals) + { + for (int n = 0; pendingSignals && n < 64; n++) + { + if (pendingSignals & (1 << n)) + { + pendingSignals &= ~(1 << n); + ISC_kill(process_id, n + 1); + } + } + } } -} +} void ISC_exit(void) @@ -461,6 +467,10 @@ static void cleanup(void* arg) **************************************/ signals = NULL; + pendingSignals = 0; + + inhibitCounter = 0; + process_id = 0; initialized_signals = false; @@ -558,6 +568,21 @@ static void CLIB_ROUTINE signal_handler(int number) * Checkin with various signal handlers. * **************************************/ + if (inhibitCounter > 0 && number != SIGALRM) + { + pendingSignals |= QUADCONST(1) << (number - 1); + return; + } + +#ifndef SUPERSERVER + // Save signal delivery status. + const bool restoreState = inSignalHandler; + inSignalHandler = true; + sigset_t set, localSavedSigmask; + sigfillset(&set); + sigprocmask(SIG_BLOCK, &set, &localSavedSigmask); +#endif + /* Invoke everybody who may have expressed an interest. */ for (SIG sig = signals; sig; sig = sig->sig_next) @@ -571,5 +596,10 @@ static void CLIB_ROUTINE signal_handler(int number) } else (*sig->sig_routine.user) (sig->sig_arg); + +#ifndef SUPERSERVER + sigprocmask(SIG_SETMASK, &localSavedSigmask, NULL); + inSignalHandler = restoreState; +#endif }