Bug #17568


Thread.handle_interrupt is per-Thread but should probably be per-Fiber

Added by Eregon (Benoit Daloze) 9 months ago. Updated about 1 month ago.

Target version:
ruby -v:
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]


Thread.handle_interrupt and the pending interrupts is currently kept as state on the thread (rb_thread_t).
However, that seems potentially confusing when Fibers are used.

For instance, this innocent-looking Fiber will forever disable interrupts in the main thread:

main_thread = Thread.current

never_die = do
  Thread.handle_interrupt(RuntimeError => :never) do

begin { main_thread.raise "interrupt1" }.join
rescue => e
  puts "raised: #{e}"

never_die.resume { main_thread.raise "interrupt2" }.join { main_thread.raise "interrupt3" }.join

p :after

Output is:

raised: interrupt1

(I noticed these weird semantics when implementing Thread.handle_interrupt on TruffleRuby, and got a fairly subtle bug due to multiple Fibers of the same Thread queuing the same interrupt multiple times in the Thread's interrupt queue).

Actions #1

Updated by nobu (Nobuyoshi Nakada) about 1 month ago

  • Description updated (diff)

Updated by ko1 (Koichi Sasada) about 1 month ago

I understand some case it is confusing, but if Fiber is used to represent the data structure like Enumerator, Thread-wide mask is needed.
Could you give us the example which should be fiber local?

mame-san also proposed Fiber.handle_interrupt for fiber local handler to set fiber local setting.

Updated by mame (Yusuke Endoh) about 1 month ago

ko1 (Koichi Sasada) wrote in #note-2:

mame-san also proposed Fiber.handle_interrupt for fiber local handler to set fiber local setting.

No I didn't propose it actually. In today's dev meeting, we discussed that there are a case where per-Thread mask is needed (e.g., to take an element from an external enumerator), and a case where per-Fiber mask may be needed (I'm unsure about a concrete case though). I just said that, if so, it is theoretically possible to have both Thread.handle_interrupt for per-Thread mask and Fiber.handle_interrupt for per-Fiber mask (maybe per-Fiber mask takes precedence if any). But I have no idea whether per-Fiber mask is practically needed.

Actions #4

Updated by jeremyevans0 (Jeremy Evans) about 1 month ago

  • Status changed from Open to Feedback

Also available in: Atom PDF