From: Robert Larsen Date: 2009-09-10T20:15:08+09:00 Subject: Timer implementation Hi all I am porting a timer class that I wrote in Java many years ago but I cannot see how to implement it in Ruby. What I want is a single thread, that sleeps forever or until the next timer block should be called or until a new timer block i added. The thread should be woken when a new timer block is added because it might be the next one to be called. I have implemented it like this: #!/usr/bin/ruby require 'thread' require 'bsearch' class Timer class TimerObject attr_reader :invoke_time, :block def initialize(invoke_time, block) @invoke_time, @block = invoke_time, block end end def initialize @timer_list = [] @mutex = Mutex.new @condition = ConditionVariable.new @running = false start end def stop running = false @mutex.synchronize { @condition.signal } end def start @running = true Thread.new do @mutex.synchronize do an_hour = 60 * 60 * 1000 while running now_in_milliseconds = (Time.now.to_f * 1000).to_i milliseconds_to_sleep = @timer_list.empty? ? an_hour : @timer_list.first.invoke_time - now_in_milliseconds @condition.wait(@mutex, now_in_milliseconds) while @timer_list.empty? now_in_milliseconds = (Time.now.to_f * 1000).to_i while @time_list.empty? == false and @time_list.first.invoke_time < now_in_milliseconds @time_list.delete_at(0).block.call end end end end end def postpone (timeout, &block) now = (Time.now.to_f * 1000).to_i time = now + timeout timerobject = TimerObject.new time, block @mutex.synchronize do idx = @timer_list.bsearch_lower_boundary { |x| x.invoke_time <=> time } @timer_list.insert(idx, timerobject) unless idx.nil? @timer_list << timerobject if idx.nil? @condition.signal end end end BUT...the 'start' method does not work since 'ConditionVariable' does not have a 'wait' method that takes a maximum wait time in milliseconds like we have in Java. Any ideas as to how this can be done ? Or is there a better way ? I really don't want a thread per timer. Best regards, Robert