Skip to content

Commit a87c8c3

Browse files
committed
On Windows, close the client socket explicitly during backend shutdown.
It turns out that this is necessary to keep Winsock from dropping any not-yet-sent data, such as an error message explaining the reason for process termination. It's pretty weird that the implicit close done by the kernel acts differently from an explicit close, but it's hard to argue with experimental results. Independently submitted by Alexander Lakhin and Lars Kanis (comments by me, though). Back-patch to all supported branches. Discussion: https://postgr.es/m/90b34057-4176-7bb0-0dbb-9822a5f6425b@greiz-reinsdorf.de Discussion: https://postgr.es/m/16678-253e48d34dc0c376@postgresql.org
1 parent 0e603b7 commit a87c8c3

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

src/backend/libpq/pqcomm.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,28 @@ socket_close(int code, Datum arg)
289289
secure_close(MyProcPort);
290290

291291
/*
292-
* Formerly we did an explicit close() here, but it seems better to
293-
* leave the socket open until the process dies. This allows clients
294-
* to perform a "synchronous close" if they care --- wait till the
295-
* transport layer reports connection closure, and you can be sure the
296-
* backend has exited.
292+
* On most platforms, we leave the socket open until the process dies.
293+
* This allows clients to perform a "synchronous close" if they care
294+
* --- wait till the transport layer reports connection closure, and
295+
* you can be sure the backend has exited. Saves a kernel call, too.
297296
*
298-
* We do set sock to PGINVALID_SOCKET to prevent any further I/O,
299-
* though.
297+
* However, that does not work on Windows: if the kernel closes the
298+
* socket it will invoke an "abortive shutdown" that discards any data
299+
* not yet sent to the client. (This is a flat-out violation of the
300+
* TCP RFCs, but count on Microsoft not to care about that.) To get
301+
* the spec-compliant "graceful shutdown" behavior, we must invoke
302+
* closesocket() explicitly.
303+
*
304+
* This code runs late enough during process shutdown that we should
305+
* have finished all externally-visible shutdown activities, so that
306+
* in principle it's good enough to act as a synchronous close on
307+
* Windows too. But it's a lot more fragile than the other way.
300308
*/
309+
#ifdef WIN32
310+
closesocket(MyProcPort->sock);
311+
#endif
312+
313+
/* In any case, set sock to PGINVALID_SOCKET to prevent further I/O */
301314
MyProcPort->sock = PGINVALID_SOCKET;
302315
}
303316
}

0 commit comments

Comments
 (0)