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

Issue #5355 has been reported by Masaki M…


Bug #5355: Sync_mにBug #5195やBug #5258と同様のバグ

Author: Masaki M.
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されます。

また、 Bug #5258: SizedQueueにBug #5195と同様のバグ - Ruby master - Ruby Issue Tracking System
と同様の問題ですが、ロックの開放待ちで寝ているスレッドに例外を発生させると、
@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

Issue #5355 has been updated by Masaki M…

=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と同様のバグ

Author: Masaki M.
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されます。

また、 Bug #5258: SizedQueueにBug #5195と同様のバグ - Ruby master - Ruby Issue Tracking System
と同様の問題ですが、ロックの開放待ちで寝ているスレッドに例外を発生させると、
@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

Issue #5355 has been updated by Masaki M…

[Bug #5350]に書くべきものを間違えてこちらに書いてしまいました。すみません。

Bug #5355: Sync_mにBug #5195やBug #5258と同様のバグ

Author: Masaki M.
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されます。

また、 Bug #5258: SizedQueueにBug #5195と同様のバグ - Ruby master - Ruby Issue Tracking System
と同様の問題ですが、ロックの開放待ちで寝ているスレッドに例外を発生させると、
@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

Issue #5355 has been updated by Motohiro KOSAKI.

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


Bug #5355: Sync_mにBug #5195やBug #5258と同様のバグ

Author: Masaki M.
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されます。

また、 Bug #5258: SizedQueueにBug #5195と同様のバグ - Ruby master - Ruby Issue Tracking System
と同様の問題ですが、ロックの開放待ちで寝ているスレッドに例外を発生させると、
@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

Issue #5355 has been updated by Ayumu AIZAWA.

Assignee set to Motohiro KOSAKI

#5258 とおなじく小崎さんにAssignしますよ

Bug #5355: Sync_mにBug #5195やBug #5258と同様のバグ

Author: Masaki M.
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されます。

また、 Bug #5258: SizedQueueにBug #5195と同様のバグ - Ruby master - Ruby Issue Tracking System
と同様の問題ですが、ロックの開放待ちで寝ているスレッドに例外を発生させると、
@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

Issue #5355 has been updated by kosaki (Motohiro KOSAKI).

これも #5195と同じく timeout moduleが予期せぬタイミングでexception投げるケースを考えると
ensure節を1つ足しただけではなにも解決してないのですが、悪化することはないので入れます

Bug #5355: Sync_mにBug #5195やBug #5258と同様のバグ

Author: Glass_saga (Masaki M.)
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されます。

また、 Bug #5258: SizedQueueにBug #5195と同様のバグ - Ruby master - Ruby Issue Tracking System
と同様の問題ですが、ロックの開放待ちで寝ているスレッドに例外を発生させると、
@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