Skip to content

Commit 698ef86

Browse files
committed
IO.select accepts +Float::INFINITY+ as a timeout argument.
matz accepted at the developper meeting 2024-07-11.
1 parent e1f544c commit 698ef86

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ Note: We're only listing outstanding class updates.
2020
Also, `Binding#local_variable_get` and `Binding#local_variable_set` reject to handle numbered parameters.
2121
[[Bug #21049]]
2222

23+
* IO
24+
25+
* `IO.select` accepts +Float::INFINITY+ as a timeout argument.
26+
[[Feature #20610]]
27+
2328
* String
2429

2530
* Update Unicode to Version 15.1.0 and Emoji Version 15.1. [[Feature #19908]]

io.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10993,6 +10993,16 @@ rb_io_advise(int argc, VALUE *argv, VALUE io)
1099310993
#endif
1099410994
}
1099510995

10996+
static int
10997+
is_pos_inf(VALUE x)
10998+
{
10999+
double f;
11000+
if (!RB_FLOAT_TYPE_P(x))
11001+
return 0;
11002+
f = RFLOAT_VALUE(x);
11003+
return isinf(f) && 0 < f;
11004+
}
11005+
1099611006
/*
1099711007
* call-seq:
1099811008
* IO.select(read_ios, write_ios = [], error_ios = [], timeout = nil) -> array or nil
@@ -11009,6 +11019,8 @@ rb_io_advise(int argc, VALUE *argv, VALUE io)
1100911019
*
1101011020
* Argument +timeout+ is a numeric value (such as integer or float) timeout
1101111021
* interval in seconds.
11022+
* +timeout+ can also be +nil+ or +Float::INFINITY+.
11023+
* +nil+ and +Float::INFINITY+ means no timeout.
1101211024
*
1101311025
* The method monitors the \IO objects given in all three arrays,
1101411026
* waiting for some to be ready;
@@ -11159,7 +11171,7 @@ rb_f_select(int argc, VALUE *argv, VALUE obj)
1115911171
int i;
1116011172

1116111173
rb_scan_args(argc, argv, "13", &args.read, &args.write, &args.except, &timeout);
11162-
if (NIL_P(timeout)) {
11174+
if (NIL_P(timeout) || is_pos_inf(timeout)) {
1116311175
args.timeout = 0;
1116411176
}
1116511177
else {

test/ruby/test_io.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4262,6 +4262,23 @@ def test_select_exceptfds
42624262
end
42634263
end if Socket.const_defined?(:MSG_OOB)
42644264

4265+
def test_select_timeout
4266+
assert_equal(nil, IO.select(nil,nil,nil,0))
4267+
assert_equal(nil, IO.select(nil,nil,nil,0.0))
4268+
assert_raise(TypeError) { IO.select(nil,nil,nil,"invalid-timeout") }
4269+
assert_raise(ArgumentError) { IO.select(nil,nil,nil,-1) }
4270+
assert_raise(ArgumentError) { IO.select(nil,nil,nil,-0.1) }
4271+
assert_raise(ArgumentError) { IO.select(nil,nil,nil,-Float::INFINITY) }
4272+
assert_raise(RangeError) { IO.select(nil,nil,nil,Float::NAN) }
4273+
IO.pipe {|r, w|
4274+
w << "x"
4275+
ret = [[r], [], []]
4276+
assert_equal(ret, IO.select([r],nil,nil,0.1))
4277+
assert_equal(ret, IO.select([r],nil,nil,1))
4278+
assert_equal(ret, IO.select([r],nil,nil,Float::INFINITY))
4279+
}
4280+
end
4281+
42654282
def test_recycled_fd_close
42664283
dot = -'.'
42674284
IO.pipe do |sig_rd, sig_wr|

0 commit comments

Comments
 (0)