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

Appearance settings

Commit cdc7ace

Browse filesBrowse files
committed
In libpq for Windows, call WSAStartup once and WSACleanup not at all.
The Windows documentation insists that every WSAStartup call should have a matching WSACleanup call. However, if that ever had actual relevance, it wasn't in this century. Every remotely-modern Windows kernel is capable of cleaning up when a process exits without doing that, and must be so to avoid resource leaks in case of a process crash. Moreover, Postgres backends have done WSAStartup without WSACleanup since commit 4cdf51e in 2004, and we've never seen any indication of a problem with that. libpq's habit of doing WSAStartup during connection start and WSACleanup during shutdown is also rather inefficient, since a series of non-overlapping connection requests leads to repeated, quite expensive DLL unload/reload cycles. We document a workaround for that (having the application call WSAStartup for itself), but that's just a kluge. It's also worth noting that it's far from uncommon for applications to exit without doing PQfinish, and we've not heard reports of trouble from that either. However, the real reason for acting on this is that recent experiments by Alexander Lakhin show that calling WSACleanup during PQfinish is triggering the symptom we occasionally see that a process using libpq fails to emit expected stdio output. Therefore, let's change libpq so that it calls WSAStartup only once per process, during the first connection attempt, and never calls WSACleanup at all. While at it, get rid of the only other WSACleanup call in our code tree, in pg_dump/parallel.c; that presumably is equally useless. Back-patch of HEAD commit 7d00a6b. Discussion: https://postgr.es/m/ac976d8c-03df-d6b8-025c-15a2de8d9af1@postgrespro.ru
1 parent 8ae447e commit cdc7ace
Copy full SHA for cdc7ace

File tree

Expand file treeCollapse file tree

3 files changed

+18
-44
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+18
-44
lines changed

‎doc/src/sgml/libpq.sgml

Copy file name to clipboardExpand all lines: doc/src/sgml/libpq.sgml
-15Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,6 @@
9191
</para>
9292
</warning>
9393

94-
<note>
95-
<para>
96-
On Windows, there is a way to improve performance if a single
97-
database connection is repeatedly started and shutdown. Internally,
98-
libpq calls <function>WSAStartup()</> and <function>WSACleanup()</> for connection startup
99-
and shutdown, respectively. <function>WSAStartup()</> increments an internal
100-
Windows library reference count which is decremented by <function>WSACleanup()</>.
101-
When the reference count is just one, calling <function>WSACleanup()</> frees
102-
all resources and all DLLs are unloaded. This is an expensive
103-
operation. To avoid this, an application can manually call
104-
<function>WSAStartup()</> so resources will not be freed when the last database
105-
connection is closed.
106-
</para>
107-
</note>
108-
10994
<variablelist>
11095
<varlistentry id="libpq-pqconnectdbparams">
11196
<term><function>PQconnectdbParams</function><indexterm><primary>PQconnectdbParams</></></term>

‎src/bin/pg_dump/parallel.c

Copy file name to clipboardExpand all lines: src/bin/pg_dump/parallel.c
+1-15Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -193,19 +193,6 @@ static char *readMessageFromPipe(int fd);
193193
(strcmp(msg, pattern) == 0)
194194

195195

196-
/*
197-
* Shutdown callback to clean up socket access
198-
*/
199-
#ifdef WIN32
200-
static void
201-
shutdown_parallel_dump_utils(int code, void *unused)
202-
{
203-
/* Call the cleanup function only from the main thread */
204-
if (mainThreadId == GetCurrentThreadId())
205-
WSACleanup();
206-
}
207-
#endif
208-
209196
/*
210197
* Initialize parallel dump support --- should be called early in process
211198
* startup. (Currently, this is called whether or not we intend parallel
@@ -231,8 +218,7 @@ init_parallel_dump_utils(void)
231218
fprintf(stderr, _("%s: WSAStartup failed: %d\n"), progname, err);
232219
exit_nicely(1);
233220
}
234-
/* ... and arrange to shut it down at exit */
235-
on_exit_nicely(shutdown_parallel_dump_utils, NULL);
221+
236222
parallel_init_done = true;
237223
}
238224
#endif

‎src/interfaces/libpq/fe-connect.c

Copy file name to clipboardExpand all lines: src/interfaces/libpq/fe-connect.c
+17-14Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,23 +2911,30 @@ makeEmptyPGconn(void)
29112911
#ifdef WIN32
29122912

29132913
/*
2914-
* Make sure socket support is up and running.
2914+
* Make sure socket support is up and running in this process.
2915+
*
2916+
* Note: the Windows documentation says that we should eventually do a
2917+
* matching WSACleanup() call, but experience suggests that that is at
2918+
* least as likely to cause problems as fix them. So we don't.
29152919
*/
2916-
WSADATA wsaData;
2920+
static bool wsastartup_done = false;
29172921

2918-
if (WSAStartup(MAKEWORD(1, 1), &wsaData))
2919-
return NULL;
2922+
if (!wsastartup_done)
2923+
{
2924+
WSADATA wsaData;
2925+
2926+
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
2927+
return NULL;
2928+
wsastartup_done = true;
2929+
}
2930+
2931+
/* Forget any earlier error */
29202932
WSASetLastError(0);
2921-
#endif
2933+
#endif /* WIN32 */
29222934

29232935
conn = (PGconn *) malloc(sizeof(PGconn));
29242936
if (conn == NULL)
2925-
{
2926-
#ifdef WIN32
2927-
WSACleanup();
2928-
#endif
29292937
return conn;
2930-
}
29312938

29322939
/* Zero all pointers and booleans */
29332940
MemSet(conn, 0, sizeof(PGconn));
@@ -3077,10 +3084,6 @@ freePGconn(PGconn *conn)
30773084
termPQExpBuffer(&conn->workBuffer);
30783085

30793086
free(conn);
3080-
3081-
#ifdef WIN32
3082-
WSACleanup();
3083-
#endif
30843087
}
30853088

30863089
/*

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.