class Empathy::EM::ConditionVariable
Provides for Empathys (Fibers) what Ruby’s ConditionVariable
provides for Threads.
Public Class Methods
new()
click to toggle source
Create a new condition variable.
# File lib/empathy/em/condition_variable.rb, line 7 def initialize @waiters = [] end
Public Instance Methods
broadcast()
click to toggle source
Like ::ConditionVariable#broadcast @return [ConditionVariable] self
# File lib/empathy/em/condition_variable.rb, line 55 def broadcast all_waiting = @waiters.dup @waiters.clear ::EM.next_tick { all_waiting.each { |w| w.wakeup } } self end
signal()
click to toggle source
Like ::ConditionVariable#signal @return [ConditionVariable] self
# File lib/empathy/em/condition_variable.rb, line 39 def signal # Find a waiter to wake up until @waiters.empty? waiter = @waiters.shift if waiter.alive? ::EM.next_tick{ waiter.wakeup if waiter.alive? } break; end end self end
wait(mutex=nil,timeout = nil)
click to toggle source
Using a mutex for condition variables is meant to protect against race conditions when the signal occurs between testing whether a wait is needed and waiting. This situation will never occur with fibers, but the semantic is retained for compatibility with ::ConditionVariable @return [ConditionVariable] self
# File lib/empathy/em/condition_variable.rb, line 16 def wait(mutex=nil,timeout = nil) if timeout.nil? && (mutex.nil? || Numeric === mutex) timeout = mutex mutex = nil end # Get the fiber (Empathy::EM::Thread) that called us. thread = Thread.current # Add the fiber to the list of waiters. @waiters << thread begin sleeper = mutex ? mutex : Kernel if timeout then sleeper.sleep(timeout) else sleeper.sleep() end ensure # Remove from list of waiters. Note this doesn't run if the thread is killed @waiters.delete(thread) end self end