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

ruby-changes:63799

From: Nobuyoshi <ko1@a...>
Date: Mon, 30 Nov 2020 16:08:00 +0900 (JST)
Subject: [ruby-changes:63799] 930a135524 (master): Fixed Ractor.shareable? on cross-recursive objects [Bug #17344]

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

From 930a135524382ddd80c0608a7593b6cdfceee846 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Mon, 30 Nov 2020 16:07:36 +0900
Subject: Fixed Ractor.shareable? on cross-recursive objects [Bug #17344]


diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index d5d78d7..6bd00d5 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -975,6 +975,15 @@ assert_equal 'true', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L975
   Ractor.shareable?(pr)
 }
 
+# Ractor.shareable?(recursive_objects)
+assert_equal '[false, false]', %q{
+  y = []
+  x = [y, {}].freeze
+  y << x
+  y.freeze
+  [Ractor.shareable?(x), Ractor.shareable?(y)]
+}
+
 # define_method() can invoke different Ractor's proc if the proc is shareable.
 assert_equal '1', %q{
   class C
diff --git a/ractor.c b/ractor.c
index cb474d0..9a09312 100644
--- a/ractor.c
+++ b/ractor.c
@@ -1805,6 +1805,9 @@ enum obj_traverse_iterator_result { https://github.com/ruby/ruby/blob/trunk/ractor.c#L1805
 
 typedef enum obj_traverse_iterator_result (*rb_obj_traverse_enter_func)(VALUE obj);
 typedef enum obj_traverse_iterator_result (*rb_obj_traverse_leave_func)(VALUE obj);
+typedef enum obj_traverse_iterator_result (*rb_obj_traverse_final_func)(VALUE obj);
+
+static enum obj_traverse_iterator_result null_leave(VALUE obj);
 
 struct obj_traverse_data {
     rb_obj_traverse_enter_func enter_func;
@@ -1979,12 +1982,29 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data) https://github.com/ruby/ruby/blob/trunk/ractor.c#L1982
     }
 }
 
+struct rb_obj_traverse_final_data {
+    rb_obj_traverse_final_func final_func;
+    int stopped;
+};
+
+static int
+obj_traverse_final_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+    struct rb_obj_traverse_final_data *data = (void *)arg;
+    if (data->final_func(key)) {
+        data->stopped = 1;
+        return ST_STOP;
+    }
+    return ST_CONTINUE;
+}
+
 // 0: traverse all
 // 1: stopped
 static int
 rb_obj_traverse(VALUE obj,
                 rb_obj_traverse_enter_func enter_func,
-                rb_obj_traverse_leave_func leave_func)
+                rb_obj_traverse_leave_func leave_func,
+                rb_obj_traverse_final_func final_func)
 {
     struct obj_traverse_data data = {
         .enter_func = enter_func,
@@ -1992,7 +2012,13 @@ rb_obj_traverse(VALUE obj, https://github.com/ruby/ruby/blob/trunk/ractor.c#L2012
         .rec = NULL,
     };
 
-    return obj_traverse_i(obj, &data);
+    if (obj_traverse_i(obj, &data)) return 1;
+    if (final_func && data.rec) {
+        struct rb_obj_traverse_final_data f = {final_func, 0};
+        st_foreach(data.rec, obj_traverse_final_i, (st_data_t)&f);
+        return f.stopped;
+    }
+    return 0;
 }
 
 static int
@@ -2063,7 +2089,7 @@ rb_ractor_make_shareable(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2089
 {
     rb_obj_traverse(obj,
                     make_shareable_check_shareable,
-                    mark_shareable);
+                    mark_shareable, mark_shareable);
     return obj;
 }
 
@@ -2092,7 +2118,7 @@ MJIT_FUNC_EXPORTED bool https://github.com/ruby/ruby/blob/trunk/ractor.c#L2118
 rb_ractor_shareable_p_continue(VALUE obj)
 {
     if (rb_obj_traverse(obj,
-                        shareable_p_enter,
+                        shareable_p_enter, null_leave,
                         mark_shareable)) {
         return false;
     }
@@ -2113,20 +2139,20 @@ reset_belonging_enter(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2139
         return traverse_cont;
     }
 }
+#endif
 
 static enum obj_traverse_iterator_result
 null_leave(VALUE obj)
 {
     return traverse_cont;
 }
-#endif
 
 static VALUE
 ractor_reset_belonging(VALUE obj)
 {
 #if RACTOR_CHECK_MODE > 0
     rp(obj);
-    rb_obj_traverse(obj, reset_belonging_enter, null_leave);
+    rb_obj_traverse(obj, reset_belonging_enter, null_leave, NULL);
 #endif
     return obj;
 }
-- 
cgit v0.10.2


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

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