Sha256: 11051671eeab2ae2aabf29ce1ac6ccee51b93547e5e8b014635a7783ba0c7fbf

Contents?: true

Size: 1.64 KB

Versions: 1

Compression:

Stored size: 1.64 KB

Contents

module Celluloid
  class ConditionError < StandardError; end

  # ConditionVariable-like signaling between tasks and actors
  class Condition
    attr_reader :owner

    def initialize
      @mutex = Mutex.new
      @owner = Actor.current
      @tasks = []
    end

    # Wait for the given signal and return the associated value
    def wait
      raise ConditionError, "cannot wait for signals while exclusive" if Celluloid.exclusive?

      @mutex.synchronize do
        raise ConditionError, "can't wait unless owner" unless Actor.current == @owner
        @tasks << Task.current
      end

      result = Task.suspend :condwait
      raise result if result.is_a? ConditionError
      result
    end

    # Send a signal to the first task waiting on this condition
    def signal(value = nil)
       @mutex.synchronize do
        if task = @tasks.shift
          @owner.mailbox << SignalConditionRequest.new(task, value)
        else
          Logger.debug("Celluloid::Condition signaled spuriously")
        end
      end
    end

    # Broadcast a value to all waiting tasks
    def broadcast(value = nil)
      @mutex.synchronize do
        @tasks.each { |task| @owner.mailbox << SignalConditionRequest.new(task, value) }
        @tasks.clear
      end
    end

    # Change the owner of this condition
    def owner=(actor)
      @mutex.synchronize do
        if @owner != actor
          @tasks.each do |task|
            ex = ConditionError.new("ownership changed")
            @owner.mailbox << SignalConditionRequest.new(task, ex)
          end
          @tasks.clear
        end

        @owner = actor
      end
    end

    alias_method :inspect, :to_s
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
celluloid-0.13.0.pre lib/celluloid/condition.rb