From aa63699d10e489bc6d9c13406fc47f581001568b Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Tue, 5 Nov 2024 04:54:06 +0900 Subject: support `require` in non-main Ractors Many libraries should be loaded on the main ractor because of setting constants with unshareable objects and so on. This patch allows to call `requore` on non-main Ractors by asking the main ractor to call `require` on it. The calling ractor waits for the result of `require` from the main ractor. If the `require` call failed with some reasons, an exception objects will be deliverred from the main ractor to the calling ractor if it is copy-able. Same on `require_relative` and `require` by `autoload`. Now `Ractor.new{pp obj}` works well (the first call of `pp` requires `pp` library implicitly). [Feature #20627] --- load.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'load.c') diff --git a/load.c b/load.c index c1862c38fa..e4dd1e47ba 100644 --- a/load.c +++ b/load.c @@ -18,6 +18,7 @@ #include "darray.h" #include "ruby/encoding.h" #include "ruby/util.h" +#include "ractor_core.h" static VALUE ruby_dln_libmap; @@ -1383,17 +1384,25 @@ static VALUE rb_require_string_internal(VALUE fname, bool resurrect) { rb_execution_context_t *ec = GET_EC(); - int result = require_internal(ec, fname, 1, RTEST(ruby_verbose)); - if (result > TAG_RETURN) { - EC_JUMP_TAG(ec, result); - } - if (result < 0) { + // main ractor check + if (!rb_ractor_main_p()) { if (resurrect) fname = rb_str_resurrect(fname); - load_failed(fname); + return rb_ractor_require(fname); } + else { + int result = require_internal(ec, fname, 1, RTEST(ruby_verbose)); + + if (result > TAG_RETURN) { + EC_JUMP_TAG(ec, result); + } + if (result < 0) { + if (resurrect) fname = rb_str_resurrect(fname); + load_failed(fname); + } - return RBOOL(result); + return RBOOL(result); + } } VALUE -- cgit v1.2.3