On 2026-04-05 14:58, Bruno Haible wrote:
This looks right at first glance, but maybe a NEWS entry is warranted?

Sure, I installed the attached.


* fatal-signal: This module is used, for example, by 'clean-temp', whose
   purpose is to clean up a temporary file when a catchable fatal signal
   like SIGINT is received. To this effect, the code
     1. blocks the signal SIGINT,
     2. creates the temporary file,
     3. registers the temporary file in the data structures that are
        inspected when SIGINT is received,
     4. unblocks the signal SIGINT.
   In a single-threaded process, a SIGINT that comes in between steps 2 and 3
   is delayed until after step 4. This ensures that the temporary file gets
   deleted.
   But in a multi-threaded process, a SIGINT that comes in between steps 2 and 3
   is delivered through another thread and terminates the process, without
   having deleted the temporary file.

   The fix for this will be by blocking the signal SIGINT across all threads
   of the process. I'm attaching a draft module for this purpose, that I'm
   working on.

Would it be less invasive to put a spin lock (in addition to blocking the signal) around the critical section? That would avoid the need for sigaction fiddling with global process state, something that looks like it might cause trouble.


* term-style-control: When I modify the unit test 'test-term-style-control-yes'
   to install a second thread (that does nothing but nanosleep()), I see that
   test program dump core sometimes. This is because the SIGCONT signal handler
   is being executed in that second thread, in parallel to the main thread.

   The fix here will be to change the SIGCONT signal handler to redirect its
   execution to the main thread.

Yes, that's what Emacs does. It ships signals off to the main thread. See emacs/src/sysdep.c's deliver_process_signal.

A couple of things. First, surely these signals should be sent to the thread that invoked the term-style-control functions, which might not be the main thread.

Second, if we have a way to deliver signals to a particular thread, maybe that can also be used in the fix for the fatal-signal issue.


   But in any case, signals and multithreading together is one of the most
   complicated areas of POSIX programming. Any hope to get this done just
   by calling pthread_sigmask() is day-dreaming.

Yes, I'm not surprised. However as I understand it the issues you raise can occur regardless of whether the code uses sigprocmask or pthread_sigmask, so in some sense the main problem with my recent changes to term-style-control and to fatal-signal was that I should have left FIXME comments in.
From 0e049d12d8549bb3ecba529e65f49f19b91badec Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Sun, 5 Apr 2026 15:20:39 -0700
Subject: [PATCH] sigprocmask: add NEWS entry

---
 NEWS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/NEWS b/NEWS
index faaece85b2..55dc317ebf 100644
--- a/NEWS
+++ b/NEWS
@@ -78,6 +78,12 @@ User visible incompatible changes
 
 Date        Modules         Changes
 
+2026-04-05  sigprocmask     The native MS-Windows implementation no longer
+                            tries to be thread-safe. (As per POSIX,
+                            sigprocmask's behavior has never been
+                            well-defined in multithreaded programs,
+                            which should use pthread_sigmask instead.)
+
 2026-03-31  lock            This module no longer defines the once-only
                             execution primitives. For these, request the
                             'once' module and #include "glthread/once.h".
-- 
2.51.0

Reply via email to