diff options
author | Samuel Williams <[email protected]> | 2022-10-07 21:48:38 +1300 |
---|---|---|
committer | GitHub <[email protected]> | 2022-10-07 21:48:38 +1300 |
commit | e4f91bbdbaa6ab3125f24967414ac5300bb244f5 (patch) | |
tree | 575f8febdd50601522c5e5ec72f3436139304537 /ext | |
parent | e76217a7f3957c9cea52832c2f4237130411f7dd (diff) |
Add IO#timeout attribute and use it for blocking IO operations. (#5653)
Notes
Notes:
Merged-By: ioquatix <[email protected]>
Diffstat (limited to 'ext')
-rw-r--r-- | ext/openssl/extconf.rb | 1 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl.c | 14 | ||||
-rw-r--r-- | ext/socket/ancdata.c | 4 | ||||
-rw-r--r-- | ext/socket/basicsocket.c | 2 | ||||
-rw-r--r-- | ext/socket/init.c | 4 | ||||
-rw-r--r-- | ext/socket/socket.c | 4 | ||||
-rw-r--r-- | ext/socket/udpsocket.c | 2 |
7 files changed, 23 insertions, 8 deletions
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index cc2b1f8ba2..a856646fe5 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -27,6 +27,7 @@ if with_config("debug") or enable_config("debug") end have_func("rb_io_maybe_wait") # Ruby 3.1 +have_func("rb_io_timeout") # Ruby 3.2 Logging::message "=== Checking for system dependent stuff... ===\n" have_library("nsl", "t_open") diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 6e1a50fd6d..605591efe5 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1641,11 +1641,21 @@ no_exception_p(VALUE opts) return 0; } +inline static +VALUE io_timeout() +{ +#ifdef HAVE_RB_IO_TIMEOUT + return Qundef; +#else + return Qnil; +#endif +} + static void io_wait_writable(rb_io_t *fptr) { #ifdef HAVE_RB_IO_MAYBE_WAIT - rb_io_maybe_wait_writable(errno, fptr->self, Qnil); + rb_io_maybe_wait_writable(errno, fptr->self, io_timeout()); #else rb_io_wait_writable(fptr->fd); #endif @@ -1655,7 +1665,7 @@ static void io_wait_readable(rb_io_t *fptr) { #ifdef HAVE_RB_IO_MAYBE_WAIT - rb_io_maybe_wait_readable(errno, fptr->self, Qnil); + rb_io_maybe_wait_readable(errno, fptr->self, io_timeout()); #else rb_io_wait_readable(fptr->fd); #endif diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index 071e3323bb..0ab3a8da47 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -1285,7 +1285,7 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, if (ss == -1) { int e; - if (!nonblock && rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { + if (!nonblock && rb_io_maybe_wait_writable(errno, fptr->self, fptr->timeout)) { rb_io_check_closed(fptr); goto retry; } @@ -1557,7 +1557,7 @@ bsock_recvmsg_internal(VALUE sock, if (ss == -1) { int e; - if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, Qnil)) { + if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, fptr->timeout)) { rb_io_check_closed(fptr); goto retry; } diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index 93196c924d..66c2537cbb 100644 --- a/ext/socket/basicsocket.c +++ b/ext/socket/basicsocket.c @@ -601,7 +601,7 @@ rsock_bsock_send(int argc, VALUE *argv, VALUE socket) if (n >= 0) return SSIZET2NUM(n); - if (rb_io_maybe_wait_writable(errno, socket, Qnil)) { + if (rb_io_maybe_wait_writable(errno, socket, fptr->timeout)) { continue; } diff --git a/ext/socket/init.c b/ext/socket/init.c index 0cff3d6794..e60dd32264 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -189,7 +189,7 @@ rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from) if (slen >= 0) break; - if (!rb_io_maybe_wait_readable(errno, socket, Qnil)) + if (!rb_io_maybe_wait_readable(errno, socket, Qundef)) rb_sys_fail("recvfrom(2)"); } @@ -705,7 +705,7 @@ rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len) retry = 1; goto retry; default: - if (!rb_io_maybe_wait_readable(error, io, Qnil)) break; + if (!rb_io_maybe_wait_readable(error, io, Qundef)) break; retry = 0; goto retry; } diff --git a/ext/socket/socket.c b/ext/socket/socket.c index b1965deb9e..5cf0835062 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -28,6 +28,10 @@ rsock_syserr_fail_host_port(int err, const char *mesg, VALUE host, VALUE port) message = rb_sprintf("%s for %+"PRIsVALUE" port % "PRIsVALUE"", mesg, host, port); + if (err == ETIMEDOUT) { + rb_exc_raise(rb_exc_new3(rb_eIOTimeoutError, message)); + } + rb_syserr_fail_str(err, message); } diff --git a/ext/socket/udpsocket.c b/ext/socket/udpsocket.c index 3500107972..5b878b4a95 100644 --- a/ext/socket/udpsocket.c +++ b/ext/socket/udpsocket.c @@ -170,7 +170,7 @@ udp_send_internal(VALUE v) if (n >= 0) return RB_SSIZE2NUM(n); - if (rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { + if (rb_io_maybe_wait_writable(errno, fptr->self, fptr->timeout)) { goto retry; } } |