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

ruby-changes:64308

From: Koichi <ko1@a...>
Date: Sat, 19 Dec 2020 05:55:28 +0900 (JST)
Subject: [ruby-changes:64308] 80cb9165fa (master): add "copy: true" option for Ractor.make_shareable

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

From 80cb9165fa34185b601970da407a295a78ec9eff Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Sat, 19 Dec 2020 05:52:18 +0900
Subject: add "copy: true" option for Ractor.make_shareable

Ractor.make_shareable(obj) tries to make obj a shareable object
by changing the attribute of obj and traversable objects from obj
(mainly freeze them).

"copy: true" option is more conservative approach by make deep
copied object and make it sharable. It doesn't affect any existing
objects.

diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index e81afb6..c587c2c 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -1176,6 +1176,22 @@ assert_equal 'can not make a Proc shareable because it accesses outer variables https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L1176
   end
 }
 
+# Ractor.make_shareable(obj, copy: true) makes copied shareable object.
+assert_equal '[false, false, true, true]', %q{
+  r = []
+  o1 = [1, 2, ["3"]]
+
+  o2 = Ractor.make_shareable(o1, copy: true)
+  r << Ractor.shareable?(o1) # false
+  r << (o1.object_id == o2.object_id) # false
+
+  o3 = Ractor.make_shareable(o1)
+  r << Ractor.shareable?(o1) # true
+  r << (o1.object_id == o3.object_id) # false
+  r
+}
+
+
 # Ractor deep copies frozen objects (ary)
 assert_equal '[true, false]', %q{
   Ractor.new([[]].freeze) { |ary|
diff --git a/ractor.c b/ractor.c
index 89b4f68..0d850ae 100644
--- a/ractor.c
+++ b/ractor.c
@@ -2347,6 +2347,16 @@ rb_ractor_make_shareable(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2347
     return obj;
 }
 
+VALUE
+rb_ractor_make_copy_shareable(VALUE obj)
+{
+    VALUE copy = ractor_copy(obj);
+    rb_obj_traverse(copy,
+                    make_shareable_check_shareable,
+                    null_leave, mark_shareable);
+    return copy;
+}
+
 static enum obj_traverse_iterator_result
 shareable_p_enter(VALUE obj)
 {
diff --git a/ractor.rb b/ractor.rb
index 2196a93..e4fbdfe 100644
--- a/ractor.rb
+++ b/ractor.rb
@@ -214,9 +214,28 @@ class Ractor https://github.com/ruby/ruby/blob/trunk/ractor.rb#L214
     }
   end
 
-  def self.make_shareable obj
-    __builtin_cexpr! %q{
-      rb_ractor_make_shareable(obj);
-    }
+  # make obj sharable.
+  #
+  # Basically, traverse referring objects from obj and freeze them.
+  # 
+  # When a sharable object is found in traversing, stop traversing
+  # from this shareable object.
+  #
+  # If copy keyword is true, it makes a deep copied object
+  # and make it sharable. This is safer option (but it can take more time).
+  #
+  # Note that the specification and implementation of this method are not
+  # matured and can be changed in a future.
+  #
+  def self.make_shareable obj, copy: false
+    if copy
+      __builtin_cexpr! %q{
+        rb_ractor_make_copy_shareable(obj);
+      }
+    else
+      __builtin_cexpr! %q{
+        rb_ractor_make_shareable(obj);
+      }
+    end
   end
 end
-- 
cgit v0.10.2


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

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