Paul Eggert wrote: > For years, POSIX has recommended that multithreaded apps use > pthread_sigmask instead of sigprocmask.
The module 'asyncsafe-spin' is also easy to handle, because the comment in lib/asyncsafe-spin.h indicates that the code was meant to use pthread_sigmask, and sigprocmask was actually used only to avoid a link requirement. 2026-04-04 Bruno Haible <[email protected]> asyncsafe-spin: Prefer pthread_sigmask over sigprocmask. Suggested by Paul Eggert. * lib/asyncsafe-spin.c (asyncsafe_spin_lock, asyncsafe_spin_unlock): Use pthread_sigmask instead of sigprocmask. * modules/asyncsafe-spin (Depends-on): Add pthread_sigmask. Remove sigprocmask. (Link): New section. * modules/asyncsafe-spin-tests (Makefile.am): Link test-asyncsafe-spin1 with $(PTHREAD_SIGMASK_LIB). * modules/jit/cache-tests (Makefile.am): Link test-cache with $(PTHREAD_SIGMASK_LIB). diff --git a/lib/asyncsafe-spin.c b/lib/asyncsafe-spin.c index 8400ad87a3..1c2c5950a7 100644 --- a/lib/asyncsafe-spin.c +++ b/lib/asyncsafe-spin.c @@ -42,22 +42,19 @@ asyncsafe_spin_lock (asyncsafe_spinlock_t *lock, On platforms other than native Windows, it is useful to do the same thing also within a signal handler, since signals may remain enabled while a signal handler runs. It is possible to do this because - sigprocmask() is safe to call from within a signal handler, see + pthread_sigmask() is safe to call from within a signal handler, see POSIX section "Signal Actions" <https://pubs.opengroup.org/onlinepubs/9799919799/functions/V2_chap02.html#tag_16_04_03>. - (In other words, sigprocmask() is atomic, because it is implemented as a + (In other words, pthread_sigmask() is atomic, because it is implemented as a system call.) - Whereas on native Windows, sigprocmask() is not atomic, because it - manipulates global variables. Therefore in this case, we are *not* - allowed to call it from within a signal handler. */ + Whereas on native Windows, pthread_sigmask() = sigprocmask() is not atomic, + because it manipulates global variables. Therefore in this case, we are + *not* allowed to call it from within a signal handler. */ - /* FIXME: Use pthread_sigmask, not sigprocmask, as the two functions - behave differently on macOS and the sigprocmask behavior can cause - this thread to race with other threads in harmful ways. */ #if defined _WIN32 && !defined __CYGWIN__ if (!from_signal_handler) #endif - sigprocmask (SIG_BLOCK, mask, saved_mask); + pthread_sigmask (SIG_BLOCK, mask, saved_mask); glthread_spinlock_lock (lock); } @@ -70,13 +67,10 @@ asyncsafe_spin_unlock (asyncsafe_spinlock_t *lock, if (glthread_spinlock_unlock (lock)) abort (); - /* FIXME: Use pthread_sigmask, not sigprocmask, as the two functions - behave differently on macOS and the sigprocmask behavior can cause - this thread to race with other threads in harmful ways. */ #if defined _WIN32 && !defined __CYGWIN__ if (!from_signal_handler) #endif - sigprocmask (SIG_SETMASK, saved_mask, NULL); + pthread_sigmask (SIG_SETMASK, saved_mask, NULL); } void diff --git a/modules/asyncsafe-spin b/modules/asyncsafe-spin index 9c3d0097f1..c90cf2a336 100644 --- a/modules/asyncsafe-spin +++ b/modules/asyncsafe-spin @@ -7,8 +7,8 @@ lib/asyncsafe-spin.c Depends-on: signal-h +pthread_sigmask bool -sigprocmask spin configure.ac: @@ -19,6 +19,9 @@ lib_SOURCES += asyncsafe-spin.c Include: "asyncsafe-spin.h" +Link: +$(PTHREAD_SIGMASK_LIB) + License: LGPLv2+ diff --git a/modules/asyncsafe-spin-tests b/modules/asyncsafe-spin-tests index dacb26aaac..c39d11438d 100644 --- a/modules/asyncsafe-spin-tests +++ b/modules/asyncsafe-spin-tests @@ -18,4 +18,5 @@ AC_REQUIRE([gl_SEMAPHORE]) Makefile.am: TESTS += test-asyncsafe-spin1 test-asyncsafe-spin2 check_PROGRAMS += test-asyncsafe-spin1 test-asyncsafe-spin2 +test_asyncsafe_spin1_LDADD = $(LDADD) @PTHREAD_SIGMASK_LIB@ test_asyncsafe_spin2_LDADD = $(LDADD) @LIBMULTITHREAD@ @YIELD_LIB@ @LIB_SEMAPHORE@ diff --git a/modules/jit/cache-tests b/modules/jit/cache-tests index 36fe90b8e9..360d184723 100644 --- a/modules/jit/cache-tests +++ b/modules/jit/cache-tests @@ -31,4 +31,4 @@ TESTS += test-cache check_PROGRAMS += test-cache test_cache_SOURCES = jit/test-cache.c test_cache_CFLAGS = $(AM_CFLAGS) $(DISABLE_OPENBSD_RETGUARD) -test_cache_LDADD = $(LDADD) $(LIBINTL) @LIBDL@ +test_cache_LDADD = $(LDADD) $(LIBINTL) $(PTHREAD_SIGMASK_LIB) @LIBDL@
