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
[email protected]
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel