From 8351378bf3173d48fd8510badf1139809553185a Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Sun, 10 May 2026 16:58:45 +0900 Subject: `rb_fiber_scheduler_blocking_operation_wait` can garbage collect `blocking_operation` incorrectly. (#16908) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Place RB_GC_GUARD(blocking_operation) after the last implicit use of the VALUE — all accesses via the derived `operation` pointer — so the compiler cannot treat blocking_operation as dead before this point, keeping it reachable as a GC root through rb_funcall and through all subsequent uses of the raw pointer. --- scheduler.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scheduler.c b/scheduler.c index c2f370a22a..3205bb3bc9 100644 --- a/scheduler.c +++ b/scheduler.c @@ -1111,6 +1111,9 @@ VALUE rb_fiber_scheduler_blocking_operation_wait(VALUE scheduler, void* (*functi operation->data2 = NULL; operation->unblock_function = NULL; + // Ensure that the blocking operation remains visible until this point: + RB_GC_GUARD(blocking_operation); + // 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; -- cgit v1.2.3