Skip to content

Commit d989c76

Browse files
committed
Prevent ABA problem
1 parent 904e641 commit d989c76

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

base/condition.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ function wait(c::GenericCondition; first::Bool=false, timeout::Real=0.0)
145145
token = unlockall(c.lock)
146146

147147
timer::Union{Timer, Nothing} = nothing
148+
waiter_left = Threads.Atomic{Bool}(false)
148149
if timeout > 0.0
149150
timer = Timer(timeout)
150151
# start a task to wait on the timer
@@ -160,7 +161,7 @@ function wait(c::GenericCondition; first::Bool=false, timeout::Real=0.0)
160161
# Confirm that the waiting task is still in the wait queue and remove it. If
161162
# the task is not in the wait queue, it must have been notified already so we
162163
# don't do anything here.
163-
if ct.queue == c.waitq
164+
if !waiter_left[] && ct.queue == c.waitq
164165
dosched = true
165166
Base.list_deletefirst!(c.waitq, ct)
166167
end
@@ -174,7 +175,10 @@ function wait(c::GenericCondition; first::Bool=false, timeout::Real=0.0)
174175

175176
try
176177
res = wait()
177-
timer === nothing || close(timer)
178+
if timer !== nothing
179+
close(timer)
180+
waiter_left[] = true
181+
end
178182
return res
179183
catch
180184
q = ct.queue; q === nothing || Base.list_deletefirst!(q::IntrusiveLinkedList{Task}, ct)

0 commit comments

Comments
 (0)