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

ruby-changes:67240

From: Peter <ko1@a...>
Date: Tue, 24 Aug 2021 22:48:06 +0900 (JST)
Subject: [ruby-changes:67240] bbedd29b6e (master): [Bug #18117] Fix Ractor race condition with GC

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

From bbedd29b6e98ef6e3fc2ce2b358d2b509b7cd1bb Mon Sep 17 00:00:00 2001
From: Peter Zhu <peter@p...>
Date: Tue, 17 Aug 2021 09:38:40 -0400
Subject: [Bug #18117] Fix Ractor race condition with GC

rb_objspace_reachable_objects_from requires that the GC not be active.
Since the Ractor barrier is not executed for incremental sweeping,
Ractor may call rb_objspace_reachable_objects_from after sweeping
has started to share objects. This causes a crash that looks like
the following:

```
<internal:ractor>:627: [BUG] rb_objspace_reachable_objects_from() is not supported while during_gc == true
```

Co-authored-by: Vinicius Stock <vinicius.stock@s...>
---
 bootstraptest/test_ractor.rb | 15 +++++++++++++++
 ractor.c                     | 12 ++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index 28c9e6d..01d02dc 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -1418,4 +1418,19 @@ assert_equal "ok", %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L1418
   'ok'
 }
 
+# Can yield back values while GC is sweeping [Bug #18117]
+assert_equal "ok", %q{
+  workers = (0...8).map do
+    Ractor.new do
+      loop do
+        10_000.times.map { Object.new }
+        Ractor.yield Time.now
+      end
+    end
+  end
+
+  1_000.times { idle_worker, tmp_reporter = Ractor.select(*workers) }
+  "ok"
+}
+
 end # if !ENV['GITHUB_WORKFLOW']
diff --git a/ractor.c b/ractor.c
index 7996d1c..bf19aa6 100644
--- a/ractor.c
+++ b/ractor.c
@@ -2368,7 +2368,11 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2368
                 .stop = false,
                 .data = data,
             };
-            rb_objspace_reachable_objects_from(obj, obj_traverse_reachable_i, &d);
+            RB_VM_LOCK_ENTER_NO_BARRIER();
+            {
+                rb_objspace_reachable_objects_from(obj, obj_traverse_reachable_i, &d);
+            }
+            RB_VM_LOCK_LEAVE_NO_BARRIER();
             if (d.stop) return 1;
         }
         break;
@@ -2678,7 +2682,11 @@ static int https://github.com/ruby/ruby/blob/trunk/ractor.c#L2682
 obj_refer_only_shareables_p(VALUE obj)
 {
     int cnt = 0;
-    rb_objspace_reachable_objects_from(obj, obj_refer_only_shareables_p_i, &cnt);
+    RB_VM_LOCK_ENTER_NO_BARRIER();
+    {
+        rb_objspace_reachable_objects_from(obj, obj_refer_only_shareables_p_i, &cnt);
+    }
+    RB_VM_LOCK_LEAVE_NO_BARRIER();
     return cnt == 0;
 }
 
-- 
cgit v1.1


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

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