From: SASADA Koichi Date: 2011-07-01T06:14:15+09:00 Subject: [ruby-dev:44009] Re: [Ruby 1.9 - Bug #4950] ほぼ同時に異なる種類のシグナルを受信すると片方のシグナルハンドラが実行されない  ささだです.  ちょうど小崎さんに同じ問題を指摘されて,しかも解決策も提示して頂いたの で,パッチを作っていました.これで動きます(デバッグプリント込み). http://www.atdot.net/sp/view/w8gmnl/readonly ただ,make test で,copy_stream のテストが刺さる,という問題が解決できず にいます. at_exit { p :foo } megacontent = "abc" * 12345678 #File.open("megasrc", "w") {|f| f << megacontent } Thread.new { sleep p(rand*0.2); Process.kill(:INT, $$) } r1, w1 = IO.pipe r2, w2 = IO.pipe t1 = Thread.new { w1 << megacontent; w1.close } t2 = Thread.new { r2.read; r2.close } IO.copy_stream(r1, w2) rescue nil w2.close r1.close t1.join t2.join うーん,なぜだろう.rb_interrupt() までは呼ばれているようなのですが. (2011/07/01 0:18), Tomoyuki Chikanaga wrote: > > Issue #4950 has been updated by Tomoyuki Chikanaga. > > > シグナルがメインスレッドで処理されるまで配送を遅延しているので、タイマースレッドが polling をやめてしまうと配送が滞留するという問題みたいでした。 > 以下のように polling する条件に追加すると期待したような動作になりました。どうでしょうか。 > > diff --git a/thread_pthread.c b/thread_pthread.c > index 4f66c4e..016c3e9 100644 > --- a/thread_pthread.c > +++ b/thread_pthread.c > @@ -1085,7 +1085,7 @@ thread_timer(void *p) > FD_ZERO(&rfds); > FD_SET(timer_thread_pipe[0], &rfds); > > - if (gvl->waiting > 0 || need_polling) { > + if (gvl->waiting > 0 || need_polling || rb_signal_buff_size() > 0) { > timeout.tv_sec = 0; > timeout.tv_usec = TIME_QUANTUM_USEC; > > > ---------------------------------------- > Bug #4950: ほぼ同時に異なる種類のシグナルを受信すると片方のシグナルハンドラが実行されない > http://redmine.ruby-lang.org/issues/4950 > > Author: Tomoyuki Chikanaga > Status: Open > Priority: Normal > Assignee: > Category: core > Target version: 1.9.3 > ruby -v: ruby 1.9.3dev (2011-06-30 trunk 32335) [x86_64-darwin10.8.0] > > > 以下のようなスクリプトを実行すると [1,2] か [2,1] が表示されることが期待されますが、 > 実際には [1] が表示されます(稀に [2] になることもあります)。 > > a = [] > trap(:INT) { a.push(1) } > trap(:TERM) { a.push(2) } > > pid = $$ > fork do > sleep 0.5 > puts "send start" > Process.kill(:INT, pid) > Process.kill(:TERM, pid) > puts "send end" > end > > puts "sleep start" > sleep 3 > puts "sleep end" > p a > > Signal.trap のブロック内で puts してみると、一方のシグナルハンドラが終了時に遅れて実行されているようです。 > > -- // SASADA Koichi at atdot dot net