Skip to content

Commit 810ed27

Browse files
committed
Fix IO.select([io], nil, [io]) on macOS
* It was hanging due to a bug in macOS poll(2), so we have to work around it. * Fixes #3346
1 parent b7cb7fe commit 810ed27

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Bug fixes:
1010
* Fix `IO.copy_stream` with a `Tempfile` destination (#3280, @eregon).
1111
* Fix `Regexp.union` negotiating the wrong result encoding (#3287, @nirvdrum, @simonlevasseur).
1212
* Fix `Proc#parameters` and return all the numbered parameters lower than the used explicitly ones (@andrykonchin).
13+
* Fix `IO.select([io], nil, [io])` on macOS, it was hanging due to a bug in macOS `poll(2)` (#3346, @eregon, @andrykonchin).
1314

1415
Compatibility:
1516

src/main/ruby/truffleruby/core/io.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,21 @@ def self.select(readables = nil, writables = nil, errorables = nil, timeout = ni
767767
raise IOError, 'closed stream' if io.closed?
768768
io
769769
end
770+
771+
if Truffle::Platform.darwin? and !errorables.empty?
772+
if errorables.all? { |obj| readables.include?(obj) or writables.include?(obj) }
773+
# On macOS, if all errorables are in readables or writables, we make errorables empty,
774+
# because if non-empty they cause a bug with macOS poll(2), detailed in
775+
# https://github.com/oracle/truffleruby/issues/3346#issuecomment-1847323741
776+
# Errors are still reported, POLLIN_SET and POLLOUT_SET both include POLLERR.
777+
# POLLPRI is only for TCP OOB data (rare, not portable, poll(2) hangs on macOS with TCP OOB, another macOS bug),
778+
# and other "high priority data" which seems to not exist or unused since there is no way to read that data.
779+
errorables = []
780+
errorable_ios = []
781+
else
782+
raise IOError, 'IO.select call on macOS with error IOs not in read IOs or write IOs, this is not supported due to poll(2) bugs on macOS'
783+
end
784+
end
770785
else
771786
errorables = []
772787
errorable_ios = []

0 commit comments

Comments
 (0)