Skip to content

Commit af591e0

Browse files
committed
Fix and comment possible race condition
1 parent 5953433 commit af591e0

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

lib/concurrent/executor/timer_set.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,20 @@ def process_tasks
130130
interval = task.time - Time.now.to_f
131131

132132
if interval <= 0
133+
# We need to remove the task from the queue before passing
134+
# it to the executor, to avoid race conditions where we pass
135+
# the peek'ed task to the executor and then pop a different
136+
# one that's been added in the meantime.
137+
#
138+
# Note that there's no race condition between the peek and
139+
# this pop - this pop could retrieve a different task from
140+
# the peek, but that task would be due to fire now anyway
141+
# (because @queue is a priority queue, and this thread is
142+
# the only reader, so whatever timer is at the head of the
143+
# queue now must have the same pop time, or a closer one, as
144+
# when we peeked).
145+
task = mutex.synchronize { @queue.pop }
133146
@task_executor.post(*task.args, &task.op)
134-
mutex.synchronize { @queue.pop }
135147
else
136148
mutex.synchronize do
137149
@condition.wait(mutex, [interval, 60].min)

0 commit comments

Comments
 (0)