[ruby-core:119124] [Ruby master Bug#20723] `IO#close` is broken on Ruby 3.3+ when using the Fiber scheduler.

Issue #20723 has been reported by ioquatix (Samuel Williams). ---------------------------------------- Bug #20723: `IO#close` is broken on Ruby 3.3+ when using the Fiber scheduler. https://bugs.ruby-lang.org/issues/20723 * Author: ioquatix (Samuel Williams) * Status: Open * Assignee: kjtsanaktsidis (KJ Tsanaktsidis) * Backport: 3.3: REQUIRED ---------------------------------------- The following program seems to work okay on Ruby 3.2 but hangs on Ruby 3.3: ```ruby #!/usr/bin/env ruby require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'async' end require 'socket' def close_while_reading(io) thread = Thread.new do Thread.current.report_on_exception = false io.wait_readable end # Wait until the thread is blocked on read: Thread.pass until thread.status == "sleep" Async do io.close end thread.join end begin client, server = Socket.pair(:UNIX, :STREAM) close_while_reading(client) rescue => error $stderr.puts error.full_message end ``` -- https://bugs.ruby-lang.org/

Issue #20723 has been updated by ioquatix (Samuel Williams). It may be related to https://github.com/ruby/ruby/commit/66871c5a06d723f8350935ced1e88d8cc929d809 ---------------------------------------- Bug #20723: `IO#close` is broken on Ruby 3.3+ when using the Fiber scheduler. https://bugs.ruby-lang.org/issues/20723#change-109718 * Author: ioquatix (Samuel Williams) * Status: Open * Assignee: kjtsanaktsidis (KJ Tsanaktsidis) * Backport: 3.3: REQUIRED ---------------------------------------- The following program seems to work okay on Ruby 3.2 but hangs on Ruby 3.3: ```ruby #!/usr/bin/env ruby require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'async' end require 'socket' def close_while_reading(io) thread = Thread.new do Thread.current.report_on_exception = false io.wait_readable end # Wait until the thread is blocked on read: Thread.pass until thread.status == "sleep" Async do io.close end thread.join end begin client, server = Socket.pair(:UNIX, :STREAM) close_while_reading(client) rescue => error $stderr.puts error.full_message end ``` -- https://bugs.ruby-lang.org/

Issue #20723 has been updated by ioquatix (Samuel Williams). I've added the following work-around: <https://github.com/socketry/io-stream/commit/7d1546fa829d3fe046f66f559d9a774497390f3e> ---------------------------------------- Bug #20723: `IO#close` is broken on Ruby 3.3+ when using the Fiber scheduler. https://bugs.ruby-lang.org/issues/20723#change-109719 * Author: ioquatix (Samuel Williams) * Status: Open * Assignee: kjtsanaktsidis (KJ Tsanaktsidis) * Backport: 3.3: REQUIRED ---------------------------------------- The following program seems to work okay on Ruby 3.2 but hangs on Ruby 3.3: ```ruby #!/usr/bin/env ruby require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'async' end require 'socket' def close_while_reading(io) thread = Thread.new do Thread.current.report_on_exception = false io.wait_readable end # Wait until the thread is blocked on read: Thread.pass until thread.status == "sleep" Async do io.close end thread.join end begin client, server = Socket.pair(:UNIX, :STREAM) close_while_reading(client) rescue => error $stderr.puts error.full_message end ``` -- https://bugs.ruby-lang.org/

Issue #20723 has been updated by kjtsanaktsidis (KJ Tsanaktsidis). Sorry about this. I think https://github.com/ruby/ruby/pull/11614 is the smallest diff that will fix the issue (and this should probably be backported to 3.3). Separately to that, I wonder if we need to wrap up some common function for "wake up this fiber, either with the fiber scheduler or with the thread directly". We've implemented this logic in a number of places... but let's keep that refactor out of the fix PR (since it shouldn't be backported). ---------------------------------------- Bug #20723: `IO#close` is broken on Ruby 3.3+ when using the Fiber scheduler. https://bugs.ruby-lang.org/issues/20723#change-109747 * Author: ioquatix (Samuel Williams) * Status: Open * Assignee: kjtsanaktsidis (KJ Tsanaktsidis) * Backport: 3.3: REQUIRED ---------------------------------------- The following program seems to work okay on Ruby 3.2 but hangs on Ruby 3.3: ```ruby #!/usr/bin/env ruby require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'async' end require 'socket' def close_while_reading(io) thread = Thread.new do Thread.current.report_on_exception = false io.wait_readable end # Wait until the thread is blocked on read: Thread.pass until thread.status == "sleep" Async do io.close end thread.join end begin client, server = Socket.pair(:UNIX, :STREAM) close_while_reading(client) rescue => error $stderr.puts error.full_message end ``` -- https://bugs.ruby-lang.org/

Issue #20723 has been updated by kjtsanaktsidis (KJ Tsanaktsidis). Backport PR for 3.3 - https://github.com/ruby/ruby/pull/11664 No backport for 3.2 is required because this locking around close didn't exist there. ---------------------------------------- Bug #20723: `IO#close` is broken on Ruby 3.3+ when using the Fiber scheduler. https://bugs.ruby-lang.org/issues/20723#change-109887 * Author: ioquatix (Samuel Williams) * Status: Closed * Assignee: kjtsanaktsidis (KJ Tsanaktsidis) * Backport: 3.3: REQUIRED ---------------------------------------- The following program seems to work okay on Ruby 3.2 but hangs on Ruby 3.3: ```ruby #!/usr/bin/env ruby require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'async' end require 'socket' def close_while_reading(io) thread = Thread.new do Thread.current.report_on_exception = false io.wait_readable end # Wait until the thread is blocked on read: Thread.pass until thread.status == "sleep" Async do io.close end thread.join end begin client, server = Socket.pair(:UNIX, :STREAM) close_while_reading(client) rescue => error $stderr.puts error.full_message end ``` -- https://bugs.ruby-lang.org/

Issue #20723 has been updated by k0kubun (Takashi Kokubun). Backport changed from 3.3: REQUIRED to 3.3: DONE ruby_3_3 commit:5b6009870dff883a8e71a05e60f175cea1d00d55. ---------------------------------------- Bug #20723: `IO#close` is broken on Ruby 3.3+ when using the Fiber scheduler. https://bugs.ruby-lang.org/issues/20723#change-110367 * Author: ioquatix (Samuel Williams) * Status: Closed * Assignee: kjtsanaktsidis (KJ Tsanaktsidis) * Backport: 3.3: DONE ---------------------------------------- The following program seems to work okay on Ruby 3.2 but hangs on Ruby 3.3: ```ruby #!/usr/bin/env ruby require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'async' end require 'socket' def close_while_reading(io) thread = Thread.new do Thread.current.report_on_exception = false io.wait_readable end # Wait until the thread is blocked on read: Thread.pass until thread.status == "sleep" Async do io.close end thread.join end begin client, server = Socket.pair(:UNIX, :STREAM) close_while_reading(client) rescue => error $stderr.puts error.full_message end ``` -- https://bugs.ruby-lang.org/
participants (3)
-
ioquatix (Samuel Williams)
-
k0kubun (Takashi Kokubun)
-
kjtsanaktsidis (KJ Tsanaktsidis)