Forum: Ruby-dev [Ruby 1.9 - Bug #5355][Open] Sync mにBug #5195やBug #5258と同様のバグ

Posted by Masaki Matsushita (Guest)
on 2011-09-23 04:54
(Received via mailing list)
Issue #5355 has been reported by Masaki Matsushita.

----------------------------------------
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

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

 [#<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
Posted by Masaki Matsushita (Guest)
on 2011-09-23 13:16
(Received via mailing list)
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

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

 [#<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
Posted by Masaki Matsushita (Guest)
on 2011-09-23 13:25
(Received via mailing list)
Issue #5355 has been updated by Masaki Matsushita.


[Bug #5350]に書くべきものを間違えてこちらに書いてしまいました。すみません。
----------------------------------------
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

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

 [#<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
Posted by Ayumu AIZAWA (Guest)
on 2011-12-30 09:13
(Received via mailing list)
Issue #5355 has been updated by Ayumu AIZAWA.

Assignee set to Motohiro KOSAKI

#5258 とおなじく小崎さんにAssignしますよ
----------------------------------------
Bug #5355: Sync_mにBug #5195やBug #5258と同様のバグ
https://bugs.ruby-lang.org/issues/5355

Author: Masaki Matsushita
Status: Open
Priority: Normal
Assignee: 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
Posted by Motohiro KOSAKI (Guest)
on 2011-12-30 09:18
(Received via mailing list)
Issue #5355 has been updated by Motohiro KOSAKI.


スレッドまわりは振ってくれていいですよ。ほかに誰も見てくれなさそうだし。ただあからさまに優先度低そうなやつは暇なときかリリース近いときしか作業できませぬ

----------------------------------------
Bug #5355: Sync_mにBug #5195やBug #5258と同様のバグ
https://bugs.ruby-lang.org/issues/5355

Author: Masaki Matsushita
Status: Open
Priority: Normal
Assignee: 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
Posted by kosaki (Motohiro KOSAKI) (Guest)
on 2012-09-09 13:51
(Received via mailing list)
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
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.