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