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:
parent
935b1251da
commit
230cbdb4e1
@ -68,10 +68,11 @@ public:
|
|||||||
void enable() throw() { }
|
void enable() throw() { }
|
||||||
#endif
|
#endif
|
||||||
private:
|
private:
|
||||||
// Forbid copy constructor
|
// Forbid copy constructor & assignment
|
||||||
SignalInhibit(const SignalInhibit&);
|
SignalInhibit(const SignalInhibit&);
|
||||||
|
SignalInhibit& operator=(const SignalInhibit&);
|
||||||
#ifndef WIN_NT
|
#ifndef WIN_NT
|
||||||
bool enabled;
|
bool locked;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -166,39 +166,44 @@ void ISC_enter(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
volatile sig_atomic_t inhibit_counter = 0;
|
volatile int inhibitCounter = 0;
|
||||||
sigset_t saved_sigmask;
|
|
||||||
Firebird::Mutex inhibitMutex;
|
Firebird::Mutex inhibitMutex;
|
||||||
|
sigset_t savedSigmask;
|
||||||
|
volatile bool inSignalHandler = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalInhibit::SignalInhibit() throw()
|
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);
|
Firebird::MutexLockGuard lock(inhibitMutex);
|
||||||
|
|
||||||
if (inhibit_counter == 0) {
|
if (inhibitCounter == 0) {
|
||||||
sigset_t set, oset;
|
sigset_t set;
|
||||||
sigfillset(&set);
|
sigfillset(&set);
|
||||||
sigprocmask(SIG_BLOCK, &set, &saved_sigmask);
|
sigprocmask(SIG_BLOCK, &set, &savedSigmask);
|
||||||
}
|
}
|
||||||
inhibit_counter++;
|
inhibitCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignalInhibit::enable() throw()
|
void SignalInhibit::enable() throw()
|
||||||
{
|
{
|
||||||
if (enabled)
|
if (!locked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
enabled = true;
|
locked = false;
|
||||||
|
|
||||||
Firebird::MutexLockGuard lock(inhibitMutex);
|
Firebird::MutexLockGuard lock(inhibitMutex);
|
||||||
|
|
||||||
fb_assert(inhibit_counter > 0);
|
fb_assert(inhibitCounter > 0);
|
||||||
inhibit_counter--;
|
inhibitCounter--;
|
||||||
if (inhibit_counter == 0) {
|
if (inhibitCounter == 0) {
|
||||||
// Return to the mask as it were before the first recursive
|
// Return to the mask as it were before the first recursive
|
||||||
// call to ISC_inhibit
|
// 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. */
|
/* 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)
|
for (SIG sig = signals; sig; sig = sig->sig_next)
|
||||||
{
|
{
|
||||||
if (sig->sig_signal == number)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user