Project

General

Profile

Actions

Bug #5355

closed

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

Added by Glass_saga (Masaki Matsushita) about 13 years ago. Updated about 12 years ago.

Status:
Closed
Target version:
ruby -v:
ruby 1.9.4dev (2011-09-20 trunk 33301) [x86_64-linux]
Backport:
[ruby-dev:44521]

Description

=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


Files

patch.diff (1.16 KB) patch.diff Glass_saga (Masaki Matsushita), 09/23/2011 11:53 AM

Related issues 3 (0 open3 closed)

Related to Ruby master - Bug #5195: Queue#popでsleepしているthreadをwakeupさせるとQueueの@waitingにそのthreadがpushされてしまうClosedkosaki (Motohiro KOSAKI)08/16/2011Actions
Related to Ruby master - Bug #5258: SizedQueueにBug #5195と同様のバグClosedkosaki (Motohiro KOSAKI)09/01/2011Actions
Has duplicate Ruby master - Bug #6911: Sync_m#sync_unlock で ThreadError が発生する場合があるClosed08/23/2012Actions

Updated by ayumin (Ayumu AIZAWA) almost 13 years ago

  • Assignee set to kosaki (Motohiro KOSAKI)

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

Updated by kosaki (Motohiro KOSAKI) almost 13 years ago

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

Actions #3

Updated by shyouhei (Shyouhei Urabe) over 12 years ago

  • Status changed from Open to Assigned
Actions #4

Updated by kosaki (Motohiro KOSAKI) about 12 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r36936.
Masaki, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • lib/sync.rb (Sync_m#sync_lock): Fixed wakeup/raise unsafe code.
    Patched by Masaki Matsushita. [Bug #5355] [ruby-dev:44521]

  • test/thread/test_sync.rb (test_sync_lock_and_wakeup,
    test_sync_upgrade_and_wakeup, test_sync_lock_and_raise):
    new test.

Updated by kosaki (Motohiro KOSAKI) about 12 years ago

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

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0