Bug #21505
closed[Ractor] calling exit from non-main ractor will hang if main ractor waits on it
Description
r = Ractor.new do
  exit
end
r.join # hangs
Should exit be allowed in ractors? It would be easiest to disallow, as the code might be tricky if we allow it.
        
          
          Updated by Eregon (Benoit Daloze) 4 months ago
          
          ยท Edited
        
        
      
      Kernel#exit is basically just raise SystemExit, does it mean any exception in a Ractor hangs?
IOW, I don't think it should be disallowed because exit is just an Exception.
        
          
          Updated by luke-gru (Luke Gruber) 4 months ago
          
          
        
        
      
      Yeah fair enough. It's probably not as complicated to fix as I initially thought.
        
          
          Updated by jhawthorn (John Hawthorn) 4 months ago
          
          
        
        
      
      I opened https://github.com/ruby/ruby/pull/13838 which fixes this
./miniruby -e 'Ractor.new { exit }.join'
-e:1: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
-e:1:in 'Ractor#join': thrown by remote Ractor. (Ractor::RemoteError)
        from -e:1:in '<main>'
-e:1:in 'Kernel#exit': exit (SystemExit)
        from -e:1:in 'block in <main>'
In this PR we end up wrapping SystemExit in a Ractor::RemoteError rather than exiting the program. I don't know if that's the most desirable behaviour (versus translating back to SystemExit), but it makes sense to me as calling exit in a Ractor is a bit strange.
        
          
          Updated by jhawthorn (John Hawthorn) 4 months ago
          
          
        
        
      
      - Status changed from Open to Closed
 
Applied in changeset git|6c66458070e2de45213f473ac30b431ebea81b9b.
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>'