From: Masaki Matsushita Date: 2011-09-23T20:16:00+09:00 Subject: [ruby-dev:44522] [Ruby 1.9 - Bug #5355] Sync_mにBug #5195やBug #5258と同様のバグ Issue #5355 has been updated by Masaki Matsushita. =begin もう少しシンプルなコードにしてみました。 大量のWeakRefオブジェクトを生成すると、たまに正しく参照できない事があるようです。 require "weakref" class Foo def hoge; end end TIMES = 100000 A = [] TIMES.times do A.push WeakRef.new Foo.new end A.each do |x| begin x.hoge rescue WeakRef::RefError end end 正しく参照できなかった場合には、参照先のobject_idに20を足したFixnumが格納されたArrayや、caller、callerの一部と思われるStringなどが返ります。 =end ---------------------------------------- Bug #5355: Sync_mにBug #5195やBug #5258と同様のバグ http://redmine.ruby-lang.org/issues/5355 Author: Masaki Matsushita Status: Open Priority: Normal Assignee: Category: lib Target version: 1.9.x 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://redmine.ruby-lang.org