]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
sigprocmask: Make multithread-safe on native Windows.
authorBruno Haible <bruno@clisp.org>
Fri, 16 May 2025 13:51:13 +0000 (15:51 +0200)
committerBruno Haible <bruno@clisp.org>
Fri, 16 May 2025 13:51:13 +0000 (15:51 +0200)
* lib/sigprocmask.c: Include glthread/lock.h.
(sig_lock): New variable.
(blocked_set): Remove 'volatile'.
(sigprocmask, _gl_raise_SIGPIPE): Use the sig_lock.
* modules/sigprocmask (Depends-on): Add lock.
* doc/posix-functions/sigprocmask.texi: Mention the async-safety issue.

ChangeLog
doc/posix-functions/sigprocmask.texi
lib/sigprocmask.c
modules/sigprocmask

index 95323c3a1941e8f79694415c3b0b8253ee9aa384..25cced87c65be06e22f6a8e6b506924f630d041c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2025-05-16  Bruno Haible  <bruno@clisp.org>
+
+       sigprocmask: Make multithread-safe on native Windows.
+       * lib/sigprocmask.c: Include glthread/lock.h.
+       (sig_lock): New variable.
+       (blocked_set): Remove 'volatile'.
+       (sigprocmask, _gl_raise_SIGPIPE): Use the sig_lock.
+       * modules/sigprocmask (Depends-on): Add lock.
+       * doc/posix-functions/sigprocmask.texi: Mention the async-safety issue.
+
 2025-05-16  Bruno Haible  <bruno@clisp.org>
 
        pthread-rwlock tests: Add a comment.
index 7683986b3fef21f8583e9bad266afacc68e90b0c..02bc537614f9588b1f22132baab7f8f4daf9a7e8 100644 (file)
@@ -28,3 +28,9 @@ multi-threaded programs, in practice it is essentially equivalent to
 return convention.  It's simpler to use @code{sigprocmask}, since it does
 not require linking with @code{-lpthread} on some platforms:
 glibc, NetBSD, OpenBSD, AIX.
+
+Note: While on POSIX platforms, @code{sigprocmask} is multithread-safe
+and async-signal safe (cf. POSIX section ``Signal Actions''
+@url{https://pubs.opengroup.org/onlinepubs/9799919799/functions/V2_chap02.html#tag_16_04_03}),
+the gnulib replacement on native Windows is only multithread-safe,
+not async-signal safe.
index f79386c8d02fa491dbc08ff3ef3d4a401d322320..d52e191c442c2dccf5242d1345f05191ee6306db 100644 (file)
@@ -24,6 +24,8 @@
 #include <stdint.h>
 #include <stdlib.h>
 
+#include "glthread/lock.h"
+
 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
 # include "msvc-inval.h"
 #endif
@@ -84,6 +86,10 @@ signal_nothrow (int sig, handler_t handler)
 # define signal signal_nothrow
 #endif
 
+/* This lock protects the variables defined in this file from concurrent
+   modification in multiple threads.  */
+gl_lock_define_initialized(static, sig_lock)
+
 /* Handling of gnulib defined signals.  */
 
 #if GNULIB_defined_SIGPIPE
@@ -182,7 +188,7 @@ sigfillset (sigset_t *set)
 }
 
 /* Set of currently blocked signals.  */
-static volatile sigset_t blocked_set /* = 0 */;
+static sigset_t blocked_set /* = 0 */;
 
 /* Set of currently blocked and pending signals.  */
 static volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */;
@@ -221,6 +227,8 @@ static volatile handler_t old_handlers[NSIG];
 int
 sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
 {
+  gl_lock_lock (sig_lock);
+
   if (old_set != NULL)
     *old_set = blocked_set;
 
@@ -242,6 +250,7 @@ sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
           new_blocked_set = blocked_set & ~*set;
           break;
         default:
+          gl_lock_unlock (sig_lock);
           errno = EINVAL;
           return -1;
         }
@@ -286,6 +295,8 @@ sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
               raise (sig);
         }
     }
+
+  gl_lock_unlock (sig_lock);
   return 0;
 }
 
@@ -334,11 +345,16 @@ rpl_signal (int sig, handler_t handler)
 int
 _gl_raise_SIGPIPE (void)
 {
+  gl_lock_lock (sig_lock);
   if (blocked_set & (1U << SIGPIPE))
-    pending_array[SIGPIPE] = 1;
+    {
+      pending_array[SIGPIPE] = 1;
+      gl_lock_unlock (sig_lock);
+    }
   else
     {
       handler_t handler = SIGPIPE_handler;
+      gl_lock_unlock (sig_lock);
       if (handler == SIG_DFL)
         exit (128 + SIGPIPE);
       else if (handler != SIG_IGN)
index 7f2e08380341bde0782f368da9e5c0091031896c..79e7c7302f78beec3f437a18b36a1304b335e0b9 100644 (file)
@@ -8,6 +8,7 @@ m4/signalblocking.m4
 Depends-on:
 signal-h
 stdint-h        [test $HAVE_POSIX_SIGNALBLOCKING = 0]
+lock            [test $HAVE_POSIX_SIGNALBLOCKING = 0]
 raise           [test $HAVE_POSIX_SIGNALBLOCKING = 0]
 msvc-inval      [test $HAVE_POSIX_SIGNALBLOCKING = 0]