diff --git a/gc/default/default.c b/gc/default/default.c index 5bbdc1e0265a7b..9a712b8cc2be99 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -2774,7 +2774,11 @@ rb_gc_impl_undefine_finalizer(void *objspace_ptr, VALUE obj) GC_ASSERT(!OBJ_FROZEN(obj)); st_data_t data = obj; + + int lev = rb_gc_vm_lock(); st_delete(finalizer_table, &data, 0); + rb_gc_vm_unlock(lev); + FL_UNSET(obj, FL_FINALIZE); } diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c index 59bef826bf1f01..aec48df07ae31c 100644 --- a/gc/mmtk/mmtk.c +++ b/gc/mmtk/mmtk.c @@ -966,7 +966,11 @@ rb_gc_impl_undefine_finalizer(void *objspace_ptr, VALUE obj) struct objspace *objspace = objspace_ptr; st_data_t data = obj; + + int lev = rb_gc_vm_lock(); st_delete(objspace->finalizer_table, &data, 0); + rb_gc_vm_unlock(lev); + FL_UNSET(obj, FL_FINALIZE); } diff --git a/test/objspace/test_ractor.rb b/test/objspace/test_ractor.rb index 4901eeae2e16f8..c5bb656da6a468 100644 --- a/test/objspace/test_ractor.rb +++ b/test/objspace/test_ractor.rb @@ -14,4 +14,23 @@ def test_tracing_does_not_crash end RUBY end + + def test_undefine_finalizer + assert_ractor(<<~'RUBY', require: 'objspace') + def fin + ->(id) { } + end + ractors = 5.times.map do + Ractor.new do + 10_000.times do + o = Object.new + ObjectSpace.define_finalizer(o, fin) + ObjectSpace.undefine_finalizer(o) + end + end + end + + ractors.each(&:take) + RUBY + end end