aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/port/win32_latch.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/src/backend/port/win32_latch.c b/src/backend/port/win32_latch.c
index 2a7b84539f3..e4fe05fa4b6 100644
--- a/src/backend/port/win32_latch.c
+++ b/src/backend/port/win32_latch.c
@@ -115,14 +115,19 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
else
timeout = INFINITE;
- /* Construct an array of event handles for WaitforMultipleObjects() */
+ /*
+ * Construct an array of event handles for WaitforMultipleObjects().
+ *
+ * Note: pgwin32_signal_event should be first to ensure that it will be
+ * reported when multiple events are set. We want to guarantee that
+ * pending signals are serviced.
+ */
latchevent = latch->event;
- events[0] = latchevent;
- events[1] = pgwin32_signal_event;
+ events[0] = pgwin32_signal_event;
+ events[1] = latchevent;
numevents = 2;
- if ((wakeEvents & WL_SOCKET_READABLE) ||
- (wakeEvents & WL_SOCKET_WRITEABLE))
+ if (wakeEvents & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE))
{
int flags = 0;
@@ -132,7 +137,13 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
flags |= FD_WRITE;
sockevent = WSACreateEvent();
- WSAEventSelect(sock, sockevent, flags);
+ if (sockevent == WSA_INVALID_EVENT)
+ elog(ERROR, "failed to create event for socket: error code %u",
+ WSAGetLastError());
+ if (WSAEventSelect(sock, sockevent, flags) != 0)
+ elog(ERROR, "failed to set up event for socket: error code %u",
+ WSAGetLastError());
+
events[numevents++] = sockevent;
}
if (wakeEvents & WL_POSTMASTER_DEATH)
@@ -141,6 +152,9 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
events[numevents++] = PostmasterHandle;
}
+ /* Ensure that signals are serviced even if latch is already set */
+ pgwin32_dispatch_queued_signals();
+
do
{
/*
@@ -151,6 +165,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
*/
if (!ResetEvent(latchevent))
elog(ERROR, "ResetEvent failed: error code %lu", GetLastError());
+
if ((wakeEvents & WL_LATCH_SET) && latch->is_set)
{
result |= WL_LATCH_SET;
@@ -164,21 +179,20 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
rc = WaitForMultipleObjects(numevents, events, FALSE, timeout);
if (rc == WAIT_FAILED)
- elog(ERROR, "WaitForMultipleObjects() failed: error code %lu", GetLastError());
-
- /* Participate in Windows signal emulation */
- else if (rc == WAIT_OBJECT_0 + 1)
- pgwin32_dispatch_queued_signals();
-
+ elog(ERROR, "WaitForMultipleObjects() failed: error code %lu",
+ GetLastError());
else if (rc == WAIT_TIMEOUT)
{
result |= WL_TIMEOUT;
}
- else if ((wakeEvents & WL_POSTMASTER_DEATH) &&
- rc == WAIT_OBJECT_0 + pmdeath_eventno)
+ else if (rc == WAIT_OBJECT_0)
{
- /* Postmaster died */
- result |= WL_POSTMASTER_DEATH;
+ /* Service newly-arrived signals */
+ pgwin32_dispatch_queued_signals();
+ }
+ else if (rc == WAIT_OBJECT_0 + 1)
+ {
+ /* Latch is set, we'll handle that on next iteration of loop */
}
else if ((wakeEvents & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE)) &&
rc == WAIT_OBJECT_0 + 2) /* socket is at event slot 2 */
@@ -187,9 +201,8 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
ZeroMemory(&resEvents, sizeof(resEvents));
if (WSAEnumNetworkEvents(sock, sockevent, &resEvents) == SOCKET_ERROR)
- ereport(FATAL,
- (errmsg_internal("failed to enumerate network events: error code %lu", GetLastError())));
-
+ elog(ERROR, "failed to enumerate network events: error code %lu",
+ GetLastError());
if ((wakeEvents & WL_SOCKET_READABLE) &&
(resEvents.lNetworkEvents & FD_READ))
{
@@ -201,8 +214,13 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
result |= WL_SOCKET_WRITEABLE;
}
}
- /* Otherwise it must be the latch event */
- else if (rc != WAIT_OBJECT_0)
+ else if ((wakeEvents & WL_POSTMASTER_DEATH) &&
+ rc == WAIT_OBJECT_0 + pmdeath_eventno)
+ {
+ /* Postmaster died */
+ result |= WL_POSTMASTER_DEATH;
+ }
+ else
elog(ERROR, "unexpected return code from WaitForMultipleObjects(): %lu", rc);
}
while (result == 0);