From: Bruno Haible <bruno@clisp.org> Date: Sat, 27 Jun 2020 21:17:38 +0000 (+0200) Subject: fatal-signal: Make multithread-safe. X-Git-Tag: v1.0~3955 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=73cc88eee5d39d04dcf8ac411720bf17ef7a75e4;p=gnulib.git 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/ChangeLog b/ChangeLog index 19e609e31c..aefe56392d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +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. + 2020-06-27 Paul Eggert <eggert@cs.ucla.edu> 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 <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 6683c79934..de53de7c8b 100644 --- a/modules/fatal-signal +++ b/modules/fatal-signal @@ -12,6 +12,7 @@ xalloc stdbool unistd sigaction +lock sigprocmask raise