From de2c2bd60fdce52cc7ba38a25f3e9436442af604 Mon Sep 17 00:00:00 2001 From: Luke Gruber Date: Thu, 4 Dec 2025 16:10:21 -0500 Subject: [PATCH] Take VM lock in `class_switch_superclass` (#15356) Safe multi-ractor subclass list mutation We need to lock around mutation and accesses of a class's subclasses list. Unfortunately we also need to do this when creating singleton classes, as the singleton class does need to go into `super`'s subclasses list for CC invalidation purposes. --- class.c | 6 ++++-- test/ruby/test_class.rb | 13 +++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/class.c b/class.c index 0cec526b74..9716ba07da 100644 --- a/class.c +++ b/class.c @@ -734,8 +734,10 @@ class_detach_subclasses(VALUE klass, VALUE arg) static void class_switch_superclass(VALUE super, VALUE klass) { - class_detach_subclasses(klass, Qnil); - rb_class_subclass_add(super, klass); + RB_VM_LOCKING() { + class_detach_subclasses(klass, Qnil); + rb_class_subclass_add(super, klass); + } } /** diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb index 10b7655e9a..1faecd0cb2 100644 --- a/test/ruby/test_class.rb +++ b/test/ruby/test_class.rb @@ -917,4 +917,17 @@ CODE end end; end + + def test_safe_multi_ractor_subclasses_list_mutation + assert_ractor "#{<<~"begin;"}\n#{<<~'end;'}" + begin; + 4.times.map do + Ractor.new do + 20_000.times do + Object.new.singleton_class + end + end + end.each(&:join) + end; + end end