Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b91dd9d

Browse files
committed
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
1 parent 1321509 commit b91dd9d

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

src/backend/storage/lmgr/condition_variable.c

+11
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,26 @@ void
245245
ConditionVariableCancelSleep(void)
246246
{
247247
ConditionVariable *cv = cv_sleep_target;
248+
bool signaled = false;
248249

249250
if (cv == NULL)
250251
return;
251252

252253
SpinLockAcquire(&cv->mutex);
253254
if (proclist_contains(&cv->wakeup, MyProc->pgprocno, cvWaitLink))
254255
proclist_delete(&cv->wakeup, MyProc->pgprocno, cvWaitLink);
256+
else
257+
signaled = true;
255258
SpinLockRelease(&cv->mutex);
256259

260+
/*
261+
* If we've received a signal, pass it on to another waiting process, if
262+
* there is one. Otherwise a call to ConditionVariableSignal() might get
263+
* lost, despite there being another process ready to handle it.
264+
*/
265+
if (signaled)
266+
ConditionVariableSignal(cv);
267+
257268
cv_sleep_target = NULL;
258269
}
259270

0 commit comments

Comments
 (0)