From: Brian Schroeder Date: 2004-07-26T06:06:53+09:00 Subject: Mutex question / request Hello, playing around with threads I observed, that it is impossible to lock a mutex twice from within the same thread. Coming from a delphi background I'm used to have the possibility to enter a critical section as often as I like, as long as I'm in the same thread. That allows for some simpler programming, as I can for example allow the user to read from a protected accessor while he has aquired the lock for some bigger operation. To be more specific: The following is not working: === Test 1 === require 'thread' m = Mutex.new m.synchronize do puts 'locked level 1' m.synchronize do puts 'level 2' end end === EOF === I'd like to use it for this usecase: === usecase === class A def initialize @lock = Mutex.new end def x result = '' @lock.synchronize do # Do something with result end result end def synchronize @lock.synchronize do yield end end end a = A.new a.synchronize do # Do something with a puts a.x # Do some more with a end === EOF === I looked into the thread library and came up with some changes that should implement the behaviour I want. But my knowledge of ruby threads is quite limited, so I'd like your feedback on how good this is. Also I'm interested if you think that this is a good idea, and if it should be proposed for inclusion in the standard library? === MultiMutex === class MultiMutex < Mutex def initialize @lockingthread = nil @lockdepth = 0 super end def lock Thread.critical = true begin if @lockingthread = Thread.current then @lockdepth += 1 else while (Thread.critical = true; @lockdepth > 0) @waiting.push Thread.current Thread.stop end @lockdepth = 1 end ensure Thread.critical = false end self end def unlock return @lockdepth unless @locked Thread.critical = true begin if @lockdepth > 1 then @lockdepth -= 1 return @lockdepth else @lockingthread = nil @lockdepth = 0 begin t = @waiting.shift t.wakeup if t rescue ThreadError retry end end ensure Thread.critical = false end begin t.run if t rescue ThreadError end @lockdepth end end === EOF === -- Brian Schr�der http://www.brian-schroeder.de/