diff options
author | Koichi Sasada <ko1@atdot.net> | 2020-11-06 03:21:08 +0900 |
---|---|---|
committer | Koichi Sasada <ko1@atdot.net> | 2020-11-06 16:14:36 +0900 |
commit | 7718e9588b4d7d83c8f9a89dce10b06b9f97bddb (patch) | |
tree | c0b36eacc0bf05cefb617c14843d34277648dc5d /ractor.c | |
parent | 4948982b53ef18d367738ede6a32df46353cb9a7 (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.c | 26 |
1 files changed, 26 insertions, 0 deletions
@@ -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; |