diff options
author | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2022-10-07 21:48:38 +1300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-07 21:48:38 +1300 |
commit | e4f91bbdbaa6ab3125f24967414ac5300bb244f5 (patch) | |
tree | 575f8febdd50601522c5e5ec72f3436139304537 /include/ruby | |
parent | e76217a7f3957c9cea52832c2f4237130411f7dd (diff) | |
download | ruby-e4f91bbdbaa6ab3125f24967414ac5300bb244f5.tar.gz |
Add IO#timeout attribute and use it for blocking IO operations. (#5653)
Diffstat (limited to 'include/ruby')
-rw-r--r-- | include/ruby/io.h | 50 |
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); |