diff options
author | Jean Boussier <[email protected]> | 2025-04-22 18:55:55 +0900 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2025-04-22 23:23:35 +0200 |
commit | 7c30bd50df8617063c99630112e1015ec5a743c3 (patch) | |
tree | 82d6ee74826dd9ef50e8801b5d49045ba926d70b /gc/default/default.c | |
parent | 9fc5a5dbedf70d6026ff8b76a57297b8021c5dcd (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.c | 4 |
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; } |