[macruby-changes] [3609] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Feb 24 16:24:32 PST 2010


Revision: 3609
          http://trac.macosforge.org/projects/ruby/changeset/3609
Author:   ernest.prabhakar at gmail.com
Date:     2010-02-24 16:24:30 -0800 (Wed, 24 Feb 2010)
Log Message:
-----------
Convert on_* to Dispatch::Source from Queue

Modified Paths:
--------------
    MacRuby/trunk/lib/dispatch/README.rdoc
    MacRuby/trunk/lib/dispatch.rb

Added Paths:
-----------
    MacRuby/trunk/lib/dispatch/source.rb
    MacRuby/trunk/spec/macruby/library/dispatch/source_spec.rb

Removed Paths:
-------------
    MacRuby/trunk/lib/dispatch/queue_source.rb
    MacRuby/trunk/spec/macruby/library/dispatch/queue_source_spec.rb

Modified: MacRuby/trunk/lib/dispatch/README.rdoc
===================================================================
--- MacRuby/trunk/lib/dispatch/README.rdoc	2010-02-24 23:58:23 UTC (rev 3608)
+++ MacRuby/trunk/lib/dispatch/README.rdoc	2010-02-25 00:24:30 UTC (rev 3609)
@@ -8,7 +8,7 @@
 	
 GCD is a revolutionary approach to multicore computing that is woven throughout the fabric of {Mac OS X}[http://www.apple.com/macosx/] version 10.6 Snow Leopard. GCD combines an easy-to-use programming model with highly-efficient system services to radically simplify the code needed to make best use of multiple processors. The technologies in GCD improve the performance, efficiency, and responsiveness of Snow Leopard out of the box, and will deliver even greater benefits as more developers adopt them.
 
-The central insight of GCD is shifting the responsibility for managing threads and their execution from applications to the operating system. As a result, programmers can write less code to deal with concurrent operations in their applications, and the system can perform more efficiently on single-processor machines, large multiprocessor servers, and everything in between. Without a pervasive approach such as GCD, even the best-written application cannot deliver optimal performance, because it doesn’t have full insight into everything else happening in the system. 
+The central insight of GCD is shifting the responsibility for managing threads and their execution from applications to the operating system. As a result, programmers can write less code to deal with concurrent operations in their applications, and the system can perform more efficiently on single-processor machines, large multiprocessor servers, and everything in between. Without a pervasive approach such as GCD, even the best-written application cannot deliver optimal performance, because it doesn't have full insight into everything else happening in the system. 
 
 === The MacRuby Dispatch module
 
@@ -56,7 +56,7 @@
 
 === Job#join: Job Completion
 
-If you just want to track completion, you can call +join[http://ruby-doc.org/core/classes/Thread.html#M000462]+, which waits without returning (or removing) the result:
+If you just want to track completion, you can call +join[http://ruby-doc.org/core/classes/Thread.html#M000462]+, which waits without returning the result:
 
 	job.join
 	puts "All Done"
@@ -79,7 +79,7 @@
 
 Note that values may be received out of order, since they may take differing amounts of time to complete. If you need to force a particular ordering, create a new +Job+ or call +join+ before submitting the block.
 
-Additionally,  you can call +values+ to obtain all the values:
+Additionally, you can call +values+ to obtain all the values:
 
 	@values = job.values 
 	puts @values # => [1.0E50, 4294967296.0]
@@ -164,7 +164,6 @@
 	job.join
 	p n # => 0 
 
-
 == Iterators
 
 Jobs are useful when you want to run a single item in the background or to run many different operations at once. But if you want to run the _same_ operation multiple times, you can take advantage of specialized GCD iterators.  The Dispatch module defines "p_" variants of common Ruby iterators, making it trivial to parellelize existing operations.  

Deleted: MacRuby/trunk/lib/dispatch/queue_source.rb
===================================================================
--- MacRuby/trunk/lib/dispatch/queue_source.rb	2010-02-24 23:58:23 UTC (rev 3608)
+++ MacRuby/trunk/lib/dispatch/queue_source.rb	2010-02-25 00:24:30 UTC (rev 3609)
@@ -1,81 +0,0 @@
-# Adds convenience methods to Queues for creating Sources
-
-module Dispatch
-  class Source
-    @@proc_events = {
-       exit:PROC_EXIT,
-       fork:PROC_FORK,
-       exec:PROC_EXEC,
-       signal:PROC_SIGNAL
-       }
-    def self.proc_event(e)
-      convert_event(e, @@proc_events)
-    end
-
-    @@vnode_events = {
-      delete:VNODE_DELETE,
-      write:VNODE_WRITE, 
-      extend:VNODE_EXTEND, 
-      attrib:VNODE_ATTRIB, 
-      link:VNODE_LINK, 
-      rename:VNODE_RENAME, 
-      revoke:VNODE_REVOKE
-      }
-    def self.vnode_event(e)
-      convert_event(e, @@vnode_events)
-    end
-    
-    def self.convert_event(e, hash)
-      return e.to_i if e.is_a? Numeric
-      value = hash[e]
-      raise ArgumentError, "No event type #{e}" if value.nil?
-      value
-    end
-  end
-  
-  class Queue
-    # Returns a Dispatch::Source::DATA_ADD
-    def on_add(&block)
-      Dispatch::Source.new(Dispatch::Source::DATA_ADD, 0, 0, self, &block)
-    end
-
-    # Returns a Dispatch::Source::DATA_OR
-    def on_or(&block)
-      Dispatch::Source.new(Dispatch::Source::DATA_OR, 0, 0, self, &block)
-    end
-
-    # Takes event symbols: :delete, :write, :extend, :attrib, :link, :rename, :revoke
-    # Returns a Dispatch::Source::PROC
-    def on_process_event(pid, *events, &block)
-      mask = events.collect {|e| Dispatch::Source::proc_event(e)}.reduce(:|)
-      Dispatch::Source.new(Dispatch::Source::PROC, pid, mask, self, &block)
-    end
-
-    # Returns a Dispatch::Source::SIGNAL
-    def on_signal(signal, &block)
-      signal = Signal.list[signal.to_s] if signal.to_i == 0
-      Dispatch::Source.new(Dispatch::Source::SIGNAL, signal, 0, self, &block)
-    end
-
-    # Returns a Dispatch::Source::READ
-    def on_read(file, &block)
-      Dispatch::Source.new(Dispatch::Source::READ, file, 0, self, &block)
-    end
-
-    # Returns a Dispatch::Source::WRITE
-    def on_write(file, &block)
-      Dispatch::Source.new(Dispatch::Source::WRITE, file, 0, self, &block)
-    end
-
-    # Takes event symbols: :exit, :fork, :exec, :signal
-    # Returns a Dispatch::Source::VNODE
-    def on_file_event(file, *events, &block)
-      mask = events.collect {|e| Dispatch::Source::vnode_event(e)}.reduce(:|)
-      Dispatch::Source.new(Dispatch::Source::VNODE, file,mask, self,&block)
-    end
-
-    def on_interval(sec, &block)
-      Dispatch::Source.timer(0, sec, 0, self, &block)
-    end
-  end
-end

Added: MacRuby/trunk/lib/dispatch/source.rb
===================================================================
--- MacRuby/trunk/lib/dispatch/source.rb	                        (rev 0)
+++ MacRuby/trunk/lib/dispatch/source.rb	2010-02-25 00:24:30 UTC (rev 3609)
@@ -0,0 +1,90 @@
+# Adds convenience methods to Queues for creating Sources
+
+module Dispatch
+  class Source
+    
+    @@proc_events = {
+       exit:PROC_EXIT,
+       fork:PROC_FORK,
+       exec:PROC_EXEC,
+       signal:PROC_SIGNAL
+       }
+
+    @@vnode_events = {
+      delete:VNODE_DELETE,
+      write:VNODE_WRITE, 
+      extend:VNODE_EXTEND, 
+      attrib:VNODE_ATTRIB, 
+      link:VNODE_LINK, 
+      rename:VNODE_RENAME, 
+      revoke:VNODE_REVOKE
+      }
+      
+    class << self
+      
+      def proc_event(e)
+        convert_event(e, @@proc_events)
+      end
+
+      def vnode_event(e)
+        convert_event(e, @@vnode_events)
+      end
+    
+      def events2mask(events, hash)
+        mask = events.collect { |e| convert_event(e, hash) }.reduce(:|)
+      end
+      
+      def convert_event(e, hash)
+        return e.to_i if e.is_a? Numeric
+        value = hash[e.to_sym]
+        raise ArgumentError, "No event type #{e.inspect}" if value.nil?
+        value
+      end
+    
+
+      # Returns a Dispatch::Source::DATA_ADD
+      def on_add(queue = Dispatch::Queue.concurrent, &block)
+        Dispatch::Source.new(Dispatch::Source::DATA_ADD, 0, 0, queue, &block)
+      end
+
+      # Returns a Dispatch::Source::DATA_OR
+      def on_or(queue = Dispatch::Queue.concurrent, &block)
+        Dispatch::Source.new(Dispatch::Source::DATA_OR, 0, 0, queue, &block)
+      end
+
+      # Takes events: :delete, :write, :extend, :attrib, :link, :rename, :revoke
+      # Returns a Dispatch::Source::PROC
+      def on_process_event(pid, events, queue = Dispatch::Queue.concurrent, &block)
+        mask = events2mask(events, @@proc_events)
+        Dispatch::Source.new(Dispatch::Source::PROC, pid, mask, queue, &block)
+      end
+
+      # Returns a Dispatch::Source::SIGNAL
+      def on_signal(signal, queue = Dispatch::Queue.concurrent, &block)
+        signal = Signal.list[signal.to_s] if signal.to_i == 0
+        Dispatch::Source.new(Dispatch::Source::SIGNAL, signal, 0, queue, &block)
+      end
+
+      # Returns a Dispatch::Source::READ
+      def on_read(file, queue = Dispatch::Queue.concurrent, &block)
+        Dispatch::Source.new(Dispatch::Source::READ, file, 0, queue, &block)
+      end
+
+      # Returns a Dispatch::Source::WRITE
+      def on_write(file, queue = Dispatch::Queue.concurrent, &block)
+        Dispatch::Source.new(Dispatch::Source::WRITE, file, 0, queue, &block)
+      end
+
+      # Takes events: :exit, :fork, :exec, :signal
+      # Returns a Dispatch::Source::VNODE
+      def on_file_event(file, events, queue = Dispatch::Queue.concurrent, &block)
+        mask = events2mask(events, @@vnode_events)
+        Dispatch::Source.new(Dispatch::Source::VNODE, file, mask, queue, &block)
+      end
+
+      def on_interval(seconds, queue = Dispatch::Queue.concurrent, &block)
+        Dispatch::Source.timer(0, seconds, 0, queue, &block)
+      end
+    end
+  end
+end

Modified: MacRuby/trunk/lib/dispatch.rb
===================================================================
--- MacRuby/trunk/lib/dispatch.rb	2010-02-24 23:58:23 UTC (rev 3608)
+++ MacRuby/trunk/lib/dispatch.rb	2010-02-25 00:24:30 UTC (rev 3609)
@@ -12,7 +12,7 @@
 # This library provides higher-level services and convenience methods
 # to make it easier for traditional Ruby programmers to add multicore support.
 
-require 'dispatch/queue_source'
+require 'dispatch/source'
 require 'dispatch/queue'
 require 'dispatch/proxy'
 require 'dispatch/job'

Deleted: MacRuby/trunk/spec/macruby/library/dispatch/queue_source_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/library/dispatch/queue_source_spec.rb	2010-02-24 23:58:23 UTC (rev 3608)
+++ MacRuby/trunk/spec/macruby/library/dispatch/queue_source_spec.rb	2010-02-25 00:24:30 UTC (rev 3609)
@@ -1,146 +0,0 @@
-require File.dirname(__FILE__) + "/../../spec_helper"
-require 'dispatch'
-
-if MACOSX_VERSION >= 10.6
-
-  describe "Dispatch::Queue source from" do
-    before :each do
-      @q = Dispatch::Queue.new('org.macruby.gcd_spec.prelude')
-      @src = nil
-    end
-
-    after :each do
-      @src.cancel! if not @src.nil? and not @src.cancelled?
-      @q.sync { }
-    end
-
-    describe "on_add" do
-      it "fires with data on summed inputs" do
-        @count = 0
-        @src = @q.on_add {|s| @count += s.data}
-        @src << 20
-        @src << 22
-        @q.sync {}
-        @count.should == 42
-      end
-    end    
-
-    describe "on_or" do
-      it "fires with data on ORed inputs" do
-        @count = 0
-        @src = @q.on_or {|s| @count += s.data}
-        @src << 0b101_000
-        @src << 0b000_010
-        @q.sync {}
-        @count.should == 42
-      end
-    end    
-
-    describe "on_process_event" do
-      it "fires with data indicating which process event(s)" do
-        @signal = Signal.list["USR1"]
-        @event = nil
-        @src = @q.on_process_event($$, :exit, :fork, :exec, :signal) do 
-           |s| @event = s.data
-        end
-        Signal.trap(@signal, "IGNORE")
-        Process.kill(@signal, $$)
-        Signal.trap(@signal, "DEFAULT")
-        @q.sync {}
-        @event.should == Dispatch::Source.proc_event(:signal)
-      end
-    end
-
-    describe "on_signal" do
-      it "fires with data on how often the process was signaled" do
-        @signal = Signal.list["USR1"]
-        @count = 0
-        @src = @q.on_signal(@signal) {|s| @count += s.data}
-        Signal.trap(@signal, "IGNORE")
-        Process.kill(@signal, $$)
-        Process.kill(@signal, $$)
-        Signal.trap(@signal, "DEFAULT")
-        @q.sync {}
-        @count.should == 2
-        @src.cancel!
-      end
-    end    
-
-    describe "file" do
-      before :each do
-        @msg = "#{$$}-#{Time.now}"
-        @filename = "/var/tmp/gcd_spec_source-#{@msg}"
-        @file = nil
-        @src = nil
-      end
-
-      after :each do
-        @src.cancel! if not @src.nil? and not @src.cancelled?
-        @q.sync { }
-        @file.close if not @file.closed?
-        File.delete(@filename)
-      end
-
-      describe "on_read" do
-        it "fires with data on how many bytes can be read" do
-          File.open(@filename, "w") {|f| f.print @msg}
-          @file = File.open(@filename, "r")
-          @result = ""
-          @src = @q.on_read(@file) {|s| @result<<@file.read(s.data)}
-          while (@result.size < @msg.size) do; end
-          @q.sync { }
-          @result.should == @msg
-        end
-      end    
-
-      describe "on_write" do
-        it "fires with data on how many bytes can be written" do
-          @file = File.open(@filename, "w")
-          @pos = 0
-          @message = @msg
-          @src = @q.on_read(@file) do |s|
-            pos = s.data
-            if not @message.nil? then
-              next_msg = @message[0..pos-1]
-              @file.write(next_msg)
-              @message = @message[pos..-1]
-            end
-          end
-          while (@result.size < @msg.size) do; end
-          @q.sync { }
-          @result.should == @msg
-        end
-      end
-      
-      describe "on_file_event" do
-        it "fires with data indicating which file event(s)" do
-          @file = File.open(@filename, "w")
-          @fired = false
-          @src = @q.on_file_event(@file, :delete, :write, :extend, :attrib, :link, :rename, :revoke) do |s|
-              @flag = s.data
-              @fired = true
-          end
-          @file.write(@msg)
-          @file.flush
-          @q.sync { }
-          #while (@fired == false) do; end
-          @fired.should == true
-          @flag.should == Dispatch::Source.vnode_event(:write)
-        end
-      end          
-    end
-
-    describe "on_interval" do
-      it "fires with data on how often the timer has fired" do
-        @count = -1
-        repeats = 2
-        @interval = 0.02
-        @src = @q.on_interval(@interval) {|s| @count += s.data}
-        sleep repeats*@interval
-        @q.sync { }
-        @count.should == repeats
-      end
-    end
-  end
-  
-end

Copied: MacRuby/trunk/spec/macruby/library/dispatch/source_spec.rb (from rev 3604, MacRuby/trunk/spec/macruby/library/dispatch/queue_source_spec.rb)
===================================================================
--- MacRuby/trunk/spec/macruby/library/dispatch/source_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/macruby/library/dispatch/source_spec.rb	2010-02-25 00:24:30 UTC (rev 3609)
@@ -0,0 +1,147 @@
+require File.dirname(__FILE__) + "/../../spec_helper"
+require 'dispatch'
+
+if MACOSX_VERSION >= 10.6
+
+  describe "Dispatch::Queue source from" do
+    before :each do
+      @q = Dispatch::Queue.new('org.macruby.gcd_spec.prelude')
+      @src = nil
+    end
+
+    after :each do
+      @src.cancel! if not @src.nil? and not @src.cancelled?
+      @q.sync { }
+    end
+
+    describe "on_add" do
+      it "fires with data on summed inputs" do
+        @count = 0
+        @src = Dispatch::Source.on_add(@q) {|s| @count += s.data}
+        @src << 20
+        @src << 22
+        @q.sync {}
+        @count.should == 42
+      end
+    end    
+
+    describe "on_or" do
+      it "fires with data on ORed inputs" do
+        @count = 0
+        @src = Dispatch::Source.on_or(@q) {|s| @count += s.data}
+        @src << 0b101_000
+        @src << 0b000_010
+        @q.sync {}
+        @count.should == 42
+      end
+    end    
+
+    describe "on_process_event" do
+      it "fires with data indicating which process event(s)" do
+        @signal = Signal.list["USR1"]
+        @event = nil
+        @src = Dispatch::Source.on_process_event($$, %w(exit fork exec signal), @q) do 
+           |s| @event = s.data
+        end
+        Signal.trap(@signal, "IGNORE")
+        Process.kill(@signal, $$)
+        Signal.trap(@signal, "DEFAULT")
+        @q.sync {}
+        (@event & Dispatch::Source.proc_event(:signal)).should > 0
+      end
+    end
+
+    describe "on_signal" do
+      it "fires with data on how often the process was signaled" do
+        @signal = Signal.list["USR1"]
+        @count = 0
+        @src = Dispatch::Source.on_signal(@signal, @q) {|s| @count += s.data}
+        Signal.trap(@signal, "IGNORE")
+        Process.kill(@signal, $$)
+        Process.kill(@signal, $$)
+        Signal.trap(@signal, "DEFAULT")
+        @q.sync {}
+        @count.should == 2
+        @src.cancel!
+      end
+    end    
+
+    describe "file" do
+      before :each do
+        @msg = "#{$$}-#{Time.now}"
+        @filename = "/var/tmp/gcd_spec_source-#{@msg}"
+        @file = nil
+        @src = nil
+      end
+
+      after :each do
+        @src.cancel! if not @src.nil? and not @src.cancelled?
+        @q.sync { }
+        @file.close if not @file.closed?
+        File.delete(@filename)
+      end
+
+      describe "on_read" do
+        it "fires with data on how many bytes can be read" do
+          File.open(@filename, "w") {|f| f.print @msg}
+          @file = File.open(@filename, "r")
+          @result = ""
+          @src = Dispatch::Source.on_read(@file, @q) {|s| @result<<@file.read(s.data)}
+          while (@result.size < @msg.size) do; end
+          @q.sync { }
+          @result.should == @msg
+        end
+      end    
+
+      describe "on_write" do
+        it "fires with data on how many bytes can be written" do
+          @file = File.open(@filename, "w")
+          @pos = 0
+          @message = @msg
+          @src = Dispatch::Source.on_read(@file, @q) do |s|
+            pos = s.data
+            if not @message.nil? then
+              next_msg = @message[0..pos-1]
+              @file.write(next_msg)
+              @message = @message[pos..-1]
+            end
+          end
+          while (@result.size < @msg.size) do; end
+          @q.sync { }
+          @result.should == @msg
+        end
+      end
+      
+      describe "on_file_event" do
+        it "fires with data indicating which file event(s)" do
+          @file = File.open(@filename, "w")
+          @fired = false
+          events = %w(delete write extend attrib link rename revoke)
+          @src = Dispatch::Source.on_file_event(@file, events, @q) do |s|
+              @flag = s.data
+              @fired = true
+          end
+          @file.write(@msg)
+          @file.flush
+          @q.sync { }
+          #while (@fired == false) do; end
+          @fired.should == true
+          @flag.should == Dispatch::Source.vnode_event(:write)
+        end
+      end          
+    end
+
+    describe "on_interval" do
+      it "fires with data on how often the timer has fired" do
+        @count = -1
+        repeats = 2
+        @interval = 0.02
+        @src = Dispatch::Source.on_interval(@interval, @q) {|s| @count += s.data}
+        sleep repeats*@interval
+        @q.sync { }
+        @count.should == repeats
+      end
+    end
+  end
+  
+end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100224/0ee180da/attachment-0001.html>


More information about the macruby-changes mailing list