summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ruby/io.h19
-rw-r--r--io.c14
-rw-r--r--spec/ruby/optional/capi/io_spec.rb12
3 files changed, 30 insertions, 15 deletions
diff --git a/include/ruby/io.h b/include/ruby/io.h
index 8fae7eb0f9..d2fd3ed317 100644
--- a/include/ruby/io.h
+++ b/include/ruby/io.h
@@ -975,6 +975,7 @@ VALUE rb_io_wait(VALUE io, VALUE events, VALUE timeout);
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
* @retval RUBY_Qfalse Operation timed out.
+ * @retval RUBY_Qnil Operation failed for some other reason (errno).
* @retval Otherwise Actual events reached.
*
*/
@@ -982,8 +983,11 @@ VALUE rb_io_maybe_wait(int error, VALUE io, VALUE events, VALUE timeout);
/**
* Blocks until the passed IO is ready for reading, if that makes sense for the
- * passed errno. This is a special case of rb_io_maybe_wait() that only
- * concerns for reading.
+ * passed errno. This is a special case of rb_io_maybe_wait() that is
+ * only concerned with reading and handles the timeout.
+ *
+ * If you do not want the default timeout handling, consider using
+ * ::rb_io_maybe_wait directly.
*
* @param[in] error System errno.
* @param[in] io An IO object to wait.
@@ -991,15 +995,18 @@ VALUE rb_io_maybe_wait(int error, VALUE io, VALUE events, VALUE timeout);
* @exception rb_eIOError `io` is not open.
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
- * @retval 0 Operation timed out.
+ * @exception rb_eIOTimeoutError The wait operation timed out.
* @retval Otherwise Always returns ::RUBY_IO_READABLE.
*/
int rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout);
/**
* Blocks until the passed IO is ready for writing, if that makes sense for the
- * passed errno. This is a special case of rb_io_maybe_wait() that only
- * concernsfor writing.
+ * passed errno. This is a special case of rb_io_maybe_wait() that is
+ * only concerned with writing, and handles the timeout.
+ *
+ * If you do not want the default timeout handling, consider using
+ * ::rb_io_maybe_wait directly.
*
* @param[in] error System errno.
* @param[in] io An IO object to wait.
@@ -1007,7 +1014,7 @@ int rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout);
* @exception rb_eIOError `io` is not open.
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
- * @retval 0 Operation timed out.
+ * @exception rb_eIOTimeoutError The wait operation timed out.
* @retval Otherwise Always returns ::RUBY_IO_WRITABLE.
*/
int rb_io_maybe_wait_writable(int error, VALUE io, VALUE timeout);
diff --git a/io.c b/io.c
index 3c99043916..1e5c851f87 100644
--- a/io.c
+++ b/io.c
@@ -1623,7 +1623,7 @@ rb_io_maybe_wait(int error, VALUE io, VALUE events, VALUE timeout)
default:
// Non-specific error, no event is ready:
- return Qfalse;
+ return Qnil;
}
}
@@ -1635,9 +1635,11 @@ rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout)
if (RTEST(result)) {
return RB_NUM2INT(result);
}
- else {
- return 0;
+ else if (result == RUBY_Qfalse) {
+ rb_raise(rb_eIOTimeoutError, "Timed out waiting for IO to become readable!");
}
+
+ return 0;
}
int
@@ -1648,9 +1650,11 @@ rb_io_maybe_wait_writable(int error, VALUE io, VALUE timeout)
if (RTEST(result)) {
return RB_NUM2INT(result);
}
- else {
- return 0;
+ else if (result == RUBY_Qfalse) {
+ rb_raise(rb_eIOTimeoutError, "Timed out waiting for IO to become writable!");
}
+
+ return 0;
}
static void
diff --git a/spec/ruby/optional/capi/io_spec.rb b/spec/ruby/optional/capi/io_spec.rb
index bdec46f5e1..01588408e1 100644
--- a/spec/ruby/optional/capi/io_spec.rb
+++ b/spec/ruby/optional/capi/io_spec.rb
@@ -458,10 +458,6 @@ describe "C-API IO function" do
@o.rb_io_maybe_wait(Errno::EINTR::Errno, @w_io, IO::WRITABLE, nil).should == IO::WRITABLE
end
- it "returns false if there is no error condition" do
- @o.rb_io_maybe_wait(0, @w_io, IO::WRITABLE, nil).should == false
- end
-
it "raises an IOError if the IO is closed" do
@w_io.close
-> { @o.rb_io_maybe_wait(0, @w_io, IO::WRITABLE, nil) }.should raise_error(IOError, "closed stream")
@@ -521,6 +517,14 @@ describe "C-API IO function" do
end
end
end
+
+ ruby_version_is "3.4" do
+ describe "rb_io_maybe_wait" do
+ it "returns nil if there is no error condition" do
+ @o.rb_io_maybe_wait(0, @w_io, IO::WRITABLE, nil).should == nil
+ end
+ end
+ end
end
describe "rb_fd_fix_cloexec" do