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.
This commit is contained in:
parent
cee02d754d
commit
80cb9165fa
@ -1176,6 +1176,22 @@ assert_equal 'can not make a Proc shareable because it accesses outer variables
|
|||||||
end
|
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)
|
# Ractor deep copies frozen objects (ary)
|
||||||
assert_equal '[true, false]', %q{
|
assert_equal '[true, false]', %q{
|
||||||
Ractor.new([[]].freeze) { |ary|
|
Ractor.new([[]].freeze) { |ary|
|
||||||
|
10
ractor.c
10
ractor.c
@ -2347,6 +2347,16 @@ rb_ractor_make_shareable(VALUE obj)
|
|||||||
return obj;
|
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
|
static enum obj_traverse_iterator_result
|
||||||
shareable_p_enter(VALUE obj)
|
shareable_p_enter(VALUE obj)
|
||||||
{
|
{
|
||||||
|
27
ractor.rb
27
ractor.rb
@ -214,9 +214,28 @@ class Ractor
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.make_shareable obj
|
# make obj sharable.
|
||||||
__builtin_cexpr! %q{
|
#
|
||||||
rb_ractor_make_shareable(obj);
|
# 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
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user