Hi everyone,
After the recent discussion about gcd and thread safety I took a look at the 
Dispatch gem (proxy object in particular). I though I'd try and improve 
efficiency, as all method calls are currently directed through method_missing 
to the delegate object. 

One attempt I made was to dynamically define methods in method_missing so that 
subsequent calls would be more efficient. I realised the naivety of this 
approach when one queue was busily defining the method whilst other queues were 
calling method_missing - much pain ensued.

The next approach might be more promising: remove method_missing and instead 
define all methods of the delegate object in initialize. It appears to work 
most of the time, but unfortunately crashes are not infrequent. Is there 
anything obviously wrong about the initialize method below? 

Cheers,

Alan

------

require 'delegate'

module Dispatch

  class Proxy < SimpleDelegator

    attr_accessor :__group__, :__queue__, :__sync__

    def initialize(delegate, group=Group.new, queue=Dispatch::Queue.concurrent)
      super(delegate)
      @__serial__ = Dispatch::Queue.for(self)
      @__group__ = group
      @__queue__ = queue
      @__retval__ = nil

      delegate.public_methods.each do |meth|
        (class << self; self; end).class_eval do
          define_method meth do |*args, &block|
            if block.nil? then
              @__serial__.sync { @__retval__ = __getobj__.__send__(meth, *args) 
}
              return @__retval__
            end
            queue = @__queue__ # copy in case it changes while in flight
            @__serial__.async(@__group__) do
              retval = __getobj__.__send__(meth, *args)
              queue.async(@__group__) { block.call(retval) }
            end
          end
        end
      end

    end

end
_______________________________________________
MacRuby-devel mailing list
MacRuby-devel@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Reply via email to