mirror of
https://github.com/postgres/postgres.git
synced 2025-05-20 00:03:14 -04:00
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
This commit is contained in:
parent
ca0830e5a2
commit
e731e9d5ee
@ -1016,7 +1016,7 @@ ExecAppendAsyncRequest(AppendState *node, TupleTableSlot **result)
|
|||||||
static void
|
static void
|
||||||
ExecAppendAsyncEventWait(AppendState *node)
|
ExecAppendAsyncEventWait(AppendState *node)
|
||||||
{
|
{
|
||||||
int nevents = node->as_nasyncplans + 1;
|
int nevents = node->as_nasyncplans + 2;
|
||||||
long timeout = node->as_syncdone ? -1 : 0;
|
long timeout = node->as_syncdone ? -1 : 0;
|
||||||
WaitEvent occurred_event[EVENT_BUFFER_SIZE];
|
WaitEvent occurred_event[EVENT_BUFFER_SIZE];
|
||||||
int noccurred;
|
int noccurred;
|
||||||
@ -1041,8 +1041,8 @@ ExecAppendAsyncEventWait(AppendState *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No need for further processing if there are no configured events other
|
* No need for further processing if none of the subplans configured any
|
||||||
* than the postmaster death event.
|
* events.
|
||||||
*/
|
*/
|
||||||
if (GetNumRegisteredWaitEvents(node->as_eventset) == 1)
|
if (GetNumRegisteredWaitEvents(node->as_eventset) == 1)
|
||||||
{
|
{
|
||||||
@ -1051,6 +1051,21 @@ ExecAppendAsyncEventWait(AppendState *node)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the process latch to the set, so that we wake up to process the
|
||||||
|
* standard interrupts with CHECK_FOR_INTERRUPTS().
|
||||||
|
*
|
||||||
|
* NOTE: For historical reasons, it's important that this is added to the
|
||||||
|
* WaitEventSet after the ExecAsyncConfigureWait() calls. Namely,
|
||||||
|
* postgres_fdw calls "GetNumRegisteredWaitEvents(set) == 1" to check if
|
||||||
|
* any other events are in the set. That's a poor design, it's
|
||||||
|
* questionable for postgres_fdw to be doing that in the first place, but
|
||||||
|
* we cannot change it now. The pattern has possibly been copied to other
|
||||||
|
* extensions too.
|
||||||
|
*/
|
||||||
|
AddWaitEventToSet(node->as_eventset, WL_LATCH_SET, PGINVALID_SOCKET,
|
||||||
|
MyLatch, NULL);
|
||||||
|
|
||||||
/* Return at most EVENT_BUFFER_SIZE events in one call. */
|
/* Return at most EVENT_BUFFER_SIZE events in one call. */
|
||||||
if (nevents > EVENT_BUFFER_SIZE)
|
if (nevents > EVENT_BUFFER_SIZE)
|
||||||
nevents = EVENT_BUFFER_SIZE;
|
nevents = EVENT_BUFFER_SIZE;
|
||||||
@ -1092,6 +1107,13 @@ ExecAppendAsyncEventWait(AppendState *node)
|
|||||||
ExecAsyncNotify(areq);
|
ExecAsyncNotify(areq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle standard interrupts */
|
||||||
|
if ((w->events & WL_LATCH_SET) != 0)
|
||||||
|
{
|
||||||
|
ResetLatch(MyLatch);
|
||||||
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user