Commit ea006ed
Fix GC safety of blocking_operation in rb_fiber_scheduler_blocking_operation_wait
rb_funcall(scheduler, :blocking_operation_wait, 1, blocking_operation) can
cause a fiber switch if the scheduler implementation calls
rb_fiber_scheduler_block (e.g. a worker-pool scheduler). When the fiber is
suspended, the C frame of rb_fiber_scheduler_blocking_operation_wait is no
longer active. In optimised builds, may be held only in
a machine register that the conservative GC does not scan for suspended
fibers, allowing the object to be collected before get_blocking_operation()
is called at line 1104.
RB_GC_GUARD(blocking_operation) after rb_funcall forces the compiler to keep
the VALUE on the stack (via a volatile read), ensuring it is always reachable
as a GC root regardless of register allocation.
Confirmed by GC.disable workaround in socketry/io-event#170
which prevents the crash by stopping GC during the blocking_operation_wait call.
Co-authored-by: Cursor <cursoragent@cursor.com>1 parent 9072aa9 commit ea006ed
1 file changed
Lines changed: 8 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1100 | 1100 | | |
1101 | 1101 | | |
1102 | 1102 | | |
| 1103 | + | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
1103 | 1111 | | |
1104 | 1112 | | |
1105 | 1113 | | |
| |||
0 commit comments