summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2025-11-13 21:45:27 -0500
committergit <svn-admin@ruby-lang.org>2025-11-14 03:22:49 +0000
commit256b4722a0dc45ee8d675db0a30f37d32a40ea88 (patch)
treed6c15265abfd055fb338bfbcbab75abbdc96e59c
parentc92a44ee685fc10ce7cf4f8865d1942eb40d2780 (diff)
[ruby/mmtk] 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. https://github.com/ruby/mmtk/commit/e4bea5676d
-rw-r--r--gc/mmtk/mmtk.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c
index cc0b1afd4d..0d78d61b7f 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