mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Disallow forking from non-main ractor
[Bug #17516] `fork(2)` only leave the calling thread alive in the child. Because of this forking from the non-main ractor can easily leave the VM in a corrupted state. It may be possible in the future to carefully allow forking from non-main Ractor, but shot term it's preferable to add this restriction.
This commit is contained in:
parent
45a2c95d0f
commit
5bcc639b34
3 changed files with 17 additions and 0 deletions
|
@ -14057,6 +14057,7 @@ process.$(OBJEXT): {$(VPATH)}onigmo.h
|
||||||
process.$(OBJEXT): {$(VPATH)}oniguruma.h
|
process.$(OBJEXT): {$(VPATH)}oniguruma.h
|
||||||
process.$(OBJEXT): {$(VPATH)}process.c
|
process.$(OBJEXT): {$(VPATH)}process.c
|
||||||
process.$(OBJEXT): {$(VPATH)}ractor.h
|
process.$(OBJEXT): {$(VPATH)}ractor.h
|
||||||
|
process.$(OBJEXT): {$(VPATH)}ractor_core.h
|
||||||
process.$(OBJEXT): {$(VPATH)}ruby_assert.h
|
process.$(OBJEXT): {$(VPATH)}ruby_assert.h
|
||||||
process.$(OBJEXT): {$(VPATH)}ruby_atomic.h
|
process.$(OBJEXT): {$(VPATH)}ruby_atomic.h
|
||||||
process.$(OBJEXT): {$(VPATH)}rubyparser.h
|
process.$(OBJEXT): {$(VPATH)}rubyparser.h
|
||||||
|
|
|
@ -114,6 +114,7 @@ int initgroups(const char *, rb_gid_t);
|
||||||
#include "ruby/st.h"
|
#include "ruby/st.h"
|
||||||
#include "ruby/thread.h"
|
#include "ruby/thread.h"
|
||||||
#include "ruby/util.h"
|
#include "ruby/util.h"
|
||||||
|
#include "ractor_core.h"
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
#include "vm_sync.h"
|
#include "vm_sync.h"
|
||||||
#include "ruby/ractor.h"
|
#include "ruby/ractor.h"
|
||||||
|
@ -4120,6 +4121,10 @@ rb_fork_async_signal_safe(int *status,
|
||||||
rb_pid_t
|
rb_pid_t
|
||||||
rb_fork_ruby(int *status)
|
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};
|
struct rb_process_status child = {.status = 0};
|
||||||
rb_pid_t pid;
|
rb_pid_t pid;
|
||||||
int try_gc = 1, err = 0;
|
int try_gc = 1, err = 0;
|
||||||
|
|
|
@ -99,6 +99,17 @@ class TestRactor < Test::Unit::TestCase
|
||||||
RUBY
|
RUBY
|
||||||
end
|
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
|
def test_require_raises_and_no_ractor_belonging_issue
|
||||||
assert_ractor(<<~'RUBY')
|
assert_ractor(<<~'RUBY')
|
||||||
require "tempfile"
|
require "tempfile"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue