Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3b790d2

Browse files
committed
Fix corner-case bug in WaitEventSetWaitBlock on Windows.
If we do not reset the FD_READ event, WaitForMultipleObjects won'treturn it again again unless we've meanwhile read from the socket,which is generally true but not guaranteed. WaitEventSetWaitBlockitself may fail to return the event to the caller if the latch isalso set, and even if we changed that, the caller isn't obliged tohandle all returned events at once. On non-Windows systems, thesocket-read event is purely level-triggered, so this issue doesnot exist. To fix, make Windows reset the event when needed.This bug was introduced by98a64d0,and causes hangs when trying to use the pldebugger extension.Patch by Amit Kapial. Reported and tested by Ashutosh Sharma, whoalso provided some analysis. Further analysis by Michael Paquier.
1 parent59649c3 commit3b790d2

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

‎src/backend/storage/ipc/latch.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,9 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch,
643643
event->fd=fd;
644644
event->events=events;
645645
event->user_data=user_data;
646+
#ifdefWIN32
647+
event->reset= false;
648+
#endif
646649

647650
if (events==WL_LATCH_SET)
648651
{
@@ -1389,6 +1392,18 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
13891392
DWORDrc;
13901393
WaitEvent*cur_event;
13911394

1395+
/* Reset any wait events that need it */
1396+
for (cur_event=set->events;
1397+
cur_event< (set->events+set->nevents);
1398+
cur_event++)
1399+
{
1400+
if (cur_event->reset)
1401+
{
1402+
WaitEventAdjustWin32(set,cur_event);
1403+
cur_event->reset= false;
1404+
}
1405+
}
1406+
13921407
/*
13931408
* Sleep.
13941409
*
@@ -1472,6 +1487,18 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
14721487
{
14731488
/* data available in socket */
14741489
occurred_events->events |=WL_SOCKET_READABLE;
1490+
1491+
/*------
1492+
* WaitForMultipleObjects doesn't guarantee that a read event will
1493+
* be returned if the latch is set at the same time. Even if it
1494+
* did, the caller might drop that event expecting it to reoccur
1495+
* on next call. So, we must force the event to be reset if this
1496+
* WaitEventSet is used again in order to avoid an indefinite
1497+
* hang. Refer https://msdn.microsoft.com/en-us/library/windows/desktop/ms741576(v=vs.85).aspx
1498+
* for the behavior of socket events.
1499+
*------
1500+
*/
1501+
cur_event->reset= true;
14751502
}
14761503
if ((cur_event->events&WL_SOCKET_WRITEABLE)&&
14771504
(resEvents.lNetworkEvents&FD_WRITE))

‎src/include/storage/latch.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ typedef struct WaitEvent
133133
uint32events;/* triggered events */
134134
pgsocketfd;/* socket fd associated with event */
135135
void*user_data;/* pointer provided in AddWaitEventToSet */
136+
#ifdefWIN32
137+
boolreset;/* Is reset of the event required? */
138+
#endif
136139
}WaitEvent;
137140

138141
/* forward declaration to avoid exposing latch.c implementation details */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp