From 8d04d1fca779c5b1f2cfe02a30a216d7af0a5a1e Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <postgres@jeltef.nl>
Date: Tue, 7 Apr 2026 19:54:13 +0200
Subject: [PATCH v9 2/7] fe_utils: Simplify cancel logic in wait_on_slots

This removes the SetCancelConn call in wait_on_slots. This call was
confusing because it was only called for a single connection of all the
connections that the select_loop would wait on. Turns out that it can be
be made completely redundant by moving the check for CancelRequested
before the check for EINTR.
---
 src/fe_utils/parallel_slot.c | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/src/fe_utils/parallel_slot.c b/src/fe_utils/parallel_slot.c
index fb9e6cc4ec1..67536a851cf 100644
--- a/src/fe_utils/parallel_slot.c
+++ b/src/fe_utils/parallel_slot.c
@@ -89,20 +89,22 @@ select_loop(int maxFd, fd_set *workerset)
 	{
 		/*
 		 * On Windows, we need to check once in a while for cancel requests;
-		 * on other platforms we rely on select() returning when interrupted.
+		 * on other platforms we can generally rely on select() returning when
+		 * interrupted, but even on those platforms its possible for another
+		 * signal to interrupt the select and then for SIGINT to arrive and
+		 * race between our CancelRequested check and us re-arming the
+		 * select(). So we also add a timeout of 1 second to the select, so we
+		 * can manually poll CancelRequested as a fallback.
 		 */
-		struct timeval *tvp;
-#ifdef WIN32
 		struct timeval tv = {0, 1000000};
-
-		tvp = &tv;
-#else
-		tvp = NULL;
-#endif
+		struct timeval *tvp = &tv;
 
 		*workerset = saveSet;
 		i = select(maxFd + 1, workerset, NULL, NULL, tvp);
 
+		if (CancelRequested)
+			return -1;
+
 #ifdef WIN32
 		if (i == SOCKET_ERROR)
 		{
@@ -115,10 +117,10 @@ select_loop(int maxFd, fd_set *workerset)
 
 		if (i < 0 && errno == EINTR)
 			continue;			/* ignore this */
-		if (i < 0 || CancelRequested)
+		if (i < 0)
 			return -1;			/* but not this */
 		if (i == 0)
-			continue;			/* timeout (Win32 only) */
+			continue;			/* timeout */
 		break;
 	}
 
@@ -197,8 +199,7 @@ wait_on_slots(ParallelSlotArray *sa)
 {
 	int			i;
 	fd_set		slotset;
-	int			maxFd = 0;
-	PGconn	   *cancelconn = NULL;
+	int			maxFd = -1;
 
 	/* We must reconstruct the fd_set for each call to select_loop */
 	FD_ZERO(&slotset);
@@ -219,10 +220,6 @@ wait_on_slots(ParallelSlotArray *sa)
 		if (sock < 0)
 			continue;
 
-		/* Keep track of the first valid connection we see. */
-		if (cancelconn == NULL)
-			cancelconn = sa->slots[i].connection;
-
 		FD_SET(sock, &slotset);
 		if (sock > maxFd)
 			maxFd = sock;
@@ -232,12 +229,10 @@ wait_on_slots(ParallelSlotArray *sa)
 	 * If we get this far with no valid connections, processing cannot
 	 * continue.
 	 */
-	if (cancelconn == NULL)
+	if (maxFd < 0)
 		return false;
 
-	SetCancelConn(cancelconn);
 	i = select_loop(maxFd, &slotset);
-	ResetCancelConn();
 
 	/* failure? */
 	if (i < 0)
-- 
2.54.0

