From 1435ea7f44f3d781a03054b4055a1ad2f90dd392 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 23 May 2025 16:08:51 +0200 Subject: [PATCH] Add missing lock for `Module#remove_instance_variable` We must take a lock to ensure another ractor isn't reading the ivars while we're moving them. --- variable.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/variable.c b/variable.c index fd88849689..5c381f80ba 100644 --- a/variable.c +++ b/variable.c @@ -1537,9 +1537,13 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef) { rb_check_frozen(obj); + bool locked = false; + unsigned int lev = 0; VALUE val = undef; if (BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE) { IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(id); + RB_VM_LOCK_ENTER_LEV(&lev); + locked = true; } shape_id_t old_shape_id = rb_obj_shape_id(obj); @@ -1551,6 +1555,9 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef) shape_id_t next_shape_id = rb_shape_transition_remove_ivar(obj, id, &removed_shape_id); if (next_shape_id == old_shape_id) { + if (locked) { + RB_VM_LOCK_LEAVE_LEV(&lev); + } return undef; } @@ -1600,6 +1607,10 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef) } rb_shape_set_shape_id(obj, next_shape_id); + if (locked) { + RB_VM_LOCK_LEAVE_LEV(&lev); + } + return val; too_complex: @@ -1630,6 +1641,11 @@ too_complex: } } } + + if (locked) { + RB_VM_LOCK_LEAVE_LEV(&lev); + } + return val; }