2008/2/25, Charles Oliver Nutter <charles.nutter / sun.com>: > I wrote up an article on Thread#raise, Thread#kill, and timeout.rb that > I hope can start making the rounds. Long story short, neither > Thread#raise nor Thread#kill is safe to use, and as a result all > libraries that call them are also unsafe (including timeout.rb, net/*, > and many other libraries in the wider world). > > Have a look, add comments, discuss. Hopefully we can find a way to fix > this, because it's going to hold Ruby back until we do. > > http://headius.blogspot.com/2008/02/rubys-threadraise-threadkill-timeoutrb.html There is a typo: your second example misses the "main." before the raise. :-) I have to think a bit more about this, but one remark: IMHO the locking should be outside the begin end block. Reason is, that if locking fails for a reason you would not want / need to unlock. At the moment I'm pondering implications of these options: main = Thread.current timer = Thread.new { sleep 5; main.raise } lock(some_resource) begin do_some_work ensure unlock_some_resource timer.kill # moved downwards end main = Thread.current timer = Thread.new { sleep 5; main.raise } begin lock(some_resource) begin do_some_work ensure unlock_some_resource end ensure timer.kill # separate ensure end The last one has the added benefit that you can implement it in a method with a block because timer code is not interleaved with work code. But both have the disadvantage that you risk getting a timeout exception during unlock - which would be unfortunate. OTOH, killing the timer before the lock release can violate the timing constraint if the unlocking takes longer - not very likely. Nasty issues; we had some similar issues with changed timeout handling of a TX manager in JBoss. Basically the old TX manager was able to bust an otherwise perfect transaction by timing out in the 2PC process. :-)) Kind regards robert -- use.inject do |as, often| as.you_can - without end