summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2022-10-07 21:48:38 +1300
committerGitHub <noreply@github.com>2022-10-07 21:48:38 +1300
commite4f91bbdbaa6ab3125f24967414ac5300bb244f5 (patch)
tree575f8febdd50601522c5e5ec72f3436139304537 /include
parente76217a7f3957c9cea52832c2f4237130411f7dd (diff)
Add IO#timeout attribute and use it for blocking IO operations. (#5653)
Notes
Notes: Merged-By: ioquatix <samuel@codeotaku.com>
Diffstat (limited to 'include')
-rw-r--r--include/ruby/io.h50
1 files changed, 36 insertions, 14 deletions
diff --git a/include/ruby/io.h b/include/ruby/io.h
index dc4c8becf6..b91ecd00cb 100644
--- a/include/ruby/io.h
+++ b/include/ruby/io.h
@@ -64,6 +64,11 @@ struct stat;
struct timeval;
/**
+ * Indicates that a timeout has occurred while performing an IO operation.
+ */
+RUBY_EXTERN VALUE rb_eIOTimeoutError;
+
+/**
* Type of events that an IO can wait.
*
* @internal
@@ -214,6 +219,11 @@ typedef struct rb_io_t {
* This of course doesn't help inter-process IO interleaves, though.
*/
VALUE write_lock;
+
+ /**
+ * The timeout associated with this IO when performing blocking operations.
+ */
+ VALUE timeout;
} rb_io_t;
/** @alias{rb_io_enc_t} */
@@ -845,10 +855,32 @@ int rb_io_wait_writable(int fd);
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv);
/**
+ * Get the timeout associated with the specified io object.
+ *
+ * @param[in] io An IO object.
+ * @retval RUBY_Qnil There is no associated timeout.
+ * @retval Otherwise The timeout value.
+ */
+VALUE rb_io_timeout(VALUE io);
+
+/**
+ * Set the timeout associated with the specified io object. This timeout is
+ * used as a best effort timeout to prevent operations from blocking forever.
+ *
+ * @param[in] io An IO object.
+ * @param[in] timeout A timeout value. Must respond to #to_f.
+ * @
+ */
+VALUE rb_io_set_timeout(VALUE io, VALUE timeout);
+
+/**
* Blocks until the passed IO is ready for the passed events. The "events"
* here is a Ruby level integer, which is an OR-ed value of `IO::READABLE`,
* `IO::WRITable`, and `IO::PRIORITY`.
*
+ * If timeout is `Qundef`, it will use the default timeout as given by
+ * `rb_io_timeout(io)`.
+ *
* @param[in] io An IO object to wait.
* @param[in] events See above.
* @param[in] timeout Time, or numeric seconds since UNIX epoch.
@@ -903,13 +935,8 @@ 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.
- * @exception rb_eTypeError Operation timed out.
- * @return Always returns ::RUBY_IO_READABLE.
- *
- * @internal
- *
- * Because rb_io_maybe_wait() returns ::RUBY_Qfalse on timeout, this function
- * fails to convert that value to `int`, and raises ::rb_eTypeError.
+ * @retval 0 Operation timed out.
+ * @retval Otherwise Always returns ::RUBY_IO_READABLE.
*/
int rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout);
@@ -924,13 +951,8 @@ 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.
- * @exception rb_eTypeError Operation timed out.
- * @return Always returns ::RUBY_IO_WRITABLE.
- *
- * @internal
- *
- * Because rb_io_maybe_wait() returns ::RUBY_Qfalse on timeout, this function
- * fails to convert that value to `int`, and raises ::rb_eTypeError.
+ * @retval 0 Operation timed out.
+ * @retval Otherwise Always returns ::RUBY_IO_WRITABLE.
*/
int rb_io_maybe_wait_writable(int error, VALUE io, VALUE timeout);