diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a615dc0411c..1513484e7d0 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -91,21 +91,6 @@
-
-
- On Windows, there is a way to improve performance if a single
- database connection is repeatedly started and shutdown. Internally,
- libpq calls WSAStartup() and WSACleanup() for connection startup
- and shutdown, respectively. WSAStartup() increments an internal
- Windows library reference count which is decremented by WSACleanup().
- When the reference count is just one, calling WSACleanup() frees
- all resources and all DLLs are unloaded. This is an expensive
- operation. To avoid this, an application can manually call
- WSAStartup() so resources will not be freed when the last database
- connection is closed.
-
-
-
PQconnectdbParamsPQconnectdbParams
diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c
index c25e3f7a888..c7d848a13e7 100644
--- a/src/bin/pg_dump/parallel.c
+++ b/src/bin/pg_dump/parallel.c
@@ -229,19 +229,6 @@ static char *readMessageFromPipe(int fd);
(strncmp(msg, prefix, strlen(prefix)) == 0)
-/*
- * Shutdown callback to clean up socket access
- */
-#ifdef WIN32
-static void
-shutdown_parallel_dump_utils(int code, void *unused)
-{
- /* Call the cleanup function only from the main thread */
- if (mainThreadId == GetCurrentThreadId())
- WSACleanup();
-}
-#endif
-
/*
* Initialize parallel dump support --- should be called early in process
* startup. (Currently, this is called whether or not we intend parallel
@@ -267,8 +254,7 @@ init_parallel_dump_utils(void)
pg_log_error("WSAStartup failed: %d", err);
exit_nicely(1);
}
- /* ... and arrange to shut it down at exit */
- on_exit_nicely(shutdown_parallel_dump_utils, NULL);
+
parallel_init_done = true;
}
#endif
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index b4d24071713..4c45c126e4c 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3866,23 +3866,30 @@ makeEmptyPGconn(void)
#ifdef WIN32
/*
- * Make sure socket support is up and running.
+ * Make sure socket support is up and running in this process.
+ *
+ * Note: the Windows documentation says that we should eventually do a
+ * matching WSACleanup() call, but experience suggests that that is at
+ * least as likely to cause problems as fix them. So we don't.
*/
- WSADATA wsaData;
+ static bool wsastartup_done = false;
- if (WSAStartup(MAKEWORD(1, 1), &wsaData))
- return NULL;
+ if (!wsastartup_done)
+ {
+ WSADATA wsaData;
+
+ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
+ return NULL;
+ wsastartup_done = true;
+ }
+
+ /* Forget any earlier error */
WSASetLastError(0);
-#endif
+#endif /* WIN32 */
conn = (PGconn *) malloc(sizeof(PGconn));
if (conn == NULL)
- {
-#ifdef WIN32
- WSACleanup();
-#endif
return conn;
- }
/* Zero all pointers and booleans */
MemSet(conn, 0, sizeof(PGconn));
@@ -4075,10 +4082,6 @@ freePGconn(PGconn *conn)
termPQExpBuffer(&conn->workBuffer);
free(conn);
-
-#ifdef WIN32
- WSACleanup();
-#endif
}
/*