зеркало из https://github.com/github/ruby.git
prohibi method call by defined_method in other racotrs
We can not call a non-isolated Proc in multiple ractors.
This commit is contained in:
Родитель
890bc2cdde
Коммит
caaa36b4e6
|
@ -724,6 +724,17 @@ assert_equal 'can not set constants with non-shareable objects by non-main Racto
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# define_method is not allowed
|
||||||
|
assert_equal "defined in a different Ractor", %q{
|
||||||
|
str = "foo"
|
||||||
|
define_method(:buggy){|i| str << "#{i}"}
|
||||||
|
begin
|
||||||
|
Ractor.new{buggy(10)}.take
|
||||||
|
rescue => e
|
||||||
|
e.cause.message
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
# Immutable Array and Hash are shareable, so it can be shared with constants
|
# Immutable Array and Hash are shareable, so it can be shared with constants
|
||||||
assert_equal '[1000, 3]', %q{
|
assert_equal '[1000, 3]', %q{
|
||||||
A = Array.new(1000).freeze # [nil, ...]
|
A = Array.new(1000).freeze # [nil, ...]
|
||||||
|
|
1
method.h
1
method.h
|
@ -159,6 +159,7 @@ typedef struct rb_method_refined_struct {
|
||||||
typedef struct rb_method_bmethod_struct {
|
typedef struct rb_method_bmethod_struct {
|
||||||
VALUE proc; /* should be marked */
|
VALUE proc; /* should be marked */
|
||||||
struct rb_hook_list_struct *hooks;
|
struct rb_hook_list_struct *hooks;
|
||||||
|
VALUE defined_ractor;
|
||||||
} rb_method_bmethod_t;
|
} rb_method_bmethod_t;
|
||||||
|
|
||||||
enum method_optimized_type {
|
enum method_optimized_type {
|
||||||
|
|
|
@ -2667,9 +2667,14 @@ vm_call_bmethod_body(rb_execution_context_t *ec, struct rb_calling_info *calling
|
||||||
rb_proc_t *proc;
|
rb_proc_t *proc;
|
||||||
VALUE val;
|
VALUE val;
|
||||||
const struct rb_callcache *cc = cd->cc;
|
const struct rb_callcache *cc = cd->cc;
|
||||||
|
const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
|
||||||
|
|
||||||
|
if (cme->def->body.bmethod.defined_ractor != rb_ec_ractor_ptr(ec)->self) {
|
||||||
|
rb_raise(rb_eRuntimeError, "defined in a different Ractor");
|
||||||
|
}
|
||||||
|
|
||||||
/* control block frame */
|
/* control block frame */
|
||||||
GetProcPtr(vm_cc_cme(cc)->def->body.bmethod.proc, proc);
|
GetProcPtr(cme->def->body.bmethod.proc, proc);
|
||||||
val = rb_vm_invoke_bmethod(ec, proc, calling->recv, calling->argc, argv, calling->kw_splat, calling->block_handler, vm_cc_cme(cc));
|
val = rb_vm_invoke_bmethod(ec, proc, calling->recv, calling->argc, argv, calling->kw_splat, calling->block_handler, vm_cc_cme(cc));
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
|
|
|
@ -430,6 +430,7 @@ rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *de
|
||||||
}
|
}
|
||||||
case VM_METHOD_TYPE_BMETHOD:
|
case VM_METHOD_TYPE_BMETHOD:
|
||||||
RB_OBJ_WRITE(me, &def->body.bmethod.proc, (VALUE)opts);
|
RB_OBJ_WRITE(me, &def->body.bmethod.proc, (VALUE)opts);
|
||||||
|
RB_OBJ_WRITE(me, &def->body.bmethod.defined_ractor, GET_THREAD()->ractor->self);
|
||||||
return;
|
return;
|
||||||
case VM_METHOD_TYPE_NOTIMPLEMENTED:
|
case VM_METHOD_TYPE_NOTIMPLEMENTED:
|
||||||
setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), rb_f_notimplement, -1);
|
setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), rb_f_notimplement, -1);
|
||||||
|
@ -471,6 +472,7 @@ method_definition_reset(const rb_method_entry_t *me)
|
||||||
break;
|
break;
|
||||||
case VM_METHOD_TYPE_BMETHOD:
|
case VM_METHOD_TYPE_BMETHOD:
|
||||||
RB_OBJ_WRITTEN(me, Qundef, def->body.bmethod.proc);
|
RB_OBJ_WRITTEN(me, Qundef, def->body.bmethod.proc);
|
||||||
|
RB_OBJ_WRITTEN(me, Qundef, def->body.bmethod.defined_ractor);
|
||||||
/* give up to check all in a list */
|
/* give up to check all in a list */
|
||||||
if (def->body.bmethod.hooks) rb_gc_writebarrier_remember((VALUE)me);
|
if (def->body.bmethod.hooks) rb_gc_writebarrier_remember((VALUE)me);
|
||||||
break;
|
break;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче