[ruby-dev:46126] [ruby-trunk - Bug #5355] Sync_mにBug #5195やBug #5258と同様のバグ

From: "kosaki (Motohiro KOSAKI)" <kosaki.motohiro@...>
Date: 2012-09-09 11:51:01 UTC
List: ruby-dev #46126
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

上記のコードを実行すると

 [#<Thread:0x00000001936858 sleep>]
 [#<Thread:0x00000001936858 sleep>, #<Thread:0x00000001936858 sleep>]
 
このように、起こされた際に@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

このような結果となります。

 [[#<Thread:0x000000015e04d8 sleep>, 1]]
 []
 [[#<Thread:0x000000015e04d8 sleep>, 1]]
 [#<Thread:0x000000015e04d8 sleep>]
 
複数のスレッドが共有ロックを保持している時にあるスレッドが共有ロックから排他ロックへ昇格しようとした場合、
共有ロックの開放を待つスレッドは@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
 
実行結果:

 [#<Thread:0x00000000e498f0 sleep>]
 [#<Thread:0x00000000e498f0 dead>]

以上の問題を解決するpatchを添付します。

=end


-- 
http://bugs.ruby-lang.org/

In This Thread

Prev Next