summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2021-08-17 09:38:40 -0400
committerPeter Zhu <peter@peterzhu.ca>2021-08-24 09:47:42 -0400
commitbbedd29b6e98ef6e3fc2ce2b358d2b509b7cd1bb (patch)
tree2eba0389a85fb60b06fc4c2fe9ba6d57e4117ee0
parentb62ed309f05d248c746279f35f2609f01ea1e4a5 (diff)
[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@shopify.com>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4755
-rw-r--r--bootstraptest/test_ractor.rb15
-rw-r--r--ractor.c12
2 files changed, 25 insertions, 2 deletions
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index 28c9e6d90c..01d02dce77 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -1418,4 +1418,19 @@ assert_equal "ok", %q{
'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 7996d1c275..bf19aa62d3 100644
--- a/ractor.c
+++ b/ractor.c
@@ -2368,7 +2368,11 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
.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
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;
}