On Fri, Jan 26, 2007 at 12:26:58PM +0100, Magnus Hagander wrote:
> On Fri, Jan 26, 2007 at 01:11:00PM +0300, Teodor Sigaev wrote:
> > >Apparantly there is a bug lurking somewhere in pgwin32_select(). Because
> > >if I put a #undef select right before the select in pgstat.c, the
> > >regression tests pass.
> >
> > May be, problem is related to fixed bug in pgwin32_waitforsinglesocket() ?
> > WaitForMultipleObjectsEx might sleep indefinitely while waiting socket to
> > write, so, may be there is symmetrical problem with read? Or
> > pgwin32_select() is used for waiting write too?
>
>
> pgwin32_waitforsinglesocket() appears to work fine. And we only use
> FD_READ, so it's not affected by your patch from what I can tell.
>
> I've got it passnig tests with select replaced with waitforsinglesocket
> - now I just need to implement timeout in that one :-)
Attached patch seems to solve the problem on my machine at least. Uses
pgwin32_waitforsinglesocket() instead of pgwin32_select(). Changes
pgwin32_waitforsinglesocket() to accept the timeout as a parameter (this
is why it touches files outside of the stats area).
//Magnus
Index: src/backend/libpq/be-secure.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/libpq/be-secure.c,v
retrieving revision 1.75
diff -c -r1.75 be-secure.c
*** src/backend/libpq/be-secure.c 5 Jan 2007 22:19:29 -0000 1.75
--- src/backend/libpq/be-secure.c 26 Jan 2007 11:32:07 -0000
***************
*** 275,281 ****
#ifdef WIN32
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
(err == SSL_ERROR_WANT_READ) ?
! FD_READ |
FD_CLOSE : FD_WRITE | FD_CLOSE);
#endif
goto rloop;
case SSL_ERROR_SYSCALL:
--- 275,281 ----
#ifdef WIN32
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
(err == SSL_ERROR_WANT_READ) ?
! FD_READ |
FD_CLOSE : FD_WRITE | FD_CLOSE, INFINITE);
#endif
goto rloop;
case SSL_ERROR_SYSCALL:
***************
*** 374,380 ****
#ifdef WIN32
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
(err == SSL_ERROR_WANT_READ) ?
! FD_READ |
FD_CLOSE : FD_WRITE | FD_CLOSE);
#endif
goto wloop;
case SSL_ERROR_SYSCALL:
--- 374,380 ----
#ifdef WIN32
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
(err == SSL_ERROR_WANT_READ) ?
! FD_READ |
FD_CLOSE : FD_WRITE | FD_CLOSE, INFINITE);
#endif
goto wloop;
case SSL_ERROR_SYSCALL:
***************
*** 889,895 ****
#ifdef WIN32
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
(err == SSL_ERROR_WANT_READ) ?
! FD_READ | FD_CLOSE | FD_ACCEPT :
FD_WRITE | FD_CLOSE);
#endif
goto aloop;
case SSL_ERROR_SYSCALL:
--- 889,895 ----
#ifdef WIN32
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
(err == SSL_ERROR_WANT_READ) ?
! FD_READ | FD_CLOSE | FD_ACCEPT :
FD_WRITE | FD_CLOSE, INFINITE);
#endif
goto aloop;
case SSL_ERROR_SYSCALL:
Index: src/backend/port/win32/socket.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/port/win32/socket.c,v
retrieving revision 1.16
diff -c -r1.16 socket.c
*** src/backend/port/win32/socket.c 5 Jan 2007 22:19:35 -0000 1.16
--- src/backend/port/win32/socket.c 26 Jan 2007 11:35:16 -0000
***************
*** 114,120 ****
}
int
! pgwin32_waitforsinglesocket(SOCKET s, int what)
{
static HANDLE waitevent = INVALID_HANDLE_VALUE;
static SOCKET current_socket = -1;
--- 114,120 ----
}
int
! pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
{
static HANDLE waitevent = INVALID_HANDLE_VALUE;
static SOCKET current_socket = -1;
***************
*** 195,201 ****
}
}
else
! r = WaitForMultipleObjectsEx(2, events, FALSE, INFINITE, TRUE);
if (r == WAIT_OBJECT_0 || r == WAIT_IO_COMPLETION)
{
--- 195,201 ----
}
}
else
! r = WaitForMultipleObjectsEx(2, events, FALSE, timeout, TRUE);
if (r == WAIT_OBJECT_0 || r == WAIT_IO_COMPLETION)
{
***************
*** 205,210 ****
--- 205,212 ----
}
if (r == WAIT_OBJECT_0 + 1)
return 1;
+ if (r == WAIT_TIMEOUT)
+ return 0;
ereport(ERROR,
(errmsg_internal("Bad return from
WaitForMultipleObjects: %i (%i)", r, (int) GetLastError())));
return 0;
***************
*** 274,280 ****
return -1;
}
! while (pgwin32_waitforsinglesocket(s, FD_CONNECT) == 0)
{
/* Loop endlessly as long as we are just delivering signals */
}
--- 276,282 ----
return -1;
}
! while (pgwin32_waitforsinglesocket(s, FD_CONNECT, INFINITE) == 0)
{
/* Loop endlessly as long as we are just delivering signals */
}
***************
*** 310,316 ****
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
! if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT) == 0)
return -1;
r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
--- 312,318 ----
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
! if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT,
INFINITE) == 0)
return -1;
r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
***************
*** 355,361 ****
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK
(<=nt4) */
! if (pgwin32_waitforsinglesocket(s, FD_WRITE | FD_CLOSE) == 0)
return -1;
}
--- 357,363 ----
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK
(<=nt4) */
! if (pgwin32_waitforsinglesocket(s, FD_WRITE | FD_CLOSE,
INFINITE) == 0)
return -1;
}
Index: src/backend/postmaster/pgstat.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/postmaster/pgstat.c,v
retrieving revision 1.143
diff -c -r1.143 pgstat.c
*** src/backend/postmaster/pgstat.c 11 Jan 2007 23:06:03 -0000 1.143
--- src/backend/postmaster/pgstat.c 26 Jan 2007 11:37:37 -0000
***************
*** 1657,1668 ****
--- 1657,1670 ----
int len;
PgStat_Msg msg;
+ #ifndef WIN32
#ifdef HAVE_POLL
struct pollfd input_fd;
#else
struct timeval sel_timeout;
fd_set rfds;
#endif
+ #endif
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
***************
*** 1724,1730 ****
* Setup the descriptor set for select(2). Since only one bit in
the set
* ever changes, we need not repeat FD_ZERO each time.
*/
! #ifndef HAVE_POLL
FD_ZERO(&rfds);
#endif
--- 1726,1732 ----
* Setup the descriptor set for select(2). Since only one bit in
the set
* ever changes, we need not repeat FD_ZERO each time.
*/
! #if !defined(HAVE_POLL) && !defined(WIN32)
FD_ZERO(&rfds);
#endif
***************
*** 1772,1778 ****
--- 1774,1782 ----
* which is more important.)
*
* We use poll(2) if available, otherwise select(2)
+ * Win32 has a native implementation.
*/
+ #ifndef WIN32
#ifdef HAVE_POLL
input_fd.fd = pgStatSock;
input_fd.events = POLLIN | POLLERR;
***************
*** 1810,1815 ****
--- 1814,1822 ----
got_data = FD_ISSET(pgStatSock, &rfds);
#endif /* HAVE_POLL */
+ #else /* WIN32 */
+ got_data = pgwin32_waitforsinglesocket(pgStatSock, FD_READ,
PGSTAT_SELECT_TIMEOUT*1000);
+ #endif
/*
* If there is a message on the socket, read it and check for
Index: src/include/port/win32.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/port/win32.h,v
retrieving revision 1.71
diff -c -r1.71 win32.h
*** src/include/port/win32.h 25 Jan 2007 21:50:49 -0000 1.71
--- src/include/port/win32.h 26 Jan 2007 11:27:49 -0000
***************
*** 289,295 ****
int pgwin32_send(SOCKET s, char *buf, int len, int flags);
const char *pgwin32_socket_strerror(int err);
! int pgwin32_waitforsinglesocket(SOCKET s, int what);
/* in backend/port/win32/security.c */
extern int pgwin32_is_admin(void);
--- 289,295 ----
int pgwin32_send(SOCKET s, char *buf, int len, int flags);
const char *pgwin32_socket_strerror(int err);
! int pgwin32_waitforsinglesocket(SOCKET s, int what, int
timeout);
/* in backend/port/win32/security.c */
extern int pgwin32_is_admin(void);
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?
http://archives.postgresql.org/