v9-0002-fe_utils-Simplify-cancel-logic-in-wait_on_slots.patch
text/x-patch
Filename: v9-0002-fe_utils-Simplify-cancel-logic-in-wait_on_slots.patch
Type: text/x-patch
Part: 1
Patch
Format: format-patch
Series: patch v9-0002
Subject: fe_utils: Simplify cancel logic in wait_on_slots
| File | + | − |
|---|---|---|
| src/fe_utils/parallel_slot.c | 14 | 19 |
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