From: Tom Lane Date: Mon, 4 Apr 2016 15:13:17 +0000 (-0400) Subject: Fix latent portability issue in pgwin32_dispatch_queued_signals(). X-Git-Tag: REL9_1_22~23 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=b1b6aa88b146e0e7ca9b2eb5911d1f56064ccabb;p=postgresql.git Fix latent portability issue in pgwin32_dispatch_queued_signals(). The first iteration of the signal-checking loop would compute sigmask(0) which expands to 1<<(-1) which is undefined behavior according to the C standard. The lack of field reports of trouble suggest that it evaluates to 0 on all existing Windows compilers, but that's hardly something to rely on. Since signal 0 isn't a queueable signal anyway, we can just make the loop iterate from 1 instead, and save a few cycles as well as avoiding the undefined behavior. In passing, avoid evaluating the volatile expression UNBLOCKED_SIGNAL_QUEUE twice in a row; there's no reason to waste cycles like that. Noted by Aleksander Alekseev, though this isn't his proposed fix. Back-patch to all supported branches. --- diff --git a/src/backend/port/win32/signal.c b/src/backend/port/win32/signal.c index d2dfd01223c..63b96489f9c 100644 --- a/src/backend/port/win32/signal.c +++ b/src/backend/port/win32/signal.c @@ -33,6 +33,7 @@ HANDLE pgwin32_initial_signal_pipe = INVALID_HANDLE_VALUE; */ static CRITICAL_SECTION pg_signal_crit_sec; +/* Note that array elements 0 are unused since they correspond to signal 0 */ static pqsigfunc pg_signal_array[PG_SIGNAL_COUNT]; static pqsigfunc pg_signal_defaults[PG_SIGNAL_COUNT]; @@ -105,15 +106,15 @@ pgwin32_signal_initialize(void) void pgwin32_dispatch_queued_signals(void) { - int i; + int exec_mask; EnterCriticalSection(&pg_signal_crit_sec); - while (UNBLOCKED_SIGNAL_QUEUE()) + while ((exec_mask = UNBLOCKED_SIGNAL_QUEUE()) != 0) { /* One or more unblocked signals queued for execution */ - int exec_mask = UNBLOCKED_SIGNAL_QUEUE(); + int i; - for (i = 0; i < PG_SIGNAL_COUNT; i++) + for (i = 1; i < PG_SIGNAL_COUNT; i++) { if (exec_mask & sigmask(i)) {