Skip to content

Commit

Permalink
should check pending interrupts correctly.
Browse files Browse the repository at this point in the history
rb_uninterruptible() disables any interrupts using handle_interrupt
feature (This function is used by `p`).
After this function, pending interrupts should be checked correctly,
however there is no chance to setup interrupt flag of working
threads, it means that nobody checks pending interrupts.
For example, it ignores terminate signal delivered at the end
of main thread and program can't stop.

This patch set interrupt flag if there are pending interrupts.
  • Loading branch information
ko1 committed Apr 9, 2020
1 parent d2bb2e0 commit fd0222c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
14 changes: 14 additions & 0 deletions bootstraptest/test_thread.rb
Expand Up @@ -484,3 +484,17 @@ def m
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
18 changes: 17 additions & 1 deletion thread.c
Expand Up @@ -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)
{
Expand All @@ -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;
}

0 comments on commit fd0222c

Please sign in to comment.