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

Commitb98e551

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 parentce92fc4 commitb98e551

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
@@ -640,6 +640,9 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch,
640640
event->fd=fd;
641641
event->events=events;
642642
event->user_data=user_data;
643+
#ifdefWIN32
644+
event->reset= false;
645+
#endif
643646

644647
if (events==WL_LATCH_SET)
645648
{
@@ -1381,6 +1384,18 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
13811384
DWORDrc;
13821385
WaitEvent*cur_event;
13831386

1387+
/* Reset any wait events that need it */
1388+
for (cur_event=set->events;
1389+
cur_event< (set->events+set->nevents);
1390+
cur_event++)
1391+
{
1392+
if (cur_event->reset)
1393+
{
1394+
WaitEventAdjustWin32(set,cur_event);
1395+
cur_event->reset= false;
1396+
}
1397+
}
1398+
13841399
/*
13851400
* Sleep.
13861401
*
@@ -1464,6 +1479,18 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
14641479
{
14651480
/* data available in socket */
14661481
occurred_events->events |=WL_SOCKET_READABLE;
1482+
1483+
/*------
1484+
* WaitForMultipleObjects doesn't guarantee that a read event will
1485+
* be returned if the latch is set at the same time. Even if it
1486+
* did, the caller might drop that event expecting it to reoccur
1487+
* on next call. So, we must force the event to be reset if this
1488+
* WaitEventSet is used again in order to avoid an indefinite
1489+
* hang. Refer https://msdn.microsoft.com/en-us/library/windows/desktop/ms741576(v=vs.85).aspx
1490+
* for the behavior of socket events.
1491+
*------
1492+
*/
1493+
cur_event->reset= true;
14671494
}
14681495
if ((cur_event->events&WL_SOCKET_WRITEABLE)&&
14691496
(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