Emulate sigprocmask(), not sigsetmask(), on Windows.
authorThomas Munro <tmunro@postgresql.org>
Sat, 16 Jul 2022 04:07:45 +0000 (16:07 +1200)
committerThomas Munro <tmunro@postgresql.org>
Sat, 16 Jul 2022 05:03:38 +0000 (17:03 +1200)
Since commit a65e0864, we've required Unix systems to have
sigprocmask().  As noted in that commit's message, we were still
emulating the historical pre-standard sigsetmask() function in our
Windows support code.  Emulate standard sigprocmask() instead, for
consistency.

The PG_SETMASK() abstraction is now redundant and all calls could in
theory be replaced by plain sigprocmask() calls, but that isn't done by
this commit.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/3153247.1657834482%40sss.pgh.pa.us

src/backend/port/win32/signal.c
src/include/libpq/pqsignal.h

index b71164d8dbd933fbdbc65d1fcf590804fbbacdf0..53b93a50b26fda40e54675c0be0c12a61e7be470 100644 (file)
@@ -112,7 +112,7 @@ pgwin32_signal_initialize(void)
 /*
  * Dispatch all signals currently queued and not blocked
  * Blocked signals are ignored, and will be fired at the time of
- * the pqsigsetmask() call.
+ * the pqsigprocmask() call.
  */
 void
 pgwin32_dispatch_queued_signals(void)
@@ -154,12 +154,29 @@ pgwin32_dispatch_queued_signals(void)
 
 /* signal masking. Only called on main thread, no sync required */
 int
-pqsigsetmask(int mask)
+pqsigprocmask(int how, const sigset_t *set, sigset_t *oset)
 {
-       int                     prevmask;
+       if (oset)
+               *oset = pg_signal_mask;
 
-       prevmask = pg_signal_mask;
-       pg_signal_mask = mask;
+       if (!set)
+               return 0;
+
+       switch (how)
+       {
+               case SIG_BLOCK:
+                       pg_signal_mask |= *set;
+                       break;
+               case SIG_UNBLOCK:
+                       pg_signal_mask &= ~*set;
+                       break;
+               case SIG_SETMASK:
+                       pg_signal_mask = *set;
+                       break;
+               default:
+                       errno = EINVAL;
+                       return -1;
+       }
 
        /*
         * Dispatch any signals queued up right away, in case we have unblocked
@@ -167,7 +184,7 @@ pqsigsetmask(int mask)
         */
        pgwin32_dispatch_queued_signals();
 
-       return prevmask;
+       return 0;
 }
 
 
index 41227a30e2455ecbaffce2936dbafc28be02f82b..d17ddb787e753b60ce9f7c0ad041c543042e0487 100644 (file)
 
 #include <signal.h>
 
-#ifndef WIN32
 #define PG_SETMASK(mask)       sigprocmask(SIG_SETMASK, mask, NULL)
-#else
+
+#ifdef WIN32
 /* Emulate POSIX sigset_t APIs on Windows */
 typedef int sigset_t;
 
-extern int     pqsigsetmask(int mask);
+extern int     pqsigprocmask(int how, const sigset_t *set, sigset_t *oset);
 
-#define PG_SETMASK(mask)               pqsigsetmask(*(mask))
+#define SIG_BLOCK                              1
+#define SIG_UNBLOCK                            2
+#define SIG_SETMASK                            3
+#define sigprocmask(how, set, oset) pqsigprocmask((how), (set), (oset))
 #define sigemptyset(set)               (*(set) = 0)
 #define sigfillset(set)                        (*(set) = ~0)
 #define sigaddset(set, signum) (*(set) |= (sigmask(signum)))