diff options
author | Luke Gruber <[email protected]> | 2025-05-21 11:32:49 -0400 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2025-05-23 18:20:35 +0900 |
commit | 966fcb77e48328baf28c1d042d8da25ba181f262 (patch) | |
tree | d0ab529baa099873d586a07a676c0ece4ec6e8d3 /variable.c | |
parent | 627a5ac53b8116d83ad63929c8510cae674f8423 (diff) |
lock vm around `rb_free_generic_ivar`
Currently, this can be reproduced by:
r = Ractor.new do
a = [1, 2, 3]
a.object_id
a.dup # this frees the generic ivar for `object_id` on the copied object
:done
end
r.take
In debug builds, this hits an assertion failure without this fix.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13401
Diffstat (limited to 'variable.c')
-rw-r--r-- | variable.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/variable.c b/variable.c index 62dfe5844e..661a0ef04f 100644 --- a/variable.c +++ b/variable.c @@ -1273,15 +1273,19 @@ rb_free_generic_ivar(VALUE obj) bool too_complex = rb_shape_obj_too_complex_p(obj); - if (st_delete(generic_fields_tbl_no_ractor_check(obj), &key, &value)) { - struct gen_fields_tbl *fields_tbl = (struct gen_fields_tbl *)value; + RB_VM_LOCK_ENTER(); + { + if (st_delete(generic_fields_tbl_no_ractor_check(obj), &key, &value)) { + struct gen_fields_tbl *fields_tbl = (struct gen_fields_tbl *)value; - if (UNLIKELY(too_complex)) { - st_free_table(fields_tbl->as.complex.table); - } + if (UNLIKELY(too_complex)) { + st_free_table(fields_tbl->as.complex.table); + } - xfree(fields_tbl); + xfree(fields_tbl); + } } + RB_VM_LOCK_LEAVE(); } size_t |