Bug #7455

Queue#popで待っている間にtrapに入りその時にQueue#pushされると、Queue#popから戻ってこなくなる。

Added by Masaya Tarui over 1 year ago. Updated over 1 year ago.

[ruby-dev:46654]
Status:Closed
Priority:Normal
Assignee:Koichi Sasada
Category:core
Target version:2.0.0
ruby -v:ruby 2.0.0dev (2012-11-28 trunk 37937) [x86_64-linux] Backport:

Description

以下スクリプトを実行すると期待したように終わらずに、deadlockしてしまいます。

ささださんよろしく。

require 'thread'

que = Queue.new
th = Thread.new{
sleep 0.1
Process.kill(:INT,$$)
sleep 0.1
que.push 2
}
Signal.trap :INT do
p :traptask
123456*100000 / 456 * 10000
p :trap
task_end
end
puts "que.pop"
p que.pop
puts "success!"

Associated revisions

Revision 37944
Added by Koichi Sasada over 1 year ago

add ticket ref: [ruby-trunk - Bug #7455]

History

#1 Updated by Motohiro KOSAKI over 1 year ago

とりあえず原因を書いておくと

  1. que.popで、mutex.sleepが呼ばれ、結局sleepforever()が呼ばれる。ここで一旦 status = THREADSTOPPED_FOREVERになる
  2. Process.kill をうけて status = THREAD_RUNNABLEにしてトラップハンドラを実行はじめる
  3. que.push を呼ぶが、main threadはすでに thread runnableなので何もおこらず
  4. サブスレッド死ぬ
  5. trap抜けたところで rbthreadptrexecuteinterrupt()内の th->status = prevstatus; の処理によって、 statusがTHREADSTOPPEDFOREVERに戻る 6.sleepforever() は status != THREADRUNNABLE の場合sleepを再実行するので、ここでデッドロックチェック 唯一残っているスレッドであるメインスレッドが THREADSTOPPEDFOREVERなので、めでたくチェックにひっかかり強制終了

ささださん、よろしく

#2 Updated by Koichi Sasada over 1 year ago

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

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


add ticket ref: [ruby-trunk - Bug #7455]

Also available in: Atom PDF