Commit 8792391e authored by Simon Marlow's avatar Simon Marlow
Browse files

Add a mutex around stg_sig_install

Protects against a race when two threads call installHandler
simultaneously.  This was causing occasional failure of the test
libraries/process/tests/3231(threaded2).
parent fa168a3b
......@@ -65,6 +65,39 @@ static StgInt nHandlers = 0; /* Size of handlers array */
static nat n_haskell_handlers = 0;
static sigset_t userSignals;
static sigset_t savedSignals;
#ifdef THREADED_RTS
static Mutex sig_mutex; // protects signal_handlers, nHandlers
#endif
/* -----------------------------------------------------------------------------
* Initialisation / deinitialisation
* -------------------------------------------------------------------------- */
void
initUserSignals(void)
{
sigemptyset(&userSignals);
#ifdef THREADED_RTS
initMutex(&sig_mutex);
#endif
}
void
freeSignalHandlers(void) {
if (signal_handlers != NULL) {
stgFree(signal_handlers);
signal_handlers = NULL;
nHandlers = 0;
n_haskell_handlers = 0;
}
#ifdef THREADED_RTS
closeMutex(&sig_mutex);
#endif
}
/* -----------------------------------------------------------------------------
* Allocate/resize the table of signal handlers.
* -------------------------------------------------------------------------- */
......@@ -260,15 +293,6 @@ generic_handler(int sig USED_IF_THREADS,
* Blocking/Unblocking of the user signals
* -------------------------------------------------------------------------- */
static sigset_t userSignals;
static sigset_t savedSignals;
void
initUserSignals(void)
{
sigemptyset(&userSignals);
}
void
blockUserSignals(void)
{
......@@ -312,11 +336,14 @@ stg_sig_install(int sig, int spi, void *mask)
struct sigaction action;
StgInt previous_spi;
ACQUIRE_LOCK(&sig_mutex);
// Block the signal until we figure out what to do
// Count on this to fail if the signal number is invalid
if (sig < 0 || sigemptyset(&signals) ||
sigaddset(&signals, sig) || sigprocmask(SIG_BLOCK, &signals, &osignals)) {
return STG_SIG_ERR;
RELEASE_LOCK(&sig_mutex);
return STG_SIG_ERR;
}
more_handlers(sig);
......@@ -356,7 +383,8 @@ stg_sig_install(int sig, int spi, void *mask)
if (sigaction(sig, &action, NULL))
{
errorBelch("sigaction");
return STG_SIG_ERR;
RELEASE_LOCK(&sig_mutex);
return STG_SIG_ERR;
}
signal_handlers[sig] = spi;
......@@ -381,9 +409,11 @@ stg_sig_install(int sig, int spi, void *mask)
if (sigprocmask(SIG_SETMASK, &osignals, NULL))
{
errorBelch("sigprocmask");
return STG_SIG_ERR;
RELEASE_LOCK(&sig_mutex);
return STG_SIG_ERR;
}
RELEASE_LOCK(&sig_mutex);
return previous_spi;
}
......@@ -636,11 +666,4 @@ resetDefaultHandlers(void)
set_sigtstp_action(rtsFalse);
}
void
freeSignalHandlers(void) {
if (signal_handlers != NULL) {
stgFree(signal_handlers);
}
}
#endif /* RTS_USER_SIGNALS */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment