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) raise 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 raise result if result.is_a?(ConditionError) return yield(result) if block_given? result end