8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 00:03:03 +01:00

Made classes SignalInhibit and AstInhibit async signal safe.

This commit is contained in:
alexpeshkoff 2007-08-10 13:55:41 +00:00
parent 935b1251da
commit 230cbdb4e1
2 changed files with 32 additions and 15 deletions

View File

@ -68,10 +68,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
};

View File

@ -166,39 +166,44 @@ void ISC_enter(void)
}
namespace {
volatile sig_atomic_t inhibit_counter = 0;
sigset_t saved_sigmask;
volatile int inhibitCounter = 0;
Firebird::Mutex inhibitMutex;
sigset_t savedSigmask;
volatile bool inSignalHandler = false;
}
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;
if (inhibitCounter == 0) {
sigset_t set;
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, &saved_sigmask);
sigprocmask(SIG_BLOCK, &set, &savedSigmask);
}
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) {
fb_assert(inhibitCounter > 0);
inhibitCounter--;
if (inhibitCounter == 0) {
// Return to the mask as it were before the first recursive
// call to ISC_inhibit
sigprocmask(SIG_SETMASK, &saved_sigmask, NULL);
sigprocmask(SIG_SETMASK, &savedSigmask, NULL);
}
}
@ -562,6 +567,13 @@ static void CLIB_ROUTINE signal_action(int number, siginfo_t *siginfo, void *con
**************************************/
/* Invoke everybody who may have expressed an interest. */
bool restoreState = inSignalHandler;
inSignalHandler = true;
sigset_t set, localSavedSigmask;
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, &localSavedSigmask);
for (SIG sig = signals; sig; sig = sig->sig_next)
{
if (sig->sig_signal == number)
@ -591,5 +603,9 @@ static void CLIB_ROUTINE signal_action(int number, siginfo_t *siginfo, void *con
}
}
}
sigprocmask(SIG_SETMASK, &localSavedSigmask, NULL);
inSignalHandler = restoreState;
}