From a29442701785463d0febf5b8cf217246e927bfae Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 15 May 2025 13:43:44 +0200 Subject: [PATCH] Add missing lock to `rb_gc_impl_copy_finalizer` --- gc/default/default.c | 2 ++ gc/mmtk/mmtk.c | 2 ++ test/objspace/test_ractor.rb | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/gc/default/default.c b/gc/default/default.c index 7743164732..5c6c2a9417 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -2803,6 +2803,7 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj) if (!FL_TEST(obj, FL_FINALIZE)) return; + int lev = rb_gc_vm_lock(); if (RB_LIKELY(st_lookup(finalizer_table, obj, &data))) { table = (VALUE)data; st_insert(finalizer_table, dest, table); @@ -2811,6 +2812,7 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj) else { rb_bug("rb_gc_copy_finalizer: FL_FINALIZE set but not found in finalizer_table: %s", rb_obj_info(obj)); } + rb_gc_vm_unlock(lev); } static VALUE diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c index aec48df07a..09a8c0bc5c 100644 --- a/gc/mmtk/mmtk.c +++ b/gc/mmtk/mmtk.c @@ -983,6 +983,7 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj) if (!FL_TEST(obj, FL_FINALIZE)) return; + int lev = rb_gc_vm_lock(); if (RB_LIKELY(st_lookup(objspace->finalizer_table, obj, &data))) { table = (VALUE)data; st_insert(objspace->finalizer_table, dest, table); @@ -991,6 +992,7 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj) else { rb_bug("rb_gc_copy_finalizer: FL_FINALIZE set but not found in finalizer_table: %s", rb_obj_info(obj)); } + rb_gc_vm_unlock(lev); } static int diff --git a/test/objspace/test_ractor.rb b/test/objspace/test_ractor.rb index c5bb656da6..1176a78b4b 100644 --- a/test/objspace/test_ractor.rb +++ b/test/objspace/test_ractor.rb @@ -33,4 +33,25 @@ class TestObjSpaceRactor < Test::Unit::TestCase ractors.each(&:take) RUBY end + + def test_copy_finalizer + assert_ractor(<<~'RUBY', require: 'objspace') + def fin + ->(id) { } + end + OBJ = Object.new + ObjectSpace.define_finalizer(OBJ, fin) + OBJ.freeze + + ractors = 5.times.map do + Ractor.new do + 10_000.times do + OBJ.clone + end + end + end + + ractors.each(&:take) + RUBY + end end