summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--eval.c6
-rw-r--r--test/ruby/test_signal.rb15
-rw-r--r--thread.c26
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 <mame@tsg.ne.jp>
+
+ * 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 <nobu@ruby-lang.org>
* 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 */