lib/celluloid/actor.rb in celluloid-0.13.0.pre vs lib/celluloid/actor.rb in celluloid-0.13.0.pre2

- old
+ new

@@ -64,23 +64,11 @@ mailbox << call rescue MailboxError raise DeadActorError, "attempted to call a dead actor" end - if Thread.current[:celluloid_task] && !Celluloid.exclusive? - Task.suspend(:callwait).value - else - response = loop do - message = Thread.mailbox.receive do |msg| - msg.respond_to?(:call) and msg.call == call - end - break message unless message.is_a?(SystemEvent) - Thread.current[:celluloid_actor].handle_system_event(message) - end - - response.value - end + Celluloid.suspend(:callwait, call).value end # Invoke a method asynchronously on an actor via its mailbox def async(mailbox, meth, *args, &block) begin @@ -166,11 +154,11 @@ @mailbox = options[:mailbox] || Mailbox.new @exit_handler = options[:exit_handler] @exclusives = options[:exclusive_methods] @task_class = options[:task_class] || Celluloid.task_class - @tasks = Set.new + @tasks = TaskSet.new @links = Links.new @signals = Signals.new @receivers = Receivers.new @timers = Timers.new @running = true @@ -306,19 +294,29 @@ # Schedule a block to run at the given time def every(interval, &block) @timers.every(interval) { task(:timer, &block) } end + class Sleeper + def initialize(timers, interval) + @timers = timers + @interval = interval + end + + def before_suspend(task) + @timers.after(@interval) { task.resume } + end + + def wait + Kernel.sleep(@interval) + end + end + # Sleep for the given amount of time def sleep(interval) - task = Thread.current[:celluloid_task] - if task && !Celluloid.exclusive? - @timers.after(interval) { task.resume } - Task.suspend :sleeping - else - Kernel.sleep(interval) - end + sleeper = Sleeper.new(@timers, interval) + Celluloid.suspend(:sleeping, sleeper) end # Handle standard low-priority messages def handle_message(message) case message @@ -388,11 +386,11 @@ task(:finalizer, :finalize) { @subject.finalize } end finalizer = @subject.class.finalizer - if finalizer && @subject.respond_to?(finalizer) + if finalizer && @subject.respond_to?(finalizer, true) task(:finalizer, :finalize) { @subject.__send__(finalizer) } end rescue => ex Logger.crash("#{@subject.class}#finalize crashed!", ex) end @@ -413,10 +411,10 @@ Logger.crash("#{@subject.class}: CLEANUP CRASHED!", ex) end # Run a method inside a task unless it's exclusive def task(task_type, method_name = nil, &block) - if @exclusives && (@exclusives == :all || @exclusives.include?(method_name.to_sym)) + if @exclusives && (@exclusives == :all || (method_name && @exclusives.include?(method_name.to_sym))) exclusive { block.call } else @task_class.new(task_type, &block).resume end end