aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bootstraptest/test_thread.rb14
-rw-r--r--thread.c18
2 files changed, 31 insertions, 1 deletions
diff --git a/bootstraptest/test_thread.rb b/bootstraptest/test_thread.rb
index e7ddadf4a7..38a55ff229 100644
--- a/bootstraptest/test_thread.rb
+++ b/bootstraptest/test_thread.rb
@@ -484,3 +484,17 @@ assert_equal 'foo', %q{
GC.start
f.call.source
}
+assert_normal_exit %q{
+ class C
+ def inspect
+ sleep 0.5
+ 'C!!'
+ end
+ end
+ Thread.new{
+ loop{
+ p C.new
+ }
+ }
+ sleep 0.1
+}, timeout: 5
diff --git a/thread.c b/thread.c
index e59b6dbac8..ccfa870f99 100644
--- a/thread.c
+++ b/thread.c
@@ -5564,6 +5564,19 @@ rb_default_coverage(int n)
return coverage;
}
+static VALUE
+uninterruptible_exit(VALUE v)
+{
+ rb_thread_t *cur_th = GET_THREAD();
+ rb_ary_pop(cur_th->pending_interrupt_mask_stack);
+
+ cur_th->pending_interrupt_queue_checked = 0;
+ if (!rb_threadptr_pending_interrupt_empty_p(cur_th)) {
+ RUBY_VM_SET_INTERRUPT(cur_th->ec);
+ }
+ return Qnil;
+}
+
VALUE
rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data)
{
@@ -5574,5 +5587,8 @@ rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data)
OBJ_FREEZE_RAW(interrupt_mask);
rb_ary_push(cur_th->pending_interrupt_mask_stack, interrupt_mask);
- return rb_ensure(b_proc, data, rb_ary_pop, cur_th->pending_interrupt_mask_stack);
+ VALUE ret = rb_ensure(b_proc, data, uninterruptible_exit, Qnil);
+
+ RUBY_VM_CHECK_INTS(cur_th->ec);
+ return ret;
}