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; }