summaryrefslogtreecommitdiff
path: root/gc/default/default.c
diff options
context:
space:
mode:
authorJean Boussier <[email protected]>2025-04-22 18:55:55 +0900
committerJean Boussier <[email protected]>2025-04-22 23:23:35 +0200
commit7c30bd50df8617063c99630112e1015ec5a743c3 (patch)
tree82d6ee74826dd9ef50e8801b5d49045ba926d70b /gc/default/default.c
parent9fc5a5dbedf70d6026ff8b76a57297b8021c5dcd (diff)
Add missing lock in `rb_gc_impl_define_finalizer`
`objspace->finalizer_table` must be synchronized, otherwise concurrent insertion from multiple ractors will cause a crash. Repro: ```ruby ractors = 5.times.map do |i| Ractor.new do 100_000.times.map do o = Object.new ObjectSpace.define_finalizer(o, ->(id) {}) o end end end ractors.each(&:take) ```
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13151
Diffstat (limited to 'gc/default/default.c')
-rw-r--r--gc/default/default.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/gc/default/default.c b/gc/default/default.c
index 447fe15b06..1dda258bfd 100644
--- a/gc/default/default.c
+++ b/gc/default/default.c
@@ -2834,6 +2834,8 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block)
RBASIC(obj)->flags |= FL_FINALIZE;
+ int lev = rb_gc_vm_lock();
+
if (st_lookup(finalizer_table, obj, &data)) {
table = (VALUE)data;
@@ -2858,6 +2860,8 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block)
st_add_direct(finalizer_table, obj, table);
}
+ rb_gc_vm_unlock(lev);
+
return block;
}