summaryrefslogtreecommitdiff
path: root/ractor.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-11-06 03:21:08 +0900
committerKoichi Sasada <ko1@atdot.net>2020-11-06 16:14:36 +0900
commit7718e9588b4d7d83c8f9a89dce10b06b9f97bddb (patch)
treec0b36eacc0bf05cefb617c14843d34277648dc5d /ractor.c
parent4948982b53ef18d367738ede6a32df46353cb9a7 (diff)
a part of T_DATA object can Ractor#send
T_DATA objects can refer unshareable objects and they should be copied recursively, however there is no way to replace with copied unshareable objects. However, if a T_DATA object refers only shareable objects, there is no need to replace. So this kind of T_DATA object (such as Time, Dir, File::Status and so on) can be sent by Ractor.send.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3739
Diffstat (limited to 'ractor.c')
-rw-r--r--ractor.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/ractor.c b/ractor.c
index 5b05d988b0..c30f5ce6c2 100644
--- a/ractor.c
+++ b/ractor.c
@@ -2181,6 +2181,24 @@ void rb_hash_transient_heap_evacuate(VALUE hash, int promote);
void rb_struct_transient_heap_evacuate(VALUE st, int promote);
#endif
+static void
+obj_refer_only_shareables_p_i(VALUE obj, void *ptr)
+{
+ int *pcnt = (int *)ptr;
+
+ if (!rb_ractor_shareable_p(obj)) {
+ pcnt++;
+ }
+}
+
+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);
+ return cnt == 0;
+}
+
static int
obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
{
@@ -2329,6 +2347,14 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
break;
case T_DATA:
+ if (!data->move && obj_refer_only_shareables_p(obj)) {
+ break;
+ }
+ else {
+ rb_raise(rb_eRactorError, "can not %s %"PRIsVALUE" object.",
+ data->move ? "move" : "copy", rb_class_of(obj));
+ }
+
case T_IMEMO:
// not supported yet
return 1;