]> Savannah Git Hosting - gnulib.git/commitdiff
fatal-signal: Make multithread-safe.
authorBruno Haible <bruno@clisp.org>
Sat, 27 Jun 2020 21:17:38 +0000 (23:17 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 27 Jun 2020 21:17:38 +0000 (23:17 +0200)
* 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
lib/fatal-signal.c
modules/fatal-signal

index 19e609e31c6915b2c1ba105918d09dc26fcbfce1..aefe56392d00eeeae60489699de79f1451933e45 100644 (file)
--- 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
index c8ff33804103eb20327217c499eba2675cedd76a..975393b4a0ebde18eeac36bf21f75cab82b46d90 100644 (file)
@@ -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);
 }
 
 
index 6683c7993449c0cc6a558a916d7262e1c83f053d..de53de7c8b9a92d427d88e441399d93a159eb6ab 100644 (file)
@@ -12,6 +12,7 @@ xalloc
 stdbool
 unistd
 sigaction
+lock
 sigprocmask
 raise