From: Minero Aoki Date: 2005-02-24T09:15:02+09:00 Subject: [ruby-dev:25755] I/O operation differs signal handler 青木です。 以下のようなプログラムを実行して SIGTERM を送っても、 $stdin.gets が戻るまでシグナルハンドラが実行されません。 Signal.trap(:TERM) { puts 'TERM'; exit } puts $$ while true p $stdin.gets() end pure Ruby 版の FastCGI サーバでこのようなコードが必要になりました。 FastCGI サーバは常に stdin を待ち受けますが、SIGUSR1 でリジューム、 SIGTERM で exit 0 をするという規約があるので、I/O 待ちをしつつ リアルタイムでシグナルも受け付ける必要があります。 これが動作しないと事実上シグナルが効かなくなるので、例えば Apache が停止しても ruby プロセスだけが残ってしまうという問題があります。 うちのサーバでは毎日ログをローテートするたびに ruby プロセスが死に 損なっていました。 なお、上記のコードが動作しない原因は [ruby-dev:25003] で導入された signal.c:1.55 がそのままになっていることだと思います。そのあとの 展開でこのリビジョンの変更は不要になっているはずなので、巻き戻す べきではないでしょうか。 ------------------------------------------------------------------- 青木峰郎 Thu Feb 24 09:08:10 2005 Minero Aoki * signal.c: revert rev 1.55; allow pure ruby signal handler in I/O operation. Index: signal.c =================================================================== RCS file: /var/cvs/src/ruby/signal.c,v retrieving revision 1.57 diff -u -r1.57 signal.c --- signal.c 22 Feb 2005 14:50:33 -0000 1.57 +++ signal.c 24 Feb 2005 00:02:31 -0000 @@ -465,7 +465,7 @@ } #endif - if (trap_list[sig].cmd == 0 && ATOMIC_TEST(rb_trap_immediate)) { + if (ATOMIC_TEST(rb_trap_immediate)) { IN_MAIN_CONTEXT(signal_exec, sig); ATOMIC_SET(rb_trap_immediate, 1); }