diff --git a/src/backend/port/win32/socket.c b/src/backend/port/win32/socket.c
index c7557034b755b4ca9a9d216951bdf6bcfecc5253..3c6fbdb60d87ff56b0080328677a5c975a863173 100644
--- a/src/backend/port/win32/socket.c
+++ b/src/backend/port/win32/socket.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.17 2007/01/26 20:06:52 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.18 2007/06/04 13:39:28 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -291,6 +291,7 @@ pgwin32_recv(SOCKET s, char *buf, int len, int f)
 	int			r;
 	DWORD		b;
 	DWORD		flags = f;
+	int		n;
 
 	if (pgwin32_poll_signals())
 		return -1;
@@ -312,17 +313,36 @@ pgwin32_recv(SOCKET s, char *buf, int len, int f)
 
 	/* 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);
-	if (r == SOCKET_ERROR)
+	for (n = 0; n < 5; n++)
 	{
-		TranslateSocketError();
-		return -1;
+		if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT,
+										INFINITE) == 0)
+			return -1; /* errno already set */
+	
+		r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
+		if (r == SOCKET_ERROR)
+		{
+			if (WSAGetLastError() == WSAEWOULDBLOCK)
+			{
+				/*
+				 * There seem to be cases on win2k (at least) where WSARecv
+				 * can return WSAEWOULDBLOCK even when pgwin32_waitforsinglesocket
+				 * claims the socket is readable. In this case, just sleep for a
+				 * moment and try again. We try up to 5 times - if it fails more than
+				 * that it's not likely to ever come back.
+				 */
+				pg_usleep(10000);
+				continue;
+			}
+			TranslateSocketError();
+			return -1;
+		}
+		return b;
 	}
-	return b;
+	ereport(NOTICE,
+		(errmsg_internal("Failed to read from ready socket (after retries)")));
+	errno = EWOULDBLOCK;
+	return -1;
 }
 
 int