[前][次][番号順一覧][スレッド一覧]

ruby-changes:71683

From: Koichi <ko1@a...>
Date: Fri, 8 Apr 2022 21:30:47 +0900 (JST)
Subject: [ruby-changes:71683] c77a31df5e (master): call `const_added` after `autoload`

https://git.ruby-lang.org/ruby.git/commit/?id=c77a31df5e

From c77a31df5ed17231b2ddd213899716b900181ad2 Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Fri, 8 Apr 2022 16:44:03 +0900
Subject: call `const_added` after `autoload`

When calling `const_added` while process in `autoload`, it can
cause synchronization issue because of a thread swithcing.

http://ci.rvm.jp/logfiles/brlog.trunk.20220407-152213#L489

```
1)
Module#autoload (concurrently) raises a LoadError in each thread if the file does not exist ERROR
NameError: uninitialized constant ModuleSpecs::Autoload::FileDoesNotExist

            ModuleSpecs::Autoload::FileDoesNotExist
                                 ^^^^^^^^^^^^^^^^^^
/tmp/ruby/v3/src/trunk/spec/ruby/core/module/autoload_spec.rb:965:in `block (5 levels) in <top (required)>'
```
---
 variable.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/variable.c b/variable.c
index 577c2b855f..082b4c1549 100644
--- a/variable.c
+++ b/variable.c
@@ -2239,6 +2239,9 @@ rb_autoload(VALUE mod, ID id, const char *file) https://github.com/ruby/ruby/blob/trunk/variable.c#L2239
     rb_autoload_str(mod, id, rb_fstring_cstr(file));
 }
 
+static void const_set(VALUE klass, ID id, VALUE val);
+static void const_added(VALUE klass, ID const_name);
+
 void
 rb_autoload_str(VALUE mod, ID id, VALUE file)
 {
@@ -2263,7 +2266,7 @@ rb_autoload_str(VALUE mod, ID id, VALUE file) https://github.com/ruby/ruby/blob/trunk/variable.c#L2266
 	return;
     }
 
-    rb_const_set(mod, id, Qundef);
+    const_set(mod, id, Qundef);
     tbl = RCLASS_IV_TBL(mod);
     if (tbl && st_lookup(tbl, (st_data_t)autoload, &av)) {
 	tbl = check_autoload_table((VALUE)av);
@@ -2307,6 +2310,8 @@ rb_autoload_str(VALUE mod, ID id, VALUE file) https://github.com/ruby/ruby/blob/trunk/variable.c#L2310
         ccan_list_add_tail(&ele->constants, &ac->cnode);
         st_insert(tbl, (st_data_t)id, (st_data_t)acv);
     }
+
+    const_added(mod, id);
 }
 
 static void
@@ -3111,14 +3116,14 @@ const_added(VALUE klass, ID const_name) https://github.com/ruby/ruby/blob/trunk/variable.c#L3116
     }
 }
 
-void
-rb_const_set(VALUE klass, ID id, VALUE val)
+static void
+const_set(VALUE klass, ID id, VALUE val)
 {
     rb_const_entry_t *ce;
 
     if (NIL_P(klass)) {
-	rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"",
-		 QUOTE_ID(id));
+        rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"",
+                 QUOTE_ID(id));
     }
 
     if (!rb_ractor_main_p() && !rb_ractor_shareable_p(val)) {
@@ -3156,10 +3161,10 @@ rb_const_set(VALUE klass, ID id, VALUE val) https://github.com/ruby/ruby/blob/trunk/variable.c#L3161
         int val_path_permanent;
         VALUE val_path = classname(val, &val_path_permanent);
         if (NIL_P(val_path) || !val_path_permanent) {
-	    if (klass == rb_cObject) {
+            if (klass == rb_cObject) {
                 set_namespace_path(val, rb_id2str(id));
-	    }
-	    else {
+            }
+            else {
                 int parental_path_permanent;
                 VALUE parental_path = classname(klass, &parental_path_permanent);
                 if (NIL_P(parental_path)) {
@@ -3172,9 +3177,15 @@ rb_const_set(VALUE klass, ID id, VALUE val) https://github.com/ruby/ruby/blob/trunk/variable.c#L3177
                 else if (!parental_path_permanent && NIL_P(val_path)) {
                     ivar_set(val, tmp_classpath, build_const_path(parental_path, id));
                 }
-	    }
-	}
+            }
+        }
     }
+}
+
+void
+rb_const_set(VALUE klass, ID id, VALUE val)
+{
+    const_set(klass, id, val);
     const_added(klass, id);
 }
 
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]