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