Fixed Ractor.shareable? on cross-recursive objects [Bug #17344]
This commit is contained in:
parent
555bd83a8e
commit
930a135524
Notes:
git
2020-11-30 16:08:06 +09:00
Merged: https://github.com/ruby/ruby/pull/3823 Merged-By: nobu <nobu@ruby-lang.org>
@ -975,6 +975,15 @@ assert_equal 'true', %q{
|
|||||||
Ractor.shareable?(pr)
|
Ractor.shareable?(pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ractor.shareable?(recursive_objects)
|
||||||
|
assert_equal '[false, false]', %q{
|
||||||
|
y = []
|
||||||
|
x = [y, {}].freeze
|
||||||
|
y << x
|
||||||
|
y.freeze
|
||||||
|
[Ractor.shareable?(x), Ractor.shareable?(y)]
|
||||||
|
}
|
||||||
|
|
||||||
# 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
|
||||||
|
38
ractor.c
38
ractor.c
@ -1805,6 +1805,9 @@ enum obj_traverse_iterator_result {
|
|||||||
|
|
||||||
typedef enum obj_traverse_iterator_result (*rb_obj_traverse_enter_func)(VALUE obj);
|
typedef enum obj_traverse_iterator_result (*rb_obj_traverse_enter_func)(VALUE obj);
|
||||||
typedef enum obj_traverse_iterator_result (*rb_obj_traverse_leave_func)(VALUE obj);
|
typedef enum obj_traverse_iterator_result (*rb_obj_traverse_leave_func)(VALUE obj);
|
||||||
|
typedef enum obj_traverse_iterator_result (*rb_obj_traverse_final_func)(VALUE obj);
|
||||||
|
|
||||||
|
static enum obj_traverse_iterator_result null_leave(VALUE obj);
|
||||||
|
|
||||||
struct obj_traverse_data {
|
struct obj_traverse_data {
|
||||||
rb_obj_traverse_enter_func enter_func;
|
rb_obj_traverse_enter_func enter_func;
|
||||||
@ -1979,12 +1982,29 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct rb_obj_traverse_final_data {
|
||||||
|
rb_obj_traverse_final_func final_func;
|
||||||
|
int stopped;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
obj_traverse_final_i(st_data_t key, st_data_t val, st_data_t arg)
|
||||||
|
{
|
||||||
|
struct rb_obj_traverse_final_data *data = (void *)arg;
|
||||||
|
if (data->final_func(key)) {
|
||||||
|
data->stopped = 1;
|
||||||
|
return ST_STOP;
|
||||||
|
}
|
||||||
|
return ST_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
// 0: traverse all
|
// 0: traverse all
|
||||||
// 1: stopped
|
// 1: stopped
|
||||||
static int
|
static int
|
||||||
rb_obj_traverse(VALUE obj,
|
rb_obj_traverse(VALUE obj,
|
||||||
rb_obj_traverse_enter_func enter_func,
|
rb_obj_traverse_enter_func enter_func,
|
||||||
rb_obj_traverse_leave_func leave_func)
|
rb_obj_traverse_leave_func leave_func,
|
||||||
|
rb_obj_traverse_final_func final_func)
|
||||||
{
|
{
|
||||||
struct obj_traverse_data data = {
|
struct obj_traverse_data data = {
|
||||||
.enter_func = enter_func,
|
.enter_func = enter_func,
|
||||||
@ -1992,7 +2012,13 @@ rb_obj_traverse(VALUE obj,
|
|||||||
.rec = NULL,
|
.rec = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
return obj_traverse_i(obj, &data);
|
if (obj_traverse_i(obj, &data)) return 1;
|
||||||
|
if (final_func && data.rec) {
|
||||||
|
struct rb_obj_traverse_final_data f = {final_func, 0};
|
||||||
|
st_foreach(data.rec, obj_traverse_final_i, (st_data_t)&f);
|
||||||
|
return f.stopped;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -2063,7 +2089,7 @@ rb_ractor_make_shareable(VALUE obj)
|
|||||||
{
|
{
|
||||||
rb_obj_traverse(obj,
|
rb_obj_traverse(obj,
|
||||||
make_shareable_check_shareable,
|
make_shareable_check_shareable,
|
||||||
mark_shareable);
|
mark_shareable, mark_shareable);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2092,7 +2118,7 @@ MJIT_FUNC_EXPORTED bool
|
|||||||
rb_ractor_shareable_p_continue(VALUE obj)
|
rb_ractor_shareable_p_continue(VALUE obj)
|
||||||
{
|
{
|
||||||
if (rb_obj_traverse(obj,
|
if (rb_obj_traverse(obj,
|
||||||
shareable_p_enter,
|
shareable_p_enter, null_leave,
|
||||||
mark_shareable)) {
|
mark_shareable)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2113,20 +2139,20 @@ reset_belonging_enter(VALUE obj)
|
|||||||
return traverse_cont;
|
return traverse_cont;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static enum obj_traverse_iterator_result
|
static enum obj_traverse_iterator_result
|
||||||
null_leave(VALUE obj)
|
null_leave(VALUE obj)
|
||||||
{
|
{
|
||||||
return traverse_cont;
|
return traverse_cont;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
ractor_reset_belonging(VALUE obj)
|
ractor_reset_belonging(VALUE obj)
|
||||||
{
|
{
|
||||||
#if RACTOR_CHECK_MODE > 0
|
#if RACTOR_CHECK_MODE > 0
|
||||||
rp(obj);
|
rp(obj);
|
||||||
rb_obj_traverse(obj, reset_belonging_enter, null_leave);
|
rb_obj_traverse(obj, reset_belonging_enter, null_leave, NULL);
|
||||||
#endif
|
#endif
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user