From 73cc88eee5d39d04dcf8ac411720bf17ef7a75e4 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 27 Jun 2020 23:17:38 +0200 Subject: [PATCH] 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. --- ChangeLog | 10 ++++++++++ lib/fatal-signal.c | 39 +++++++++++++++++++++++++++++++++++---- modules/fatal-signal | 1 + 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19e609e31c..aefe56392d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2020-06-27 Bruno Haible + + 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. + 2020-06-27 Paul Eggert getloadavg: don’t depend on fopen-gnu diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c index c8ff338041..975393b4a0 100644 --- a/lib/fatal-signal.c +++ b/lib/fatal-signal.c @@ -26,6 +26,7 @@ #include #include +#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 6683c79934..de53de7c8b 100644 --- a/modules/fatal-signal +++ b/modules/fatal-signal @@ -12,6 +12,7 @@ xalloc stdbool unistd sigaction +lock sigprocmask raise -- 2.39.5