Fix rb_eSystemExit raised in Ractor

[Bug #21505]

Previously `Ractor.new { exit }.join` would hang because SystemExit was
special cased.

This commit updates this to take the same path as other exceptions,
which wraps the exception in a Ractor::RemoteError and does not end up
exiting the main Ractor. I don't know if that's what this should do, but
I think it's a reasonable behaviour as calling exit() in a Ractor is
odd.

    in 'Ractor#join': thrown by remote Ractor. (Ractor::RemoteError)
       from -e:1:in '<main>'
    in 'Kernel#exit': exit (SystemExit)
            from -e:1:in 'block in <main>'
This commit is contained in:
John Hawthorn 2025-07-09 13:25:53 -07:00
parent 470e11a411
commit 6c66458070
2 changed files with 30 additions and 0 deletions

View file

@ -358,6 +358,32 @@ assert_equal 'ok', %q{
r.value
}
# SystemExit from a Ractor is re-raised
# [Bug #21505]
assert_equal '[SystemExit, "exit", true]', %q{
r = Ractor.new { exit }
begin
r.value
rescue Ractor::RemoteError => e
[e.cause.class, #=> RuntimeError
e.cause.message, #=> 'ok'
e.ractor == r] #=> true
end
}
# SystemExit from a Thread inside a Ractor is re-raised
# [Bug #21505]
assert_equal '[SystemExit, "exit", true]', %q{
r = Ractor.new { Thread.new { exit }.join }
begin
r.value
rescue Ractor::RemoteError => e
[e.cause.class, #=> RuntimeError
e.cause.message, #=> 'ok'
e.ractor == r] #=> true
end
}
# threads in a ractor will killed
assert_equal '{ok: 3}', %q{
Ractor.new Ractor.current do |main|

View file

@ -703,6 +703,10 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start)
/* fatal error within this thread, need to stop whole script */
}
else if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
if (th->invoke_type == thread_invoke_type_ractor_proc) {
rb_ractor_atexit_exception(th->ec);
}
/* exit on main_thread. */
}
else {