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