Skip to content

Commit d2fb076

Browse files
committed
Handle interrupts while waiting on Append's async subplans
We did not wake up on interrupts while waiting on async events on an async-capable append node. For example, if you tried to cancel the query, nothing would happen until one of the async subplans becomes readable. To fix, add WL_LATCH_SET to the WaitEventSet. Backpatch down to v14 where async Append execution was introduced. Discussion: https://www.postgresql.org/message-id/37a40570-f558-40d3-b5ea-5c2079b3b30b@iki.fi
1 parent d3a29ae commit d2fb076

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

src/backend/executor/nodeAppend.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ ExecAppendAsyncRequest(AppendState *node, TupleTableSlot **result)
10201020
static void
10211021
ExecAppendAsyncEventWait(AppendState *node)
10221022
{
1023-
int nevents = node->as_nasyncplans + 1;
1023+
int nevents = node->as_nasyncplans + 2;
10241024
long timeout = node->as_syncdone ? -1 : 0;
10251025
WaitEvent occurred_event[EVENT_BUFFER_SIZE];
10261026
int noccurred;
@@ -1047,13 +1047,28 @@ ExecAppendAsyncEventWait(AppendState *node)
10471047
}
10481048

10491049
/*
1050-
* If there are no configured events other than the postmaster death
1051-
* event, we don't need to wait or poll.
1050+
* No need for further processing if none of the subplans configured
1051+
* any events.
10521052
*/
10531053
if (GetNumRegisteredWaitEvents(node->as_eventset) == 1)
10541054
noccurred = 0;
10551055
else
10561056
{
1057+
/*
1058+
* Add the process latch to the set, so that we wake up to process
1059+
* the standard interrupts with CHECK_FOR_INTERRUPTS().
1060+
*
1061+
* NOTE: For historical reasons, it's important that this is added
1062+
* to the WaitEventSet after the ExecAsyncConfigureWait() calls.
1063+
* Namely, postgres_fdw calls "GetNumRegisteredWaitEvents(set) ==
1064+
* 1" to check if any other events are in the set. That's a poor
1065+
* design, it's questionable for postgres_fdw to be doing that in
1066+
* the first place, but we cannot change it now. The pattern has
1067+
* possibly been copied to other extensions too.
1068+
*/
1069+
AddWaitEventToSet(node->as_eventset, WL_LATCH_SET, PGINVALID_SOCKET,
1070+
MyLatch, NULL);
1071+
10571072
/* Return at most EVENT_BUFFER_SIZE events in one call. */
10581073
if (nevents > EVENT_BUFFER_SIZE)
10591074
nevents = EVENT_BUFFER_SIZE;
@@ -1102,6 +1117,13 @@ ExecAppendAsyncEventWait(AppendState *node)
11021117
ExecAsyncNotify(areq);
11031118
}
11041119
}
1120+
1121+
/* Handle standard interrupts */
1122+
if ((w->events & WL_LATCH_SET) != 0)
1123+
{
1124+
ResetLatch(MyLatch);
1125+
CHECK_FOR_INTERRUPTS();
1126+
}
11051127
}
11061128
}
11071129

0 commit comments

Comments
 (0)