diff --git a/common.mk b/common.mk index e5a4d34a0a..002f5dcef7 100644 --- a/common.mk +++ b/common.mk @@ -14057,6 +14057,7 @@ process.$(OBJEXT): {$(VPATH)}onigmo.h process.$(OBJEXT): {$(VPATH)}oniguruma.h process.$(OBJEXT): {$(VPATH)}process.c process.$(OBJEXT): {$(VPATH)}ractor.h +process.$(OBJEXT): {$(VPATH)}ractor_core.h process.$(OBJEXT): {$(VPATH)}ruby_assert.h process.$(OBJEXT): {$(VPATH)}ruby_atomic.h process.$(OBJEXT): {$(VPATH)}rubyparser.h diff --git a/process.c b/process.c index 2938411c43..da9ce74027 100644 --- a/process.c +++ b/process.c @@ -114,6 +114,7 @@ int initgroups(const char *, rb_gid_t); #include "ruby/st.h" #include "ruby/thread.h" #include "ruby/util.h" +#include "ractor_core.h" #include "vm_core.h" #include "vm_sync.h" #include "ruby/ractor.h" @@ -4120,6 +4121,10 @@ rb_fork_async_signal_safe(int *status, rb_pid_t rb_fork_ruby(int *status) { + if (UNLIKELY(!rb_ractor_main_p())) { + rb_raise(rb_eRactorIsolationError, "can not fork from non-main Ractors"); + } + struct rb_process_status child = {.status = 0}; rb_pid_t pid; int try_gc = 1, err = 0; diff --git a/test/ruby/test_ractor.rb b/test/ruby/test_ractor.rb index 3fc891da23..97af7e7413 100644 --- a/test/ruby/test_ractor.rb +++ b/test/ruby/test_ractor.rb @@ -99,6 +99,17 @@ class TestRactor < Test::Unit::TestCase RUBY end + def test_fork_raise_isolation_error + assert_ractor(<<~'RUBY') + ractor = Ractor.new do + Process.fork + rescue Ractor::IsolationError => e + e + end + assert_equal Ractor::IsolationError, ractor.value.class + RUBY + end if Process.respond_to?(:fork) + def test_require_raises_and_no_ractor_belonging_issue assert_ractor(<<~'RUBY') require "tempfile"