mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
Forward received condition variable signals on cancel.
After a process decides not to wait for a condition variable, it can still consume a signal before it reaches ConditionVariableCancelSleep(). In that case, pass the signal on to another waiter if possible, so that a signal doesn't go missing when there is another process ready to receive it. Author: Thomas Munro Reviewed-by: Shawn Debnath Discussion: https://postgr.es/m/CA%2BhUKGLQ_RW%2BXs8znDn36e-%2Bmq2--zrPemBqTQ8eKT-VO1OF4Q%40mail.gmail.com
This commit is contained in:
parent
1321509fa4
commit
b91dd9de5e
@ -245,6 +245,7 @@ void
|
||||
ConditionVariableCancelSleep(void)
|
||||
{
|
||||
ConditionVariable *cv = cv_sleep_target;
|
||||
bool signaled = false;
|
||||
|
||||
if (cv == NULL)
|
||||
return;
|
||||
@ -252,8 +253,18 @@ ConditionVariableCancelSleep(void)
|
||||
SpinLockAcquire(&cv->mutex);
|
||||
if (proclist_contains(&cv->wakeup, MyProc->pgprocno, cvWaitLink))
|
||||
proclist_delete(&cv->wakeup, MyProc->pgprocno, cvWaitLink);
|
||||
else
|
||||
signaled = true;
|
||||
SpinLockRelease(&cv->mutex);
|
||||
|
||||
/*
|
||||
* If we've received a signal, pass it on to another waiting process, if
|
||||
* there is one. Otherwise a call to ConditionVariableSignal() might get
|
||||
* lost, despite there being another process ready to handle it.
|
||||
*/
|
||||
if (signaled)
|
||||
ConditionVariableSignal(cv);
|
||||
|
||||
cv_sleep_target = NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user