Note: The code summary shown below is not a distillation of the code that I had the problem with. I\'ve left this original summary here since someo
Does it happen with a class variable? @@mutex. There might be a race condition with making new class-instances between threads and the new copy of @mutex isn't ready yet. Constants and class variables however, are shared between copies of the class and subclasses. Also, what if you put the @mutex init code in a memoized method such as:
def self.mutex
@mutex ||= Mutex.new
end
While autoloading is indeed not thread safe in Rails like it is in Ruby 1.9 (per Is autoload thread-safe in Ruby 1.9?), the problem I encountered was not due to that problem and the code I had was not an instance of the code I showed above, but rather an instance of the following:
class Foo
@mutex = Mutex.new
def self.bar
@mutex.synchronize { }
end
end
class Foobar < Foo ; end
Foobar.bar
The problem is that when executing method from a superclass, the value of self remains unchanged, so the value of @mutex within Foo.bar is interpreted in the context of the Foobar object, not the value of the Foo object.
This problem can be avoided by using a class variable (e.g. @@mutex) for the mutex.