On Fri, Jul 15, 2022 at 9:34 AM Tom Lane <t...@sss.pgh.pa.us> wrote: > (Someday we oughta go ahead and make our Windows signal API look more > like POSIX, as I suggested back in 2015. I'm still not taking > point on that, though.)
For the sigprocmask() part, here's a patch that passes CI. Only the SIG_SETMASK case is actually exercised by our current code, though. One weird thing about our PG_SETMASK() macro is that you couldn't have used its return value portably: on Windows we were returning the old mask (like sigsetmask(), which has no way to report errors), and on Unix we were returning 0/-1 (from setprocmask(), ie the error we never checked).
From b21140e9b3f593b46c3bb4782c6bf84ca248dc15 Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Fri, 15 Jul 2022 14:35:01 +1200 Subject: [PATCH] Emulate sigprocmask(), not sigsetmask(), on Windows. Since commit a65e0864, we've required Unix systems to have sigprocmask(). For Windows we still emulated the old deprecated 4.2BSD function sigsetmask(). Emulate sigprocmask() instead, for consistency. Discussion: https://postgr.es/m/3153247.1657834482%40sss.pgh.pa.us --- src/backend/port/win32/signal.c | 29 +++++++++++++++++++++++------ src/include/libpq/pqsignal.h | 11 +++++++---- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/backend/port/win32/signal.c b/src/backend/port/win32/signal.c index b71164d8db..53b93a50b2 100644 --- a/src/backend/port/win32/signal.c +++ b/src/backend/port/win32/signal.c @@ -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; } diff --git a/src/include/libpq/pqsignal.h b/src/include/libpq/pqsignal.h index 41227a30e2..d17ddb787e 100644 --- a/src/include/libpq/pqsignal.h +++ b/src/include/libpq/pqsignal.h @@ -15,15 +15,18 @@ #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))) -- 2.36.1