[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
fatal-signal: make multithread-safe
From: |
Bruno Haible |
Subject: |
fatal-signal: make multithread-safe |
Date: |
Sat, 27 Jun 2020 23:57:48 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-179-generic; KDE/5.18.0; x86_64; ; ) |
2020-06-27 Bruno Haible <bruno@clisp.org>
fatal-signal: Make multithread-safe.
* lib/fatal-signal.c: Include glthread/lock.h.
(at_fatal_signal_lock): New variable.
(at_fatal_signal): Use it.
(fatal_signals_block_lock, fatal_signals_block_counter): New variables.
(block_fatal_signals, unblock_fatal_signals): Use them.
* modules/fatal-signal (Depends-on): Add lock.
diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c
index c8ff338..975393b 100644
--- a/lib/fatal-signal.c
+++ b/lib/fatal-signal.c
@@ -26,6 +26,7 @@
#include <signal.h>
#include <unistd.h>
+#include "glthread/lock.h"
#include "sig-handler.h"
#include "xalloc.h"
@@ -200,11 +201,16 @@ install_handlers (void)
}
+/* Lock that makes at_fatal_signal multi-thread safe. */
+gl_lock_define_initialized (static, at_fatal_signal_lock)
+
/* Register a cleanup function to be executed when a catchable fatal signal
occurs. */
void
at_fatal_signal (action_t action)
{
+ gl_lock_lock (at_fatal_signal_lock);
+
static bool cleanup_initialized = false;
if (!cleanup_initialized)
{
@@ -242,6 +248,8 @@ at_fatal_signal (action_t action)
actions[actions_count]. */
actions[actions_count].action = action;
actions_count++;
+
+ gl_lock_unlock (at_fatal_signal_lock);
}
@@ -269,20 +277,43 @@ init_fatal_signal_set (void)
}
}
+/* Lock and counter that allow block_fatal_signals/unblock_fatal_signals pairs
+ to occur in different threads and even overlap in time. */
+gl_lock_define_initialized (static, fatal_signals_block_lock)
+static unsigned int fatal_signals_block_counter = 0;
+
/* Temporarily delay the catchable fatal signals. */
void
block_fatal_signals (void)
{
- init_fatal_signal_set ();
- sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
+ gl_lock_lock (fatal_signals_block_lock);
+
+ if (fatal_signals_block_counter++ == 0)
+ {
+ init_fatal_signal_set ();
+ sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
+ }
+
+ gl_lock_unlock (fatal_signals_block_lock);
}
/* Stop delaying the catchable fatal signals. */
void
unblock_fatal_signals (void)
{
- init_fatal_signal_set ();
- sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+ gl_lock_lock (fatal_signals_block_lock);
+
+ if (fatal_signals_block_counter == 0)
+ /* There are more calls to unblock_fatal_signals() than to
+ block_fatal_signals(). */
+ abort ();
+ if (--fatal_signals_block_counter == 0)
+ {
+ init_fatal_signal_set ();
+ sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+ }
+
+ gl_lock_unlock (fatal_signals_block_lock);
}
diff --git a/modules/fatal-signal b/modules/fatal-signal
index 6683c79..de53de7 100644
--- a/modules/fatal-signal
+++ b/modules/fatal-signal
@@ -12,6 +12,7 @@ xalloc
stdbool
unistd
sigaction
+lock
sigprocmask
raise
- fatal-signal: make multithread-safe,
Bruno Haible <=