Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
Fiber::Scheduler#fiber_interrupt
VALUE rb_fiber_scheduler_fiber_interrupt(VALUE scheduler, VALUE target, VALUE exception)
{
VALUE arguments[] = {
target, exception
};
VALUE result;
enum ruby_tag_type state;
// We must prevent interrupts while invoking the fiber_interrupt method, because otherwise fibers can be left permanently blocked if an interrupt occurs during the execution of user code. See also `rb_fiber_scheduler_unblock`.
rb_execution_context_t * volatile ec = GET_EC();
volatile int saved_interrupt_mask = ec->interrupt_mask;
ec->interrupt_mask |= PENDING_INTERRUPT_MASK;
rb_control_frame_t *volatile cfp = ec->cfp;
EC_PUSH_TAG(ec);
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
result = rb_funcallv(scheduler, id_fiber_interrupt, 2, arguments);
}
else {
rb_vm_rewind_cfp(ec, cfp);
}
EC_POP_TAG();
ec->interrupt_mask = saved_interrupt_mask;
if (state) {
EC_JUMP_TAG(ec, state);
}
RUBY_VM_CHECK_INTS(ec);
return result;
}
Invoked by Ruby’s core methods to notify the scheduler that a blocked fiber should be interrupted with an exception. For IO operations, target is an operation-scoped proxy which responds to alive?, raise, and transfer. The scheduler should enqueue the target on its owning thread and use only those methods. transfer raises the interruption’s stored exception in the target. Once the operation completes, alive? returns false and raise has no effect, preventing a delayed exception from escaping into a later operation.
Ruby version changes
-
4.0
-
Introduce
Fiber::Scheduler#fiber_interruptto interrupt a fiber with a given exception. The initial use case is to interrupt a fiber that is waiting on a blockingIOoperation when theIOoperation is closed. [Feature #21166]
-