bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: fatal-signal: make multithread-safe


From: Bruno Haible
Subject: Re: fatal-signal: make multithread-safe
Date: Sat, 04 Jul 2020 12:45:53 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-179-generic; KDE/5.18.0; x86_64; ; )

Another multithread-safety issue was lurking in module 'fatal-signal'.
This patch fixes it.


2020-07-04  Bruno Haible  <bruno@clisp.org>

        fatal-signal: Make multithread-safe.
        * lib/fatal-signal.c (init_fatal_signals): Add comment.
        (do_init_fatal_signal_set): New function, extracted from
        init_fatal_signal_set.
        (fatal_signal_set_once): New variable.
        (init_fatal_signal_set): Use gl_once.

diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c
index c6f8dac..8b27cc6 100644
--- a/lib/fatal-signal.c
+++ b/lib/fatal-signal.c
@@ -86,6 +86,10 @@ static int fatal_signals[] =
 static void
 init_fatal_signals (void)
 {
+  /* This function is multithread-safe even without synchronization, because
+     if two threads execute it simultaneously, the fatal_signals[] array will
+     not change any more after the first of the threads has completed this
+     function.  */
   static bool fatal_signals_initialized = false;
   if (!fatal_signals_initialized)
     {
@@ -266,22 +270,25 @@ at_fatal_signal (action_t action)
 static sigset_t fatal_signal_set;
 
 static void
-init_fatal_signal_set (void)
+do_init_fatal_signal_set (void)
 {
-  static bool fatal_signal_set_initialized = false;
-  if (!fatal_signal_set_initialized)
-    {
-      size_t i;
+  size_t i;
 
-      init_fatal_signals ();
+  init_fatal_signals ();
 
-      sigemptyset (&fatal_signal_set);
-      for (i = 0; i < num_fatal_signals; i++)
-        if (fatal_signals[i] >= 0)
-          sigaddset (&fatal_signal_set, fatal_signals[i]);
+  sigemptyset (&fatal_signal_set);
+  for (i = 0; i < num_fatal_signals; i++)
+    if (fatal_signals[i] >= 0)
+      sigaddset (&fatal_signal_set, fatal_signals[i]);
+}
 
-      fatal_signal_set_initialized = true;
-    }
+/* Ensure that do_init_fatal_signal_set is called once only.  */
+gl_once_define(static, fatal_signal_set_once)
+
+static void
+init_fatal_signal_set (void)
+{
+  gl_once (fatal_signal_set_once, do_init_fatal_signal_set);
 }
 
 /* Lock and counter that allow block_fatal_signals/unblock_fatal_signals pairs




reply via email to

[Prev in Thread] Current Thread [Next in Thread]