pq_getbyte_if_available_on_win32_magnus.patch

application/octet-stream

Filename: pq_getbyte_if_available_on_win32_magnus.patch
Type: application/octet-stream
Part: 0
Message: Re: Streaming Replication on win32

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/libpq/pqcomm.c 12 0
src/backend/port/win32/socket.c 18 0
src/include/port/win32.h 2 0
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 9f0fcbd..ba980cc 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -837,9 +837,13 @@ pq_getbyte_if_available(unsigned char *c)
 	}
 
 	/* Temporarily put the socket into non-blocking mode */
+#ifdef WIN32
+	pgwin32_noblock = 1;
+#else
 	if (!pg_set_noblock(MyProcPort->sock))
 		ereport(ERROR,
 				(errmsg("couldn't put socket to non-blocking mode: %m")));
+#endif
 	MyProcPort->noblock = true;
 	PG_TRY();
 	{
@@ -851,16 +855,24 @@ pq_getbyte_if_available(unsigned char *c)
 		 * The rest of the backend code assumes the socket is in blocking
 		 * mode, so treat failure as FATAL.
 		 */
+#ifdef WIN32
+		pgwin32_noblock = 0;
+#else
 		if (!pg_set_block(MyProcPort->sock))
 			ereport(FATAL,
 					(errmsg("couldn't put socket to blocking mode: %m")));
+#endif
 		MyProcPort->noblock = false;
 		PG_RE_THROW();
 	}
 	PG_END_TRY();
+#ifdef WIN32
+	pgwin32_noblock = 0;
+#else
 	if (!pg_set_block(MyProcPort->sock))
 		ereport(FATAL,
 				(errmsg("couldn't put socket to blocking mode: %m")));
+#endif
 	MyProcPort->noblock = false;
 
 	return r;
diff --git a/src/backend/port/win32/socket.c b/src/backend/port/win32/socket.c
index 5089537..b52dd04 100644
--- a/src/backend/port/win32/socket.c
+++ b/src/backend/port/win32/socket.c
@@ -13,6 +13,14 @@
 
 #include "postgres.h"
 
+/*
+ * This indicates whether pgwin32_recv() is blocked until the receive
+ * operation has been finished. A value of zero blocks it even if
+ * the socket is set to non-blocking mode. A non-zero value makes it
+ * return immediately whether data is available or not.
+ */
+int	pgwin32_noblock = 0;
+
 #undef socket
 #undef accept
 #undef connect
@@ -310,6 +318,16 @@ pgwin32_recv(SOCKET s, char *buf, int len, int f)
 		return -1;
 	}
 
+	if (pgwin32_noblock)
+	{
+		/*
+		 * No data received, and we are in "emulated non-blocking mode", so return
+		 * indicating thta we'd block if we were to continue.
+		 */
+		errno = EWOULDBLOCK;
+		return -1;
+	}
+
 	/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
 
 	for (n = 0; n < 5; n++)
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index 7c482a1..a004861 100644
--- a/src/include/port/win32.h
+++ b/src/include/port/win32.h
@@ -283,6 +283,8 @@ 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);
 
+extern int	pgwin32_noblock;
+
 /* in backend/port/win32/security.c */
 extern int	pgwin32_is_admin(void);
 extern int	pgwin32_is_service(void);