From c94ae9d827a360d74da6a304692d34a4dc8b6445 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Sat, 16 Jul 2022 16:07:45 +1200 Subject: [PATCH] Emulate sigprocmask(), not sigsetmask(), on Windows. 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 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 -#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)))