Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
instance method
Fiber::Scheduler#unblock
unblock(blocker, fiber)
scheduler.c
View on GitHub ↗
VALUE
rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber)
{
RUBY_ASSERT(rb_obj_is_fiber(fiber));
VALUE result;
enum ruby_tag_type state;
// `rb_fiber_scheduler_unblock` can be called from points where `errno` is expected to be preserved. Therefore, we should save and restore it. For example `io_binwrite` calls `rb_fiber_scheduler_unblock` and if `errno` is reset to 0 by user code, it will break the error handling in `io_write`.
//
// If we explicitly preserve `errno` in `io_binwrite` and other similar functions (e.g. by returning it), this code is no longer needed. I hope in the future we will be able to remove it.
int saved_errno = errno;
// We must prevent interrupts while invoking the unblock method, because otherwise fibers can be left permanently blocked if an interrupt occurs during the execution of user code. See also `rb_fiber_scheduler_fiber_interrupt`.
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_funcall(scheduler, id_unblock, 2, blocker, fiber);
}
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);
errno = saved_errno;
return result;
}
Invoked to wake up Fiber previously blocked with block (for example, Thread::Mutex#lock calls block and Thread::Mutex#unlock calls unblock). The scheduler should use the fiber parameter to understand which fiber is unblocked.
blocker is what was awaited for, but it is informational only (for debugging and logging), and it is not guaranteed to be the same value as the blocker for block.