Revision: 3466 http://trac.macosforge.org/projects/ruby/changeset/3466 Author: ernest.prabhakar@gmail.com Date: 2010-02-09 15:24:24 -0800 (Tue, 09 Feb 2010) Log Message: ----------- Redo Dispatch::Future to duck-type Thread, first cut Modified Paths: -------------- MacRuby/trunk/lib/dispatch/dispatch.rb MacRuby/trunk/lib/dispatch/future.rb Modified: MacRuby/trunk/lib/dispatch/dispatch.rb =================================================================== --- MacRuby/trunk/lib/dispatch/dispatch.rb 2010-02-09 23:24:14 UTC (rev 3465) +++ MacRuby/trunk/lib/dispatch/dispatch.rb 2010-02-09 23:24:24 UTC (rev 3466) @@ -41,31 +41,13 @@ Dispatch::Actor.new( (obj.is_a? Class) ? obj.new : obj) end - # Run the +&block+ asynchronously on a concurrent queue - # of the given (optional) +priority+ - # as part of a newly-created group, which is returned for use with - # +Dispatch.group+ or +wait+ / +notify+ + # Run the +&block+ asynchronously on a concurrent queue of the given + # (optional) +priority+ as part of a Future, which is returned for use with + # +join+ or +value+ def fork(priority=nil, &block) - grp = Group.new - Dispatch.group(grp, priority) { block.call } - # Can't pass block directly for some reason - return grp + Dispatch::Future.new(priority) &block end - - class Group - # Companion to +Dispatch.fork+, allowing you to +wait+ until +grp+ completes - # via an API similar to that used by +Threads+ - # If a block is given, instead uses +notify+ to call it asynchronously - def join(q = nil, &block) - if block.nil? - self.wait - else - q ||= Dispatch::Queue.concurrent - self.notify(q, &block) - end - end - end module_function :label_for, :queue_for, :async, :sync, :group, :wrap, :fork Modified: MacRuby/trunk/lib/dispatch/future.rb =================================================================== --- MacRuby/trunk/lib/dispatch/future.rb 2010-02-09 23:24:14 UTC (rev 3465) +++ MacRuby/trunk/lib/dispatch/future.rb 2010-02-09 23:24:24 UTC (rev 3466) @@ -1,34 +1,33 @@ # Calculate the value of an object in the background module Dispatch - # Wrapper around Dispatch::Group used to implement lazy Futures - class Future + # Subclass of Dispatch::Group used to implement lazy Futures + # By returning a value and duck-typing Thread +join+ and +value+ + + class Future < Group # Create a future that asynchronously dispatches the block # to a concurrent queue of the specified (optional) +priority+ def initialize(priority=nil, &block) + super @value = nil - @group = Dispatch.fork(priority) { @value = block.call } + Dispatch.group(self, priority) { @value = block.call } end - # Waits for the computation to finish, then returns the value - # Duck-typed to lambda.call(void) + # Waits for the computation to finish + alias :wait, :join + + # Joins, then returns the value # If a block is passed, invoke that asynchronously with the final value - def call(q = nil, &callback) + # on the specified +queue+ (or else the default queue). + def value(queue = nil, &callback) if not block_given? - @group.wait + wait return @value else - q ||= Dispatch::Queue.concurrent - @group.notify(q) { callback.call(@value) } + queue ||= Dispatch::Queue.concurrent + notify(queue) { callback.call(@value) } end end end - - # Create a +Future+ that runs the block in the background - def future(priority=nil, &block) - Future.new(priority, &block) - end - - module_function :future - + end