diff --git a/src/backend/port/win32/socket.c b/src/backend/port/win32/socket.c index 6a518e5b6d9..c981169fe1f 100644 --- a/src/backend/port/win32/socket.c +++ b/src/backend/port/win32/socket.c @@ -623,7 +623,8 @@ pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, c return 0; } - if (r == WAIT_OBJECT_0 + numevents) + /* Signal-like events. */ + if (r == WAIT_OBJECT_0 + numevents || r == WAIT_IO_COMPLETION) { pgwin32_dispatch_queued_signals(); errno = EINTR; diff --git a/src/backend/port/win32_sema.c b/src/backend/port/win32_sema.c index 43b1123a24e..0adc73af7b1 100644 --- a/src/backend/port/win32_sema.c +++ b/src/backend/port/win32_sema.c @@ -118,8 +118,10 @@ PGSemaphoreReset(PGSemaphore sema) void PGSemaphoreLock(PGSemaphore sema, bool interruptOK) { - DWORD ret; HANDLE wh[2]; + bool done = false; + + ImmediateInterruptOK = interruptOK; /* * Note: pgwin32_signal_event should be first to ensure that it will be @@ -135,34 +137,44 @@ PGSemaphoreLock(PGSemaphore sema, bool interruptOK) * no hidden magic about whether the syscall will internally service a * signal --- we do that ourselves. */ - do + while (!done) { - ImmediateInterruptOK = interruptOK; + DWORD rc; + CHECK_FOR_INTERRUPTS(); - ret = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE); - - if (ret == WAIT_OBJECT_0) + rc = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE); + switch (rc) { - /* Signal event is set - we have a signal to deliver */ - pgwin32_dispatch_queued_signals(); - errno = EINTR; + case WAIT_OBJECT_0: + /* Signal event is set - we have a signal to deliver */ + pgwin32_dispatch_queued_signals(); + break; + case WAIT_OBJECT_0 + 1: + /* We got it! */ + done = true; + break; + case WAIT_IO_COMPLETION: + /* + * The system interrupted the wait to execute an I/O + * completion routine or asynchronous procedure call in this + * thread. PostgreSQL does not provoke either of these, but + * atypical loaded DLLs or even other processes might do so. + * Now, resume waiting. + */ + break; + case WAIT_FAILED: + ereport(FATAL, + (errmsg("could not lock semaphore: error code %lu", + GetLastError()))); + break; + default: + elog(FATAL, "unexpected return code from WaitForMultipleObjectsEx(): %lu", rc); + break; } - else if (ret == WAIT_OBJECT_0 + 1) - { - /* We got it! */ - errno = 0; - } - else - /* Otherwise we are in trouble */ - errno = EIDRM; + } - ImmediateInterruptOK = false; - } while (errno == EINTR); - - if (errno != 0) - ereport(FATAL, - (errmsg("could not lock semaphore: error code %lu", GetLastError()))); + ImmediateInterruptOK = false; } /*