зеркало из https://github.com/github/ruby.git
[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>
This commit is contained in:
Родитель
b62ed309f0
Коммит
bbedd29b6e
|
@ -1418,4 +1418,19 @@ assert_equal "ok", %q{
|
||||||
'ok'
|
'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']
|
end # if !ENV['GITHUB_WORKFLOW']
|
||||||
|
|
12
ractor.c
12
ractor.c
|
@ -2368,7 +2368,11 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
|
||||||
.stop = false,
|
.stop = false,
|
||||||
.data = data,
|
.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;
|
if (d.stop) return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2678,7 +2682,11 @@ static int
|
||||||
obj_refer_only_shareables_p(VALUE obj)
|
obj_refer_only_shareables_p(VALUE obj)
|
||||||
{
|
{
|
||||||
int cnt = 0;
|
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;
|
return cnt == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче