1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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:
Koichi Sasada 2020-12-19 05:52:18 +09:00
parent cee02d754d
commit 80cb9165fa
3 changed files with 49 additions and 4 deletions

View file

@ -1176,6 +1176,22 @@ assert_equal 'can not make a Proc shareable because it accesses outer variables
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)
assert_equal '[true, false]', %q{
Ractor.new([[]].freeze) { |ary|

View file

@ -2347,6 +2347,16 @@ rb_ractor_make_shareable(VALUE 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
shareable_p_enter(VALUE obj)
{

View file

@ -214,9 +214,28 @@ class Ractor
}
end
def self.make_shareable obj
# make obj sharable.
#
# 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