diff options
| author | Samuel Williams <samuel.williams@shopify.com> | 2026-05-10 16:58:45 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-10 16:58:45 +0900 |
| commit | 8351378bf3173d48fd8510badf1139809553185a (patch) | |
| tree | 3721d0731faecf4bc37727e5947c46121ce72c3c | |
| parent | 276f0d9b3efbabe46e74510e5e3585924b37772c (diff) | |
`rb_fiber_scheduler_blocking_operation_wait` can garbage collect `blocking_operation` incorrectly. (#16908)
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.
| -rw-r--r-- | scheduler.c | 3 |
1 files changed, 3 insertions, 0 deletions
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; |
