Ractor.make_shareable(proc_obj) makes inner structure shareable
Proc objects are now traversed like other objects when making them shareable. Fixes [Bug #19372] Fixes [Bug #19374]
This commit is contained in:
parent
2183899fd1
commit
d80f3a287c
Notes:
git
2025-03-26 23:05:18 +00:00
@ -1361,6 +1361,28 @@ assert_equal 'true', %q{
|
|||||||
Ractor.shareable?(pr)
|
Ractor.shareable?(pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ractor.make_shareable(a_proc) makes inner structure shareable and freezes it
|
||||||
|
assert_equal 'true,true,true,true', %q{
|
||||||
|
class Proc
|
||||||
|
attr_reader :obj
|
||||||
|
def initialize
|
||||||
|
@obj = Object.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pr = Ractor.current.instance_eval do
|
||||||
|
Proc.new {}
|
||||||
|
end
|
||||||
|
|
||||||
|
results = []
|
||||||
|
Ractor.make_shareable(pr)
|
||||||
|
results << Ractor.shareable?(pr)
|
||||||
|
results << pr.frozen?
|
||||||
|
results << Ractor.shareable?(pr.obj)
|
||||||
|
results << pr.obj.frozen?
|
||||||
|
results.map(&:to_s).join(',')
|
||||||
|
}
|
||||||
|
|
||||||
# Ractor.shareable?(recursive_objects)
|
# Ractor.shareable?(recursive_objects)
|
||||||
assert_equal '[false, false]', %q{
|
assert_equal '[false, false]', %q{
|
||||||
y = []
|
y = []
|
||||||
@ -1389,6 +1411,21 @@ assert_equal '[C, M]', %q{
|
|||||||
Ractor.make_shareable(ary = [C, M])
|
Ractor.make_shareable(ary = [C, M])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ractor.make_shareable with curried proc checks isolation of original proc
|
||||||
|
assert_equal 'isolation error', %q{
|
||||||
|
a = Object.new
|
||||||
|
orig = proc { a }
|
||||||
|
curried = orig.curry
|
||||||
|
|
||||||
|
begin
|
||||||
|
Ractor.make_shareable(curried)
|
||||||
|
rescue Ractor::IsolationError
|
||||||
|
'isolation error'
|
||||||
|
else
|
||||||
|
'no error'
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
# define_method() can invoke different Ractor's proc if the proc is shareable.
|
# define_method() can invoke different Ractor's proc if the proc is shareable.
|
||||||
assert_equal '1', %q{
|
assert_equal '1', %q{
|
||||||
class C
|
class C
|
||||||
|
23
ractor.c
23
ractor.c
@ -3045,7 +3045,7 @@ rb_obj_traverse(VALUE obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
frozen_shareable_p(VALUE obj, bool *made_shareable)
|
allow_frozen_shareable_p(VALUE obj)
|
||||||
{
|
{
|
||||||
if (!RB_TYPE_P(obj, T_DATA)) {
|
if (!RB_TYPE_P(obj, T_DATA)) {
|
||||||
return true;
|
return true;
|
||||||
@ -3055,13 +3055,6 @@ frozen_shareable_p(VALUE obj, bool *made_shareable)
|
|||||||
if (type->flags & RUBY_TYPED_FROZEN_SHAREABLE) {
|
if (type->flags & RUBY_TYPED_FROZEN_SHAREABLE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (made_shareable && rb_obj_is_proc(obj)) {
|
|
||||||
// special path to make shareable Proc.
|
|
||||||
rb_proc_ractor_make_shareable(obj);
|
|
||||||
*made_shareable = true;
|
|
||||||
VM_ASSERT(RB_OBJ_SHAREABLE_P(obj));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -3071,20 +3064,24 @@ static enum obj_traverse_iterator_result
|
|||||||
make_shareable_check_shareable(VALUE obj)
|
make_shareable_check_shareable(VALUE obj)
|
||||||
{
|
{
|
||||||
VM_ASSERT(!SPECIAL_CONST_P(obj));
|
VM_ASSERT(!SPECIAL_CONST_P(obj));
|
||||||
bool made_shareable = false;
|
|
||||||
|
|
||||||
if (rb_ractor_shareable_p(obj)) {
|
if (rb_ractor_shareable_p(obj)) {
|
||||||
return traverse_skip;
|
return traverse_skip;
|
||||||
}
|
}
|
||||||
if (!frozen_shareable_p(obj, &made_shareable)) {
|
else if (!allow_frozen_shareable_p(obj)) {
|
||||||
if (made_shareable) {
|
if (rb_obj_is_proc(obj)) {
|
||||||
return traverse_skip;
|
rb_proc_ractor_make_shareable(obj);
|
||||||
|
return traverse_cont;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rb_raise(rb_eRactorError, "can not make shareable object for %"PRIsVALUE, obj);
|
rb_raise(rb_eRactorError, "can not make shareable object for %"PRIsVALUE, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (RB_TYPE_P(obj, T_IMEMO)) {
|
||||||
|
return traverse_skip;
|
||||||
|
}
|
||||||
|
|
||||||
if (!RB_OBJ_FROZEN_RAW(obj)) {
|
if (!RB_OBJ_FROZEN_RAW(obj)) {
|
||||||
rb_funcall(obj, idFreeze, 0);
|
rb_funcall(obj, idFreeze, 0);
|
||||||
|
|
||||||
@ -3156,7 +3153,7 @@ shareable_p_enter(VALUE obj)
|
|||||||
return traverse_skip;
|
return traverse_skip;
|
||||||
}
|
}
|
||||||
else if (RB_OBJ_FROZEN_RAW(obj) &&
|
else if (RB_OBJ_FROZEN_RAW(obj) &&
|
||||||
frozen_shareable_p(obj, NULL)) {
|
allow_frozen_shareable_p(obj)) {
|
||||||
return traverse_cont;
|
return traverse_cont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user