From: "kosaki (Motohiro KOSAKI)" Date: 2012-09-09T20:51:01+09:00 Subject: [ruby-dev:46126] [ruby-trunk - Bug #5355] Sync_mにBug #5195やBug #5258と同様のバグ Issue #5355 has been updated by kosaki (Motohiro KOSAKI). これも #5195と同じく timeout moduleが予期せぬタイミングでexception投げるケースを考えると ensure節を1つ足しただけではなにも解決してないのですが、悪化することはないので入れます ---------------------------------------- Bug #5355: Sync_mにBug #5195やBug #5258と同様のバグ https://bugs.ruby-lang.org/issues/5355#change-29228 Author: Glass_saga (Masaki Matsushita) Status: Closed Priority: Normal Assignee: kosaki (Motohiro KOSAKI) Category: lib Target version: 2.0.0 ruby -v: ruby 1.9.4dev (2011-09-20 trunk 33301) [x86_64-linux] =begin Sync_mにもBug #5195やBug #5258と同様のバグがあります。 require 'sync' class Foo; include Sync_m; end foo = Foo.new foo.sync_lock(:EX) t = Thread.new { foo.sync_lock(:EX) } nil until t.stop? p foo.sync_waiting t.wakeup nil until t.stop? p foo.sync_waiting 上記のコードを実行すると [#] [#, #] このように、起こされた際に@sync_waitingに再度Thread.currentをpushしてしまいます。 また、次のコードを実行すると、 require 'sync' class Foo; include Sync_m; end foo = Foo.new foo.sync_lock(:SH) t = Thread.start do foo.sync_lock(:SH) foo.sync_lock(:EX) end nil until t.stop? p foo.sync_upgrade_waiting p foo.sync_waiting t.wakeup nil until t.stop? p foo.sync_upgrade_waiting p foo.sync_waiting このような結果となります。 [[#, 1]] [] [[#, 1]] [#] 複数のスレッドが共有ロックを保持している時にあるスレッドが共有ロックから排他ロックへ昇格しようとした場合、 共有ロックの開放を待つスレッドは@sync_upgrade_waitingにpushされますが、この状態からそのスレッドを起こすと、 @sync_upgrade_waitingではなく@sync_waitingにThread.currentがpushされます。 また、 http://redmine.ruby-lang.org/issues/5258#note-2 と同様の問題ですが、ロックの開放待ちで寝ているスレッドに例外を発生させると、 @waitingにpushされたスレッドはそのまま放置されてしまいます。 require 'sync' class Foo; include Sync_m; end foo = Foo.new foo.sync_lock(:EX) t = Thread.new { foo.sync_lock(:EX) } nil until t.stop? p foo.sync_waiting t.raise nil while t.alive? p foo.sync_waiting 実行結果: [#] [#] 以上の問題を解決するpatchを添付します。 =end -- http://bugs.ruby-lang.org/