From: Nasir Khan Date: 2007-06-12T03:13:39+09:00 Subject: Re: Synchronized attr_accessor ------=_Part_117016_353230.1181585614265 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline I think there's still a race condition... you need to change this: @@__ms_c_lock.synchronize { @__ms_lock = Mutex.new unless @__ms_lock } unless @__ms_lock To this: @@__ms_c_lock.synchronize { @__ms_lock = Mutex.new unless @__ms_lock unless @__ms_lock } What is the race condition you are talking about in the first snippet above? And why did you change it to have two identical unless's one after the other in the second snippet? Note the unless is checking for @__ms_lock in *both* the unless's. - Nasir On 6/10/07, Caleb Clausen wrote: > > On 6/10/07, Nasir Khan wrote: > > Thanks for the feedback. Here is a refinement - > > I think there's still a race condition... you need to change this: > > @@__ms_c_lock.synchronize { @__ms_lock = Mutex.new unless > @__ms_lock > } unless @__ms_lock > > To this: > > @@__ms_c_lock.synchronize { @__ms_lock = Mutex.new unless > @__ms_lock > unless @__ms_lock } > > Which is somewhat uglier, since now the class level mutex has to be > checked on every synchronized method call. > > Now, what I had in mind was a little more like this (INCOMPLETELY TESTED): > > module MethodSynchronizer > > def MethodSynchronizer.included(into) > into.sync_methods.each do |m| > MethodSynchronizer.wrap_method(into, m) > end > end > > def MethodSynchronizer.wrap_method(klass, meth) > klass.class_eval do > alias_method "__nonsync_#{meth}", "#{meth}" > require 'thread' > define_method(:initialize_synchronizer) do > @__ms_lock=Mutex.new > return self > end > define_method(meth) do |*args| > @__ms_lock.synchronize do > self.send("__nonsync_#{meth}",*args) > end > end > end > end > end > > > And now you have to make sure that #initialize_synchronizer is called > on the object before any of the synchronized methods. > > (What I really was thinking of was hacking into the regular > #initialize to get it to do the extra initialization automatically... > That can be hairy; among other things, you have to get it into the > #initialize of the class being mixed-in to, rather than the module's > #initialize. It's not impossible, but it requires more code than I > want to write right now.) > > ------=_Part_117016_353230.1181585614265--