Skip to content

Commit af71731

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/[email protected]
1 parent f4e7756 commit af71731

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

src/backend/executor/nodeAppend.c

+25-3
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ ExecAppendAsyncRequest(AppendState *node, TupleTableSlot **result)
10311031
static void
10321032
ExecAppendAsyncEventWait(AppendState *node)
10331033
{
1034-
int nevents = node->as_nasyncplans + 1;
1034+
int nevents = node->as_nasyncplans + 2;
10351035
long timeout = node->as_syncdone ? -1 : 0;
10361036
WaitEvent occurred_event[EVENT_BUFFER_SIZE];
10371037
int noccurred;
@@ -1056,8 +1056,8 @@ ExecAppendAsyncEventWait(AppendState *node)
10561056
}
10571057

10581058
/*
1059-
* No need for further processing if there are no configured events other
1060-
* than the postmaster death event.
1059+
* No need for further processing if none of the subplans configured any
1060+
* events.
10611061
*/
10621062
if (GetNumRegisteredWaitEvents(node->as_eventset) == 1)
10631063
{
@@ -1066,6 +1066,21 @@ ExecAppendAsyncEventWait(AppendState *node)
10661066
return;
10671067
}
10681068

1069+
/*
1070+
* Add the process latch to the set, so that we wake up to process the
1071+
* standard interrupts with CHECK_FOR_INTERRUPTS().
1072+
*
1073+
* NOTE: For historical reasons, it's important that this is added to the
1074+
* WaitEventSet after the ExecAsyncConfigureWait() calls. Namely,
1075+
* postgres_fdw calls "GetNumRegisteredWaitEvents(set) == 1" to check if
1076+
* any other events are in the set. That's a poor design, it's
1077+
* questionable for postgres_fdw to be doing that in the first place, but
1078+
* we cannot change it now. The pattern has possibly been copied to other
1079+
* extensions too.
1080+
*/
1081+
AddWaitEventToSet(node->as_eventset, WL_LATCH_SET, PGINVALID_SOCKET,
1082+
MyLatch, NULL);
1083+
10691084
/* Return at most EVENT_BUFFER_SIZE events in one call. */
10701085
if (nevents > EVENT_BUFFER_SIZE)
10711086
nevents = EVENT_BUFFER_SIZE;
@@ -1107,6 +1122,13 @@ ExecAppendAsyncEventWait(AppendState *node)
11071122
ExecAsyncNotify(areq);
11081123
}
11091124
}
1125+
1126+
/* Handle standard interrupts */
1127+
if ((w->events & WL_LATCH_SET) != 0)
1128+
{
1129+
ResetLatch(MyLatch);
1130+
CHECK_FOR_INTERRUPTS();
1131+
}
11101132
}
11111133
}
11121134

0 commit comments

Comments
 (0)