From 0c0d0752f1fefd9b085f191b62946a811763ef1b Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Thu, 22 Oct 2020 00:36:53 +0900 Subject: [PATCH] allow to access ivars of frozen shareable objects Accessing a shareable object is prohibitted because it can cause race condition, but if the shareable object is frozen, there is no problem to access ivars. --- bootstraptest/test_ractor.rb | 12 ++++++++++++ variable.c | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index 6290b73c36..62b0b523ae 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -734,6 +734,18 @@ assert_equal 'can not access instance variables of shareable objects from non-ma end } +# But a sharable object is frozen, it is allowed to access ivars from non-main Ractor +assert_equal '11', %q{ + [Object.new, [], ].map{|obj| + obj.instance_variable_set('@a', 1) + Ractor.make_shareable obj = obj.freeze + + Ractor.new obj do |obj| + obj.instance_variable_get('@a') + end.take.to_s + }.join +} + # cvar in sharable-objects are not allowed to access from non-main Ractor assert_equal 'can not access class variables from non-main Ractors', %q{ class C diff --git a/variable.c b/variable.c index 795ee3fb0a..8ac40efe80 100644 --- a/variable.c +++ b/variable.c @@ -922,7 +922,8 @@ generic_ivtbl(VALUE obj, ID id, bool force_check_ractor) { ASSERT_vm_locking(); - if ((force_check_ractor || rb_is_instance_id(id)) && // not internal ID + if ((force_check_ractor || LIKELY(rb_is_instance_id(id)) /* not internal ID */ ) && + !RB_OBJ_FROZEN_RAW(obj) && UNLIKELY(!rb_ractor_main_p()) && UNLIKELY(rb_ractor_shareable_p(obj))) { rb_raise(rb_eRuntimeError, "can not access instance variables of shareable objects from non-main Ractors");