Skip to content

Commit e34f925

Browse files
bdrouvotAWSCommitfest Bot
authored andcommitted
Fix a race condition in ConditionVariableTimedSleep()
A process could exit ConditionVariableTimedSleep() after detecting a state change (cv != cv_sleep_target) without being removed from the list. When ConditionVariableTimedSleep() detects that the process is no longer in the wait list (could be signaled by ConditionVariableSignal() or ConditionVariableBroadcast()), it re-adds itself to ensure that we don't miss any additional wakeup. The issue is that it could leave ConditionVariableTimedSleep() with cv_sleep_target set to NULL and the process re-added in the wait list. If cv_sleep_target is set to NULL then subsequent calls to ConditionVariableCancelSleep() will return early without removing the process from any list. This could to an assertion failure when the process later tries to wait on a condition variable, as ConditionVariablePrepareToSleep() skips cleanup when cv_sleep_target is NULL, resulting in a process trying to be in two wait lists simultaneously. The fix re-assigns cv_sleep_target to cv and then ensures that cv_sleep_target accurately describes which condition variable we’re prepared to wait on.
1 parent 5c8eda1 commit e34f925

File tree

1 file changed

+2
-0
lines changed

1 file changed

+2
-0
lines changed

src/backend/storage/lmgr/condition_variable.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
184184
if (!proclist_contains(&cv->wakeup, MyProcNumber, cvWaitLink))
185185
{
186186
done = true;
187+
if (cv_sleep_target == NULL)
188+
cv_sleep_target = cv;
187189
proclist_push_tail(&cv->wakeup, MyProcNumber, cvWaitLink);
188190
}
189191
SpinLockRelease(&cv->mutex);

0 commit comments

Comments
 (0)