instance method · added in Ruby 3.4
Fiber::Scheduler#blocking_operation_wait
blocking_operation_wait(blocking_operation)
scheduler.c
View on GitHub ↗
VALUE rb_fiber_scheduler_blocking_operation_wait(VALUE scheduler, void* (*function)(void *), void *data, rb_unblock_function_t *unblock_function, void *data2, int flags, struct rb_fiber_scheduler_blocking_operation_state *state)
{
// Check if scheduler supports blocking_operation_wait before creating the object
if (!rb_respond_to(scheduler, id_blocking_operation_wait)) {
return Qundef;
}
// Create a new BlockingOperation with the blocking operation
VALUE blocking_operation = rb_fiber_scheduler_blocking_operation_new(function, data, unblock_function, data2, flags, state);
VALUE result = rb_funcall(scheduler, id_blocking_operation_wait, 1, blocking_operation);
// Get the operation data to check if it was executed
rb_fiber_scheduler_blocking_operation_t *operation = get_blocking_operation(blocking_operation);
rb_atomic_t current_status = RUBY_ATOMIC_LOAD(operation->status);
// Invalidate the operation now that we're done with it
operation->function = NULL;
operation->state = NULL;
operation->data = NULL;
operation->data2 = NULL;
operation->unblock_function = NULL;
// If the blocking operation was never executed, return Qundef to signal the caller to use rb_nogvl instead
if (current_status == RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_QUEUED) {
return Qundef;
}
return result;
}
Invoked by Ruby’s core methods to run a blocking operation in a non-blocking way. The blocking_operation is an opaque object that encapsulates the blocking operation and responds to a call method without any arguments.
If the scheduler doesn’t implement this method, or if the scheduler doesn’t execute the blocking operation, Ruby will fall back to the non-scheduler implementation.
Minimal suggested implementation is:
Example
def blocking_operation_wait(blocking_operation) Thread.new { blocking_operation.call }.join end
Ruby version changes
-
3.4
-
An optional
Fiber::Scheduler#blocking_operation_waithook allows blocking operations to be moved out of the event loop in order to reduce latency and improve multi-core processor utilization. [Feature #20876]
-