I read in the mailing list archive that John Small proposed a solution to allow a mutex to be locked many times by the same thread. He replaced @locked = true by @locked = Thread.current and allowed new locks if @locked == Thread.current.
But there is a problem with this implementation: if a thread locks a mutex twice, you must assume it will unlock it twice. And you should not unlock it until all locks are unlocked.
In his example:
class Foo
def initialize
@mutex = Mutex.new
end
def foo
@mutex.synchronize { puts "foo" }
end
def bar
@mutex.synchronize {
foo
# Here the mutex is unlocked
}
# It should be there
end
end
I created a RMutex class that allows multiple locks by the same thread and doesn't unlock if there is any lock remaining. It saves the locker thread and counts the number of locks it did. When it reaches 0, the mutex is unlocked.
You can get it there:
http://www.lepton.fr/ruby/rmutex
Mike