Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4355d21

Browse files
committed
On Windows, use pgwin32_waitforsinglesocket() instead of select() to wait for
input in the stats collector. Our select() emulation is apparently buggy for UDP sockets :-(. This should resolve problems with stats collection (and hence autovacuum) failing under more than minimal load. Diagnosis and patch by Magnus Hagander. Patch probably needs to be back-ported to 8.1 and 8.0, but first let's see if it makes the buildfarm happy...
1 parent 8ff2bcc commit 4355d21

File tree

4 files changed

+29
-15
lines changed

4 files changed

+29
-15
lines changed

src/backend/libpq/be-secure.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.75 2007/01/05 22:19:29 momjian Exp $
14+
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.76 2007/01/26 20:06:52 tgl Exp $
1515
*
1616
* Since the server static private key ($DataDir/server.key)
1717
* will normally be stored unencrypted so that the database
@@ -275,7 +275,8 @@ secure_read(Port *port, void *ptr, size_t len)
275275
#ifdef WIN32
276276
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
277277
(err == SSL_ERROR_WANT_READ) ?
278-
FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
278+
FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE,
279+
INFINITE);
279280
#endif
280281
goto rloop;
281282
case SSL_ERROR_SYSCALL:
@@ -374,7 +375,8 @@ secure_write(Port *port, void *ptr, size_t len)
374375
#ifdef WIN32
375376
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
376377
(err == SSL_ERROR_WANT_READ) ?
377-
FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
378+
FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE,
379+
INFINITE);
378380
#endif
379381
goto wloop;
380382
case SSL_ERROR_SYSCALL:
@@ -889,7 +891,8 @@ open_server_SSL(Port *port)
889891
#ifdef WIN32
890892
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
891893
(err == SSL_ERROR_WANT_READ) ?
892-
FD_READ | FD_CLOSE | FD_ACCEPT : FD_WRITE | FD_CLOSE);
894+
FD_READ | FD_CLOSE | FD_ACCEPT : FD_WRITE | FD_CLOSE,
895+
INFINITE);
893896
#endif
894897
goto aloop;
895898
case SSL_ERROR_SYSCALL:

src/backend/port/win32/socket.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.16 2007/01/05 22:19:35 momjian Exp $
9+
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.17 2007/01/26 20:06:52 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -114,7 +114,7 @@ isDataGram(SOCKET s) {
114114
}
115115

116116
int
117-
pgwin32_waitforsinglesocket(SOCKET s, int what)
117+
pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
118118
{
119119
static HANDLE waitevent = INVALID_HANDLE_VALUE;
120120
static SOCKET current_socket = -1;
@@ -195,7 +195,7 @@ pgwin32_waitforsinglesocket(SOCKET s, int what)
195195
}
196196
}
197197
else
198-
r = WaitForMultipleObjectsEx(2, events, FALSE, INFINITE, TRUE);
198+
r = WaitForMultipleObjectsEx(2, events, FALSE, timeout, TRUE);
199199

200200
if (r == WAIT_OBJECT_0 || r == WAIT_IO_COMPLETION)
201201
{
@@ -205,6 +205,8 @@ pgwin32_waitforsinglesocket(SOCKET s, int what)
205205
}
206206
if (r == WAIT_OBJECT_0 + 1)
207207
return 1;
208+
if (r == WAIT_TIMEOUT)
209+
return 0;
208210
ereport(ERROR,
209211
(errmsg_internal("Bad return from WaitForMultipleObjects: %i (%i)", r, (int) GetLastError())));
210212
return 0;
@@ -274,7 +276,7 @@ pgwin32_connect(SOCKET s, const struct sockaddr * addr, int addrlen)
274276
return -1;
275277
}
276278

277-
while (pgwin32_waitforsinglesocket(s, FD_CONNECT) == 0)
279+
while (pgwin32_waitforsinglesocket(s, FD_CONNECT, INFINITE) == 0)
278280
{
279281
/* Loop endlessly as long as we are just delivering signals */
280282
}
@@ -310,7 +312,8 @@ pgwin32_recv(SOCKET s, char *buf, int len, int f)
310312

311313
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
312314

313-
if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT) == 0)
315+
if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT,
316+
INFINITE) == 0)
314317
return -1;
315318

316319
r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
@@ -355,7 +358,7 @@ pgwin32_send(SOCKET s, char *buf, int len, int flags)
355358

356359
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
357360

358-
if (pgwin32_waitforsinglesocket(s, FD_WRITE | FD_CLOSE) == 0)
361+
if (pgwin32_waitforsinglesocket(s, FD_WRITE | FD_CLOSE, INFINITE) == 0)
359362
return -1;
360363
}
361364

src/backend/postmaster/pgstat.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* Copyright (c) 2001-2007, PostgreSQL Global Development Group
1515
*
16-
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.143 2007/01/11 23:06:03 tgl Exp $
16+
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.144 2007/01/26 20:06:52 tgl Exp $
1717
* ----------
1818
*/
1919
#include "postgres.h"
@@ -1657,11 +1657,13 @@ PgstatCollectorMain(int argc, char *argv[])
16571657
int len;
16581658
PgStat_Msg msg;
16591659

1660+
#ifndef WIN32
16601661
#ifdef HAVE_POLL
16611662
struct pollfd input_fd;
16621663
#else
16631664
struct timeval sel_timeout;
16641665
fd_set rfds;
1666+
#endif
16651667
#endif
16661668

16671669
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
@@ -1724,7 +1726,7 @@ PgstatCollectorMain(int argc, char *argv[])
17241726
* Setup the descriptor set for select(2). Since only one bit in the set
17251727
* ever changes, we need not repeat FD_ZERO each time.
17261728
*/
1727-
#ifndef HAVE_POLL
1729+
#if !defined(HAVE_POLL) && !defined(WIN32)
17281730
FD_ZERO(&rfds);
17291731
#endif
17301732

@@ -1771,8 +1773,10 @@ PgstatCollectorMain(int argc, char *argv[])
17711773
* poll/select call, so this also limits speed of response to SIGQUIT,
17721774
* which is more important.)
17731775
*
1774-
* We use poll(2) if available, otherwise select(2)
1776+
* We use poll(2) if available, otherwise select(2).
1777+
* Win32 has its own implementation.
17751778
*/
1779+
#ifndef WIN32
17761780
#ifdef HAVE_POLL
17771781
input_fd.fd = pgStatSock;
17781782
input_fd.events = POLLIN | POLLERR;
@@ -1810,6 +1814,10 @@ PgstatCollectorMain(int argc, char *argv[])
18101814

18111815
got_data = FD_ISSET(pgStatSock, &rfds);
18121816
#endif /* HAVE_POLL */
1817+
#else /* WIN32 */
1818+
got_data = pgwin32_waitforsinglesocket(pgStatSock, FD_READ,
1819+
PGSTAT_SELECT_TIMEOUT*1000);
1820+
#endif
18131821

18141822
/*
18151823
* If there is a message on the socket, read it and check for

src/include/port/win32.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.71 2007/01/25 21:50:49 momjian Exp $ */
1+
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.72 2007/01/26 20:06:52 tgl Exp $ */
22

33
#if defined(_MSC_VER) || defined(__BORLANDC__)
44
#define WIN32_ONLY_COMPILER
@@ -289,7 +289,7 @@ int pgwin32_recv(SOCKET s, char *buf, int len, int flags);
289289
int pgwin32_send(SOCKET s, char *buf, int len, int flags);
290290

291291
const char *pgwin32_socket_strerror(int err);
292-
int pgwin32_waitforsinglesocket(SOCKET s, int what);
292+
int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
293293

294294
/* in backend/port/win32/security.c */
295295
extern int pgwin32_is_admin(void);

0 commit comments

Comments
 (0)