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

Commita622095

Browse files
committed
Fix lost Windows socket EOF events.
Winsock only signals an FD_CLOSE event once if the other end of thesocket shuts down gracefully. Because each WaitLatchOrSocket() callconstructs and destroys a new event handle every time, with unluckytiming we can lose it and hang. We get away with this only if the otherend disconnects non-gracefully, because FD_CLOSE is repeatedly signaledin that case.To fix this design flaw in our Windows socket support fundamentally,we'd probably need to rearchitect it so that a single event handleexists for the lifetime of a socket, or switch to completely differentmultiplexing or async I/O APIs. That's going to be a bigger joband probably wouldn't be back-patchable.This brute force kludge closes the race by explicitly polling withMSG_PEEK before sleeping.Back-patch to all supported releases. This should hopefully clear upsome random build farm and CI hang failures reported over the years. Itmight also allow us to try using graceful shutdown in more places again(reverted in commit29992a6) to fix instability in the transmission ofFATAL error messages, but that isn't done by this commit.Reported-by: Tom Lane <tgl@sss.pgh.pa.us>Tested-by: Alexander Lakhin <exclusion@gmail.com>Discussion:https://postgr.es/m/176008.1715492071%40sss.pgh.pa.us
1 parent34eb37f commita622095

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,6 +1967,38 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
19671967
cur_event->reset= false;
19681968
}
19691969

1970+
/*
1971+
* We associate the socket with a new event handle for each
1972+
* WaitEventSet. FD_CLOSE is only generated once if the other end
1973+
* closes gracefully. Therefore we might miss the FD_CLOSE
1974+
* notification, if it was delivered to another event after we stopped
1975+
* waiting for it. Close that race by peeking for EOF after setting
1976+
* up this handle to receive notifications, and before entering the
1977+
* sleep.
1978+
*
1979+
* XXX If we had one event handle for the lifetime of a socket, we
1980+
* wouldn't need this.
1981+
*/
1982+
if (cur_event->events&WL_SOCKET_READABLE)
1983+
{
1984+
charc;
1985+
WSABUFbuf;
1986+
DWORDreceived;
1987+
DWORDflags;
1988+
1989+
buf.buf=&c;
1990+
buf.len=1;
1991+
flags=MSG_PEEK;
1992+
if (WSARecv(cur_event->fd,&buf,1,&received,&flags,NULL,NULL)==0)
1993+
{
1994+
occurred_events->pos=cur_event->pos;
1995+
occurred_events->user_data=cur_event->user_data;
1996+
occurred_events->events=WL_SOCKET_READABLE;
1997+
occurred_events->fd=cur_event->fd;
1998+
return1;
1999+
}
2000+
}
2001+
19702002
/*
19712003
* Windows does not guarantee to log an FD_WRITE network event
19722004
* indicating that more data can be sent unless the previous send()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp