Add missing lock in rb_gc_impl_undefine_finalizer

The table is global so accesses must be synchronized.
This commit is contained in:
Jean Boussier 2025-05-15 13:00:18 +02:00
parent 3d1b8e7298
commit ed632cd0ba
Notes: git 2025-05-15 11:32:21 +00:00
3 changed files with 27 additions and 0 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -14,4 +14,23 @@ class TestObjSpaceRactor < Test::Unit::TestCase
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