From 4af243a8afa0dfefc74bb68dd08d9c5ff3ccc5d5 Mon Sep 17 00:00:00 2001 From: mame Date: Tue, 27 Apr 2010 12:27:13 +0000 Subject: * eval.c (ruby_cleanup): before cleanup, check signal buffer and run handler if any. [ruby-core:20970] * thread.c (rb_threadptr_check_signal): separeted from timer_thread_function. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27513 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 ++++++++ eval.c | 6 ++++++ test/ruby/test_signal.rb | 15 ++++++++++++++- thread.c | 26 +++++++++++++++++--------- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f82b56c56..e7c0c379a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Tue Apr 27 21:24:40 2010 Yusuke Endoh + + * eval.c (ruby_cleanup): before cleanup, check signal buffer and run + handler if any. [ruby-core:20970] + + * thread.c (rb_threadptr_check_signal): separeted from + timer_thread_function. + Tue Apr 27 18:00:50 2010 Nobuyoshi Nakada * lib/net/smtp.rb (Net::SMTP#rcptto_list): fixed typo. diff --git a/eval.c b/eval.c index a1deab6c8b..2db160c2ea 100644 --- a/eval.c +++ b/eval.c @@ -127,6 +127,12 @@ ruby_cleanup(volatile int ex) volatile VALUE errs[2]; rb_thread_t *th = GET_THREAD(); int nerr; + void rb_threadptr_interrupt(rb_thread_t *th); + void rb_threadptr_check_signal(rb_thread_t *mth); + + rb_threadptr_interrupt(th); + rb_threadptr_check_signal(th); + RUBY_VM_CHECK_INTS(); errs[1] = th->errinfo; th->safe_level = 0; diff --git a/test/ruby/test_signal.rb b/test/ruby/test_signal.rb index 1ecf5401ab..5d9d3cd691 100644 --- a/test/ruby/test_signal.rb +++ b/test/ruby/test_signal.rb @@ -36,7 +36,7 @@ class TestSignal < Test::Unit::TestCase end def test_exit_action - return unless have_fork? # snip this test + return unless have_fork? # skip this test begin r, w = IO.pipe r0, w0 = IO.pipe @@ -166,4 +166,17 @@ class TestSignal < Test::Unit::TestCase Signal.trap(:INT, oldtrap) if oldtrap end end + + def test_kill_immediately_before_termination + return unless have_fork? # skip this test + + r, w = IO.pipe + pid = Process.fork do + r.close + Signal.trap(:USR1) { w.syswrite("foo") } + Process.kill :USR1, $$ + end + w.close + assert_equal(r.read, "foo") + end end diff --git a/thread.c b/thread.c index 094427f06c..ad35c103e7 100644 --- a/thread.c +++ b/thread.c @@ -290,7 +290,7 @@ reset_unblock_function(rb_thread_t *th, const struct rb_unblock_callback *old) native_mutex_unlock(&th->interrupt_lock); } -static void +void rb_threadptr_interrupt(rb_thread_t *th) { native_mutex_lock(&th->interrupt_lock); @@ -2651,18 +2651,13 @@ rb_gc_save_machine_context(rb_thread_t *th) int rb_get_next_signal(void); -static void -timer_thread_function(void *arg) +void +rb_threadptr_check_signal(rb_thread_t *mth) { - rb_vm_t *vm = GET_VM(); /* TODO: fix me for Multi-VM */ int sig; - rb_thread_t *mth; - /* for time slice */ - RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread); + /* mth must be main_thread */ - /* check signal */ - mth = vm->main_thread; if (!mth->exec_signal && (sig = rb_get_next_signal()) > 0) { enum rb_thread_status prev_status = mth->status; thread_debug("main_thread: %s, sig: %d\n", @@ -2672,6 +2667,19 @@ timer_thread_function(void *arg) rb_threadptr_interrupt(mth); mth->status = prev_status; } +} + +static void +timer_thread_function(void *arg) +{ + rb_vm_t *vm = GET_VM(); /* TODO: fix me for Multi-VM */ + rb_thread_t *mth; + + /* for time slice */ + RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread); + + /* check signal */ + rb_threadptr_check_signal(vm->main_thread); #if 0 /* prove profiler */ -- cgit v1.2.3