thread: build a new Ractor's interrupt queue on its own main thread

Defer creating a Ractor main thread's pending-interrupt queue and mask stack
from thread_create_core (the creating thread) to thread_start_func_2 (the new
Ractor's own main thread). The mask stack starts empty rather than duplicating
the creating thread's, so a new Ractor does not inherit its
Thread.handle_interrupt state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Koichi Sasada 2026-07-02 20:47:37 +00:00
parent f5ef758a75
commit ff96f9dc1c
Notes: git 2026-07-03 01:57:45 +00:00

View File

@ -680,6 +680,13 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start)
r->r_stdin = rb_io_prep_stdin();
r->r_stdout = rb_io_prep_stdout();
r->r_stderr = rb_io_prep_stderr();
/* Build the interrupt queue and mask stack here, on the new Ractor's
* own main thread, instead of carrying over the ones the creating
* thread made. The mask stack starts empty so a new Ractor does not
* inherit the creating thread's Thread.handle_interrupt state. */
th->pending_interrupt_queue = rb_ary_hidden_new(0);
th->pending_interrupt_mask_stack = rb_ary_hidden_new(0);
}
RB_VM_UNLOCK();
}
@ -887,10 +894,19 @@ thread_create_core(VALUE thval, struct thread_create_params *params)
th->priority = current_th->priority;
th->thgroup = current_th->thgroup;
th->pending_interrupt_queue = rb_ary_hidden_new(0);
th->pending_interrupt_queue_checked = 0;
th->pending_interrupt_mask_stack = rb_ary_dup(current_th->pending_interrupt_mask_stack);
RBASIC_CLEAR_CLASS(th->pending_interrupt_mask_stack);
if (th->invoke_type == thread_invoke_type_ractor_proc) {
/* A new Ractor's main thread builds these on start
* (thread_start_func_2); leave them unset until then. */
th->pending_interrupt_queue = 0;
th->pending_interrupt_mask_stack = 0;
th->pending_interrupt_queue_checked = 0;
}
else {
th->pending_interrupt_queue = rb_ary_hidden_new(0);
th->pending_interrupt_queue_checked = 0;
th->pending_interrupt_mask_stack = rb_ary_dup(current_th->pending_interrupt_mask_stack);
RBASIC_CLEAR_CLASS(th->pending_interrupt_mask_stack);
}
rb_native_mutex_initialize(&th->interrupt_lock);