v2-0004-Remove-pgwin32_select.patch

text/x-patch

Filename: v2-0004-Remove-pgwin32_select.patch
Type: text/x-patch
Part: 3
Message: Re: Why is src/test/modules/committs/t/002_standby.pl flaky?

Patch

Format: format-patch
Series: patch v2-0004
Subject: Remove pgwin32_select().
File+
src/backend/port/win32/socket.c 0 200
src/include/port/win32_port.h 0 2
From c561d1f7091368c5e09735ab099eb4a656587dfb Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 10 Nov 2023 08:41:28 +1300
Subject: [PATCH v2 4/6] Remove pgwin32_select().

pgwin32_select(), used to replace select() in backend code on Windows,
would need to be updated to use the new per-socket event handles.  Since
the last remaining user of select() in the backend is scheduled for
replacement with the WaitEventSet API, it seems better to demolish it
instead.

Any extension code that is relying on select() with fake signals will
still compile, but will no longer respond to signals.  Hypothetical code
like that is probably buggy anyway, because backend code should also be
handling interrupts, and should switch to the various WaitEventSet APIs.
---
 src/backend/port/win32/socket.c | 200 --------------------------------
 src/include/port/win32_port.h   |   2 -
 2 files changed, 202 deletions(-)

diff --git a/src/backend/port/win32/socket.c b/src/backend/port/win32/socket.c
index a7fa98cb1d..d0cf08392f 100644
--- a/src/backend/port/win32/socket.c
+++ b/src/backend/port/win32/socket.c
@@ -867,203 +867,3 @@ pgwin32_send(SOCKET s, const void *buf, int len, int flags)
 
 	return -1;
 }
-
-
-/*
- * Wait for activity on one or more sockets.
- * While waiting, allow signals to run
- *
- * NOTE! Currently does not implement exceptfds check,
- * since it is not used in postgresql!
- */
-int
-pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout)
-{
-	WSAEVENT	events[FD_SETSIZE * 2]; /* worst case is readfds totally
-										 * different from writefds, so
-										 * 2*FD_SETSIZE sockets */
-	SOCKET		sockets[FD_SETSIZE * 2];
-	int			numevents = 0;
-	int			i;
-	int			r;
-	DWORD		timeoutval = WSA_INFINITE;
-	FD_SET		outreadfds;
-	FD_SET		outwritefds;
-	int			nummatches = 0;
-
-	Assert(exceptfds == NULL);
-
-	if (pgwin32_poll_signals())
-		return -1;
-
-	FD_ZERO(&outreadfds);
-	FD_ZERO(&outwritefds);
-
-	/*
-	 * Windows does not guarantee to log an FD_WRITE network event indicating
-	 * that more data can be sent unless the previous send() failed with
-	 * WSAEWOULDBLOCK.  While our caller might well have made such a call, we
-	 * cannot assume that here.  Therefore, if waiting for write-ready, force
-	 * the issue by doing a dummy send().  If the dummy send() succeeds,
-	 * assume that the socket is in fact write-ready, and return immediately.
-	 * Also, if it fails with something other than WSAEWOULDBLOCK, return a
-	 * write-ready indication to let our caller deal with the error condition.
-	 */
-	if (writefds != NULL)
-	{
-		for (i = 0; i < writefds->fd_count; i++)
-		{
-			char		c;
-			WSABUF		buf;
-			DWORD		sent;
-
-			buf.buf = &c;
-			buf.len = 0;
-
-			r = WSASend(writefds->fd_array[i], &buf, 1, &sent, 0, NULL, NULL);
-			if (r == 0 || WSAGetLastError() != WSAEWOULDBLOCK)
-				FD_SET(writefds->fd_array[i], &outwritefds);
-		}
-
-		/* If we found any write-ready sockets, just return them immediately */
-		if (outwritefds.fd_count > 0)
-		{
-			memcpy(writefds, &outwritefds, sizeof(fd_set));
-			if (readfds)
-				FD_ZERO(readfds);
-			return outwritefds.fd_count;
-		}
-	}
-
-
-	/* Now set up for an actual select */
-
-	if (timeout != NULL)
-	{
-		/* timeoutval is in milliseconds */
-		timeoutval = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
-	}
-
-	if (readfds != NULL)
-	{
-		for (i = 0; i < readfds->fd_count; i++)
-		{
-			events[numevents] = WSACreateEvent();
-			sockets[numevents] = readfds->fd_array[i];
-			numevents++;
-		}
-	}
-	if (writefds != NULL)
-	{
-		for (i = 0; i < writefds->fd_count; i++)
-		{
-			if (!readfds ||
-				!FD_ISSET(writefds->fd_array[i], readfds))
-			{
-				/* If the socket is not in the read list */
-				events[numevents] = WSACreateEvent();
-				sockets[numevents] = writefds->fd_array[i];
-				numevents++;
-			}
-		}
-	}
-
-	for (i = 0; i < numevents; i++)
-	{
-		int			flags = 0;
-
-		if (readfds && FD_ISSET(sockets[i], readfds))
-			flags |= FD_READ | FD_ACCEPT | FD_CLOSE;
-
-		if (writefds && FD_ISSET(sockets[i], writefds))
-			flags |= FD_WRITE | FD_CLOSE;
-
-		if (WSAEventSelect(sockets[i], events[i], flags) != 0)
-		{
-			TranslateSocketError();
-			/* release already-assigned event objects */
-			while (--i >= 0)
-				WSAEventSelect(sockets[i], NULL, 0);
-			for (i = 0; i < numevents; i++)
-				WSACloseEvent(events[i]);
-			return -1;
-		}
-	}
-
-	events[numevents] = pgwin32_signal_event;
-	r = WaitForMultipleObjectsEx(numevents + 1, events, FALSE, timeoutval, TRUE);
-	if (r != WAIT_TIMEOUT && r != WAIT_IO_COMPLETION && r != (WAIT_OBJECT_0 + numevents))
-	{
-		/*
-		 * We scan all events, even those not signaled, in case more than one
-		 * event has been tagged but Wait.. can only return one.
-		 */
-		WSANETWORKEVENTS resEvents;
-
-		for (i = 0; i < numevents; i++)
-		{
-			ZeroMemory(&resEvents, sizeof(resEvents));
-			if (WSAEnumNetworkEvents(sockets[i], events[i], &resEvents) != 0)
-				elog(ERROR, "failed to enumerate network events: error code %d",
-					 WSAGetLastError());
-			/* Read activity? */
-			if (readfds && FD_ISSET(sockets[i], readfds))
-			{
-				if ((resEvents.lNetworkEvents & FD_READ) ||
-					(resEvents.lNetworkEvents & FD_ACCEPT) ||
-					(resEvents.lNetworkEvents & FD_CLOSE))
-				{
-					FD_SET(sockets[i], &outreadfds);
-
-					nummatches++;
-				}
-			}
-			/* Write activity? */
-			if (writefds && FD_ISSET(sockets[i], writefds))
-			{
-				if ((resEvents.lNetworkEvents & FD_WRITE) ||
-					(resEvents.lNetworkEvents & FD_CLOSE))
-				{
-					FD_SET(sockets[i], &outwritefds);
-
-					nummatches++;
-				}
-			}
-		}
-	}
-
-	/* Clean up all the event objects */
-	for (i = 0; i < numevents; i++)
-	{
-		WSAEventSelect(sockets[i], NULL, 0);
-		WSACloseEvent(events[i]);
-	}
-
-	if (r == WSA_WAIT_TIMEOUT)
-	{
-		if (readfds)
-			FD_ZERO(readfds);
-		if (writefds)
-			FD_ZERO(writefds);
-		return 0;
-	}
-
-	/* Signal-like events. */
-	if (r == WAIT_OBJECT_0 + numevents || r == WAIT_IO_COMPLETION)
-	{
-		pgwin32_dispatch_queued_signals();
-		errno = EINTR;
-		if (readfds)
-			FD_ZERO(readfds);
-		if (writefds)
-			FD_ZERO(writefds);
-		return -1;
-	}
-
-	/* Overwrite socket sets with our resulting values */
-	if (readfds)
-		memcpy(readfds, &outreadfds, sizeof(fd_set));
-	if (writefds)
-		memcpy(writefds, &outwritefds, sizeof(fd_set));
-	return nummatches;
-}
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index a0ed6aaeaa..1b605d9403 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -492,7 +492,6 @@ extern int	pgkill(int pid, int sig);
 #define listen(s, backlog) pgwin32_listen(s, backlog)
 #define accept(s, addr, addrlen) pgwin32_accept(s, addr, addrlen)
 #define connect(s, name, namelen) pgwin32_connect(s, name, namelen)
-#define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout)
 #define recv(s, buf, len, flags) pgwin32_recv(s, buf, len, flags)
 #define send(s, buf, len, flags) pgwin32_send(s, buf, len, flags)
 
@@ -501,7 +500,6 @@ extern int	pgwin32_bind(SOCKET s, struct sockaddr *addr, int addrlen);
 extern int	pgwin32_listen(SOCKET s, int backlog);
 extern SOCKET pgwin32_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
 extern int	pgwin32_connect(SOCKET s, const struct sockaddr *name, int namelen);
-extern int	pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout);
 extern int	pgwin32_recv(SOCKET s, char *buf, int len, int flags);
 extern int	pgwin32_send(SOCKET s, const void *buf, int len, int flags);
 extern int	pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
-- 
2.42.0