aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-04-04 11:13:17 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2016-04-04 11:13:43 -0400
commitb1b6aa88b146e0e7ca9b2eb5911d1f56064ccabb (patch)
tree6db8d97b8b618b0dfcd6a7072d4969c996d9277b /src
parent6cd30292bfc38edcae0c1d9c127265cfe665a569 (diff)
downloadpostgresql-b1b6aa88b146e0e7ca9b2eb5911d1f56064ccabb.tar.gz
postgresql-b1b6aa88b146e0e7ca9b2eb5911d1f56064ccabb.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/port/win32/signal.c9
1 files changed, 5 insertions, 4 deletions
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))
{