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);