* [ruby-core:124851] [Ruby Bug#21918] fiber scheduler: fiber interrupt triggers for IOs that haven't been closed
@ 2026-02-19 14:43 chucke (Tiago Cardoso) via ruby-core
0 siblings, 0 replies; only message in thread
From: chucke (Tiago Cardoso) via ruby-core @ 2026-02-19 14:43 UTC (permalink / raw)
To: ruby-core; +Cc: chucke (Tiago Cardoso)
Issue #21918 has been reported by chucke (Tiago Cardoso).
----------------------------------------
Bug #21918: fiber scheduler: fiber interrupt triggers for IOs that haven't been closed
https://bugs.ruby-lang.org/issues/21918
* Author: chucke (Tiago Cardoso)
* Status: Open
* ruby -v: ruby 4.0.0 (2025-12-25 revision 553f1675f3) +PRISM [x86_64-linux]
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN
----------------------------------------
I've been chasing an issue, which I believe is to with the recent introduction of the `fiber_interrupt` hook in ruby 4. As a reproduction I have the following snippet:
```ruby
require "socket"
require_relative "test/fiber/scheduler" # use the one defined here: https://github.com/ruby/ruby/blob/master/test/fiber/scheduler.rb
udp = UDPSocket.new(Socket::AF_INET)
tcp = Socket.new(Socket::AF_INET, :STREAM, 0)
tcp.connect(Socket.sockaddr_in(80, "nghttp2"))
t = Thread.start do
Thread.current.abort_on_exception = true
scheduler = Scheduler.new
Fiber.set_scheduler scheduler
5.times do
Fiber.schedule do
begin
puts "#{Fiber.current.object_id} -> wait udp"
udp.to_io.wait_readable(2)
rescue IOError => e
puts "#{Fiber.current.object_id} -> udp io error: #{e}"
end
begin
puts "#{Fiber.current.object_id} -> closing udp"
udp.close
puts "#{Fiber.current.object_id} -> closed udp"
puts "#{Fiber.current.object_id} -> wait tcp"
tcp.to_io.wait_readable(2)
puts "#{Fiber.current.object_id} -> done"
rescue => e
puts "#{Fiber.current.object_id} -> tcp io error: #{e}"
else
puts "#{Fiber.current.object_id} -> closing tcp"
tcp.close
end
end
end
end
t.join
```
This produces the following output to me:
```
1472 -> wait udp
1488 -> wait udp
1496 -> wait udp
1504 -> wait udp
1512 -> wait udp
1472 -> closing udp
1488 -> closing udp
1488 -> closed udp
1488 -> wait tcp
1496 -> closing udp
1496 -> closed udp
1496 -> wait tcp
1504 -> closing udp
1504 -> closed udp
1504 -> wait tcp
1512 -> closing udp
1512 -> closed udp
1512 -> wait tcp
1512 -> tcp io error: stream closed in another thread
1504 -> tcp io error: stream closed in another thread
1496 -> tcp io error: stream closed in another thread
1488 -> tcp io error: stream closed in another thread
1472 -> closed udp
1472 -> wait tcp
1472 -> done
1472 -> closing tcp
```
The thing that makes this program very confusing is that the "stream closed in another thread" related to the udp socket is raised while waiting for read readiness on the tcp socket. In such a situation, I'd expect the error to relate to the actual socket being waited on, not something else that fiber does not care about anymore.
One thing that could have helped would be to have the reference of which IO object the exception relates to in the exception (aka `IOError#io` would return the socket). Nevertheless, I'd still consider an issue that this triggers in the wrong "fiber.yield" moment. Therefore, I think there are two possible outcomes here:
1. all fibers stop on `udp.close` until it is in fact closed (and then IOError is raised before the "closed udp" message can be printed)
2. exceptions related to IOs not actively being monitored by the current fiber are ignored.
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-02-19 14:43 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-19 14:43 [ruby-core:124851] [Ruby Bug#21918] fiber scheduler: fiber interrupt triggers for IOs that haven't been closed chucke (Tiago Cardoso) via ruby-core
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).