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
* no hidden magic about whether the syscall will internally service a
* signal --- we do that ourselves.
*/
- do
+ while (!done)
{
- ImmediateInterruptOK = interruptOK;
- CHECK_FOR_INTERRUPTS();
+ DWORD rc;
- ret = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE);
+ CHECK_FOR_INTERRUPTS();
- 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;
}
/*