Skip to content

Commit d0a2570

Browse files
committed
Clear interrupt_mask_stack on child thread after fork
Otherwise, we inherit a mask stack that can never be popped.
1 parent 9fefb48 commit d0a2570

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

test/ruby/test_thread.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,4 +1694,22 @@ def self.make_finalizer(stdin, stdout, stderr, wait_thread)
16941694
1000.times { Object.new }
16951695
end;
16961696
end
1697+
1698+
def test_thread_interrupt_mask_stack_cleared_after_fork_in_child
1699+
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}", timeout: 60)
1700+
begin;
1701+
Thread.handle_interrupt(Object => :never) do
1702+
pid = fork do
1703+
th = Thread.new do
1704+
loop do
1705+
end
1706+
end
1707+
while th.status
1708+
th.kill
1709+
end
1710+
end
1711+
Process.waitpid(pid)
1712+
end
1713+
end;
1714+
end if Process.respond_to?(:fork)
16971715
end

thread.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4980,6 +4980,7 @@ rb_thread_atfork_internal(rb_thread_t *th, void (*atfork)(rb_thread_t *, const r
49804980
vm->ractor.main_thread = th;
49814981
r->threads.main = th;
49824982
r->status_ = ractor_created;
4983+
rb_ary_clear(th->pending_interrupt_mask_stack);
49834984

49844985
thread_sched_atfork(TH_SCHED(th));
49854986
ubf_list_atfork();

0 commit comments

Comments
 (0)