# File lib/dynflow/clock.rb, line 43 def initialize @timers = SortedSet.new @sleeping_pill = None @sleep_barrier = Mutex.new @sleeper = Thread.new { sleeping } Thread.pass until @sleep_barrier.locked? || @sleeper.status == 'sleep' end
# File lib/dynflow/clock.rb, line 66 def add_timer(timer) @timers.add timer if @timers.size == 1 sleep_to timer else wakeup if timer == first_timer end end
# File lib/dynflow/clock.rb, line 51 def default_reference_class ClockReference end
# File lib/dynflow/clock.rb, line 55 def on_event(event) if event == :terminated @sleeper.kill end end
# File lib/dynflow/clock.rb, line 61 def tick run_ready_timers sleep_to first_timer end
# File lib/dynflow/clock.rb, line 84 def first_timer @timers.first end
# File lib/dynflow/clock.rb, line 77 def run_ready_timers while first_timer && first_timer.when <= Time.now first_timer.apply @timers.delete(first_timer) end end
# File lib/dynflow/clock.rb, line 97 def sleep_to(timer) return unless timer sec = [timer.when - Time.now, 0.0].max @sleep_barrier.synchronize do @sleeping_pill = Pill[sec] @sleeper.wakeup end end
# File lib/dynflow/clock.rb, line 106 def sleeping @sleep_barrier.synchronize do loop do @sleeping_pill = None @sleep_barrier.sleep pill = @sleeping_pill @sleeping_pill = Took @sleep_barrier.sleep pill.value reference.tell(:tick) end end end
# File lib/dynflow/clock.rb, line 88 def wakeup while @sleep_barrier.synchronize { Pill === @sleeping_pill } Thread.pass end @sleep_barrier.synchronize do @sleeper.wakeup if Took === @sleeping_pill end end