From: Tomoyuki Chikanaga Date: 2011-12-14T09:45:21+09:00 Subject: [ruby-dev:44992] [ruby-trunk - Bug #5757] main threadがreadやselectで待っていると、^C でなかなか死なない Issue #5757 has been updated by Tomoyuki Chikanaga. Bug #5343 を登録したものです。 ちゃんと試さずに書いてしまいますが、 #5343 は別の Thread からの kill や raise での割り込みの場合の問題だったと記憶していますので、ubf_select() での rb_thread_wakeup_timer_thread() の呼び出しはタイマースレッドで実行する場合は呼ばないようにすることで両方大丈夫にならないでしょうか。 diff --git a/thread_pthread.c b/thread_pthread.c index afef326..16f7674 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -924,6 +924,8 @@ native_sleep(rb_thread_t *th, struct timeval *timeout_tv) thread_debug("native_sleep done\n"); } +static pthread_t timer_thread_id; + #ifdef USE_SIGNAL_THREAD_LIST struct signal_thread_list { rb_thread_t *th; @@ -1018,7 +1020,8 @@ ubf_select(void *ptr) { rb_thread_t *th = (rb_thread_t *)ptr; add_signal_thread_list(th); - rb_thread_wakeup_timer_thread(); /* activate timer thread */ + if ( pthread_self() != timer_thread_id ) + rb_thread_wakeup_timer_thread(); /* activate timer thread */ ubf_select_each(th); } @@ -1047,7 +1050,6 @@ ping_signal_thread_list(void) { static int ping_signal_thread_list(void) { return 0; } #endif /* USE_SIGNAL_THREAD_LIST */ -static pthread_t timer_thread_id; static int timer_thread_pipe[2] = {-1, -1}; static int timer_thread_pipe_owner_process; ---------------------------------------- Bug #5757: main threadがreadやselectで待っていると、^C でなかなか死なない http://redmine.ruby-lang.org/issues/5757 Author: Yui NARUSE Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: ruby 2.0.0dev (2011-12-12 trunk 34015) [x86_64-freebsd9.0] FreeBSD 9 にて、 ./ruby と起動して ^C を投げてもなかなか死にません。 ./miniruby でも -e'$stdin.read' でも同じです。 仕組みとしては、main thread が read や select で待つ場合、最近は blocking region で unblock.func に ubf_select を設定するわけですが、この時にシグナルが来ると、 1. どこかのスレッドの sighandler が呼ばれて、rb_thread_wakeup_timer_thread() が呼ばれる 2. タイマースレッドが起きて、thread_timer() -> timer_thread_function() -> rb_threadptr_check_signal() -> rb_threadptr_interrupt() -> (th->unblock.func)(th->unblock.arg) -> ubf_select() -> rb_thread_wakeup_timer_thread() が呼ばれる 3. タイマースレッドが起きて、thread_timer() -> timer_thread_function() -> rb_threadptr_check_signal() -> rb_threadptr_interrupt() -> (th->unblock.func)(th->unblock.arg) -> ubf_select() -> rb_thread_wakeup_timer_thread() が呼ばれる 4. タイマースレッドが起きて、thread_timer() -> timer_thread_function() -> rb_threadptr_check_signal() -> rb_threadptr_interrupt() -> (th->unblock.func)(th->unblock.arg) -> ubf_select() -> rb_thread_wakeup_timer_thread() が呼ばれる ... 対策はいくつかあり得ると思うのですが、例えば、ubf_select() から rb_thread_wakeup_timer_thread() を呼ばないようにするとか -- http://redmine.ruby-lang.org