class Celluloid::Condition

ConditionVariable-like signaling between tasks and threads

Public Class Methods

new() click to toggle source
# File lib/celluloid/condition.rb, line 30
def initialize
  @mutex = Mutex.new
  @waiters = []
end

Public Instance Methods

broadcast(value = nil) click to toggle source

Broadcast a value to all waiting tasks and threads

# File lib/celluloid/condition.rb, line 79
def broadcast(value = nil)
  @mutex.synchronize do
    @waiters.each { |waiter| waiter << SignalConditionRequest.new(waiter.task, value) }
    @waiters.clear
  end
end
signal(value = nil) click to toggle source

Send a signal to the first task waiting on this condition

# File lib/celluloid/condition.rb, line 66
def signal(value = nil)
  @mutex.synchronize do
    if waiter = @waiters.shift
      waiter << SignalConditionRequest.new(waiter.task, value)
    else
      Internals::Logger.with_backtrace(caller(3)) do |logger|
        logger.debug("Celluloid::Condition signaled spuriously")
      end
    end
  end
end
wait(timeout = nil) { |result| ... } click to toggle source

Wait for the given signal and return the associated value

# File lib/celluloid/condition.rb, line 36
def wait(timeout = nil)
  fail ConditionError, "cannot wait for signals while exclusive" if Celluloid.exclusive?

  if actor = Thread.current[:celluloid_actor]
    task = Task.current
    if timeout
      bt = caller
      timer = actor.timers.after(timeout) do
        exception = ConditionError.new("timeout after #{timeout.inspect} seconds")
        exception.set_backtrace bt
        task.resume exception
      end
    end
  else
    task = Thread.current
  end
  waiter = Waiter.new(self, task, Celluloid.mailbox, timeout)

  @mutex.synchronize do
    @waiters << waiter
  end

  result = Celluloid.suspend :condwait, waiter
  timer.cancel if timer
  fail result if result.is_a?(ConditionError)
  return yield(result) if block_given?
  result
end