From 182fb73c40351f917bf44626c44c1adb6cb1aa5a Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Mon, 30 Nov 2020 16:18:43 +0900 Subject: rb_ext_ractor_safe() to declare ractor-safe ext C extensions can violate the ractor-safety, so only ractor-safe C extensions (C methods) can run on non-main ractors. rb_ext_ractor_safe(true) declares that the successive defined methods are ractor-safe. Otherwiwze, defined methods checked they are invoked in main ractor and raise an error if invoked at non-main ractors. [Feature #17307] --- include/ruby/internal/intern/load.h | 4 + load.c | 26 ++++++ ractor.c | 2 + vm.c | 1 + vm_core.h | 8 ++ vm_insnhelper.c | 165 ++++++++++++++++++++++++++++++++++++ vm_method.c | 68 ++++++++++----- 7 files changed, 253 insertions(+), 21 deletions(-) diff --git a/include/ruby/internal/intern/load.h b/include/ruby/internal/intern/load.h index b4c42a0f54..f9ba542ded 100644 --- a/include/ruby/internal/intern/load.h +++ b/include/ruby/internal/intern/load.h @@ -34,6 +34,10 @@ void rb_provide(const char*); VALUE rb_f_require(VALUE, VALUE); VALUE rb_require_string(VALUE); +// extension configuration +void rb_ext_ractor_safe(bool flag); +#define RB_EXT_RACTOR_SAFE(f) rb_ext_ractor_safe(f) + RBIMPL_SYMBOL_EXPORT_END() #endif /* RBIMPL_INTERN_LOAD_H */ diff --git a/load.c b/load.c index 00ae31e705..1c17587c47 100644 --- a/load.c +++ b/load.c @@ -997,6 +997,25 @@ rb_resolve_feature_path(VALUE klass, VALUE fname) return rb_ary_new_from_args(2, sym, path); } +static void +ext_config_push(rb_thread_t *th, struct rb_ext_config *prev) +{ + *prev = th->ext_config; + th->ext_config = (struct rb_ext_config){0}; +} + +static void +ext_config_pop(rb_thread_t *th, struct rb_ext_config *prev) +{ + th->ext_config = *prev; +} + +void +rb_ext_ractor_safe(bool flag) +{ + GET_THREAD()->ext_config.ractor_safe = flag; +} + /* * returns * 0: if already loaded (false) @@ -1015,6 +1034,8 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception) enum ruby_tag_type state; char *volatile ftptr = 0; VALUE path; + volatile bool reset_ext_config = false; + struct rb_ext_config prev_ext_config; fname = rb_get_path(fname); path = rb_str_encode_ospath(fname); @@ -1045,6 +1066,8 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception) break; case 's': + reset_ext_config = true; + ext_config_push(th, &prev_ext_config); handle = (long)rb_vm_call_cfunc(rb_vm_top_self(), load_ext, path, VM_BLOCK_HANDLER_NONE, path); rb_ary_push(ruby_dln_librefs, LONG2NUM(handle)); @@ -1055,9 +1078,12 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception) } } EC_POP_TAG(); + th = rb_ec_thread_ptr(ec); th->top_self = self; th->top_wrapper = wrapper; + if (reset_ext_config) ext_config_pop(th, &prev_ext_config); + if (ftptr) load_unlock(RSTRING_PTR(path), !state); if (state) { diff --git a/ractor.c b/ractor.c index 693bbe274d..c895aab980 100644 --- a/ractor.c +++ b/ractor.c @@ -21,6 +21,7 @@ static VALUE rb_eRactorRemoteError; static VALUE rb_eRactorMovedError; static VALUE rb_eRactorClosedError; static VALUE rb_cRactorMovedObject; +VALUE rb_eRactorUnsafeError; VALUE rb_ractor_error_class(void) @@ -1670,6 +1671,7 @@ Init_Ractor(void) rb_eRactorRemoteError = rb_define_class_under(rb_cRactor, "RemoteError", rb_eRactorError); rb_eRactorMovedError = rb_define_class_under(rb_cRactor, "MovedError", rb_eRactorError); rb_eRactorClosedError = rb_define_class_under(rb_cRactor, "ClosedError", rb_eStopIteration); + rb_eRactorUnsafeError = rb_define_class_under(rb_cRactor, "UnsafeError", rb_eRactorError); rb_cRactorMovedObject = rb_define_class_under(rb_cRactor, "MovedObject", rb_cBasicObject); rb_undef_alloc_func(rb_cRactorMovedObject); diff --git a/vm.c b/vm.c index 9114ba456c..1e1c06e0e2 100644 --- a/vm.c +++ b/vm.c @@ -3052,6 +3052,7 @@ th_init(rb_thread_t *th, VALUE self) #endif th->name = Qnil; th->report_on_exception = th->vm->thread_report_on_exception; + th->ext_config.ractor_safe = true; } static VALUE diff --git a/vm_core.h b/vm_core.h index 53bf67c2e5..5ddd7b4b4f 100644 --- a/vm_core.h +++ b/vm_core.h @@ -912,6 +912,10 @@ void rb_ec_initialize_vm_stack(rb_execution_context_t *ec, VALUE *stack, size_t // @param ec the execution context to update. void rb_ec_clear_vm_stack(rb_execution_context_t *ec); +struct rb_ext_config { + bool ractor_safe; +}; + typedef struct rb_ractor_struct rb_ractor_t; typedef struct rb_thread_struct { @@ -1000,6 +1004,8 @@ typedef struct rb_thread_struct { /* misc */ VALUE name; + struct rb_ext_config ext_config; + #ifdef USE_SIGALTSTACK void *altstack; #endif @@ -1994,6 +2000,8 @@ extern void rb_reset_coverages(void); void rb_postponed_job_flush(rb_vm_t *vm); +extern VALUE rb_eRactorUnsafeError; // ractor.c + RUBY_SYMBOL_EXPORT_END #endif /* RUBY_VM_CORE_H */ diff --git a/vm_insnhelper.c b/vm_insnhelper.c index b6ad18cd51..e6282ca668 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2469,110 +2469,275 @@ vm_call_iseq_setup_tailcall(rb_execution_context_t *ec, rb_control_frame_t *cfp, return Qundef; } +static void +ractor_unsafe_check(void) +{ + if (!rb_ractor_main_p()) { + rb_raise(rb_eRactorUnsafeError, "ractor unsafe method called from not main ractor"); + } +} + static VALUE call_cfunc_m2(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); return (*func)(recv, rb_ary_new4(argc, argv)); } static VALUE call_cfunc_m1(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); return (*func)(argc, argv, recv); } static VALUE call_cfunc_0(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE) = (VALUE(*)(VALUE))func; return (*f)(recv); } + static VALUE call_cfunc_1(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE) = (VALUE(*)(VALUE, VALUE))func; return (*f)(recv, argv[0]); } + static VALUE call_cfunc_2(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1]); } + static VALUE call_cfunc_3(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2]); } + static VALUE call_cfunc_4(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3]); } + static VALUE call_cfunc_5(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]); } + static VALUE call_cfunc_6(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); } + static VALUE call_cfunc_7(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); } + static VALUE call_cfunc_8(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]); } + static VALUE call_cfunc_9(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]); } + static VALUE call_cfunc_10(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]); } + static VALUE call_cfunc_11(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]); } + static VALUE call_cfunc_12(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11]); } + static VALUE call_cfunc_13(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12]); } + static VALUE call_cfunc_14(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { + ractor_unsafe_check(); VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]); } + static VALUE call_cfunc_15(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + ractor_unsafe_check(); + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14]); +} + +static VALUE +ractor_safe_call_cfunc_m2(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + return (*func)(recv, rb_ary_new4(argc, argv)); +} + +static VALUE +ractor_safe_call_cfunc_m1(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + return (*func)(argc, argv, recv); +} + +static VALUE +ractor_safe_call_cfunc_0(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE) = (VALUE(*)(VALUE))func; + return (*f)(recv); +} + +static VALUE +ractor_safe_call_cfunc_1(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE) = (VALUE(*)(VALUE, VALUE))func; + return (*f)(recv, argv[0]); +} + +static VALUE +ractor_safe_call_cfunc_2(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1]); +} + +static VALUE +ractor_safe_call_cfunc_3(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2]); +} + +static VALUE +ractor_safe_call_cfunc_4(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3]); +} + +static VALUE +ractor_safe_call_cfunc_5(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]); +} + +static VALUE +ractor_safe_call_cfunc_6(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); +} + +static VALUE +ractor_safe_call_cfunc_7(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); +} + +static VALUE +ractor_safe_call_cfunc_8(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]); +} + +static VALUE +ractor_safe_call_cfunc_9(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]); +} + +static VALUE +ractor_safe_call_cfunc_10(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]); +} + +static VALUE +ractor_safe_call_cfunc_11(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]); +} + +static VALUE +ractor_safe_call_cfunc_12(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11]); +} + +static VALUE +ractor_safe_call_cfunc_13(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12]); +} + +static VALUE +ractor_safe_call_cfunc_14(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) +{ + VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; + return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]); +} + +static VALUE +ractor_safe_call_cfunc_15(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS)) { VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func; return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14]); diff --git a/vm_method.c b/vm_method.c index a143db7cc5..6845ad44f0 100644 --- a/vm_method.c +++ b/vm_method.c @@ -347,27 +347,53 @@ extern int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_me static VALUE (*call_cfunc_invoker_func(int argc))(VALUE recv, int argc, const VALUE *, VALUE (*func)(ANYARGS)) { - switch (argc) { - case -2: return &call_cfunc_m2; - case -1: return &call_cfunc_m1; - case 0: return &call_cfunc_0; - case 1: return &call_cfunc_1; - case 2: return &call_cfunc_2; - case 3: return &call_cfunc_3; - case 4: return &call_cfunc_4; - case 5: return &call_cfunc_5; - case 6: return &call_cfunc_6; - case 7: return &call_cfunc_7; - case 8: return &call_cfunc_8; - case 9: return &call_cfunc_9; - case 10: return &call_cfunc_10; - case 11: return &call_cfunc_11; - case 12: return &call_cfunc_12; - case 13: return &call_cfunc_13; - case 14: return &call_cfunc_14; - case 15: return &call_cfunc_15; - default: - rb_bug("call_cfunc_func: unsupported length: %d", argc); + if (!GET_THREAD()->ext_config.ractor_safe) { + switch (argc) { + case -2: return &call_cfunc_m2; + case -1: return &call_cfunc_m1; + case 0: return &call_cfunc_0; + case 1: return &call_cfunc_1; + case 2: return &call_cfunc_2; + case 3: return &call_cfunc_3; + case 4: return &call_cfunc_4; + case 5: return &call_cfunc_5; + case 6: return &call_cfunc_6; + case 7: return &call_cfunc_7; + case 8: return &call_cfunc_8; + case 9: return &call_cfunc_9; + case 10: return &call_cfunc_10; + case 11: return &call_cfunc_11; + case 12: return &call_cfunc_12; + case 13: return &call_cfunc_13; + case 14: return &call_cfunc_14; + case 15: return &call_cfunc_15; + default: + rb_bug("unsupported length: %d", argc); + } + } + else { + switch (argc) { + case -2: return &ractor_safe_call_cfunc_m2; + case -1: return &ractor_safe_call_cfunc_m1; + case 0: return &ractor_safe_call_cfunc_0; + case 1: return &ractor_safe_call_cfunc_1; + case 2: return &ractor_safe_call_cfunc_2; + case 3: return &ractor_safe_call_cfunc_3; + case 4: return &ractor_safe_call_cfunc_4; + case 5: return &ractor_safe_call_cfunc_5; + case 6: return &ractor_safe_call_cfunc_6; + case 7: return &ractor_safe_call_cfunc_7; + case 8: return &ractor_safe_call_cfunc_8; + case 9: return &ractor_safe_call_cfunc_9; + case 10: return &ractor_safe_call_cfunc_10; + case 11: return &ractor_safe_call_cfunc_11; + case 12: return &ractor_safe_call_cfunc_12; + case 13: return &ractor_safe_call_cfunc_13; + case 14: return &ractor_safe_call_cfunc_14; + case 15: return &ractor_safe_call_cfunc_15; + default: + rb_bug("unsupported length: %d", argc); + } } } -- cgit v1.2.3