From e4bea5676dad28d1f15497712229eb3fb980d09a Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Thu, 13 Nov 2025 21:45:27 -0500 Subject: [PATCH] Lock VM in fork hooks If we are using multiple Ractors, other Ractors may allocate objects after rb_gc_impl_before_fork is ran because it does not lock the VM. This can cause the GC to be in a bad state since rb_gc_impl_before_fork may have terminated GC threads so a GC cannot run until rb_gc_impl_after_fork is ran. --- gc/mmtk/mmtk.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c index cc0b1af..0d78d61 100644 --- a/gc/mmtk/mmtk.c +++ b/gc/mmtk/mmtk.c @@ -38,6 +38,8 @@ struct objspace { size_t start_the_world_count; struct rb_gc_vm_context vm_context; + + unsigned int fork_hook_vm_lock_lev; }; struct MMTk_ractor_cache { @@ -1045,13 +1047,21 @@ rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr) void rb_gc_impl_before_fork(void *objspace_ptr) { + struct objspace *objspace = objspace_ptr; + + objspace->fork_hook_vm_lock_lev = RB_GC_VM_LOCK(); + mmtk_before_fork(); } void rb_gc_impl_after_fork(void *objspace_ptr, rb_pid_t pid) { + struct objspace *objspace = objspace_ptr; + mmtk_after_fork(rb_gc_get_ractor_newobj_cache()); + + RB_GC_VM_UNLOCK(objspace->fork_hook_vm_lock_lev); } // Statistics