diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index 0ab3a8da47..7406177de2 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, fptr->timeout)) { + if (!nonblock && rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { 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, fptr->timeout)) { + if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { rb_io_check_closed(fptr); goto retry; } diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index 66c2537cbb..54c369f6fc 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, fptr->timeout)) { + if (rb_io_maybe_wait_writable(errno, socket, RUBY_IO_TIMEOUT_DEFAULT)) { continue; } diff --git a/ext/socket/init.c b/ext/socket/init.c index e60dd32264..ac28f5c329 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, Qundef)) + if (!rb_io_maybe_wait_readable(errno, socket, RUBY_IO_TIMEOUT_DEFAULT)) 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, Qundef)) break; + if (!rb_io_maybe_wait_readable(error, io, RUBY_IO_TIMEOUT_DEFAULT)) break; retry = 0; goto retry; } diff --git a/ext/socket/udpsocket.c b/ext/socket/udpsocket.c index 5b878b4a95..5224e48a96 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, fptr->timeout)) { + if (rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { goto retry; } } diff --git a/include/ruby/io.h b/include/ruby/io.h index bb3bb9cd53..88029b1bb9 100644 --- a/include/ruby/io.h +++ b/include/ruby/io.h @@ -59,7 +59,7 @@ #define RUBY_IO_WAIT_METHODS // Used as the default timeout argument to `rb_io_wait` to use the `IO#timeout` value. -#define RUBY_IO_TIMEOUT_DEFAULT Qundef +#define RUBY_IO_TIMEOUT_DEFAULT Qnil RBIMPL_SYMBOL_EXPORT_BEGIN() @@ -881,14 +881,14 @@ VALUE rb_io_set_timeout(VALUE io, VALUE timeout); * 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 + * If timeout is `Qnil`, 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. - * If Qnil, wait forever. If Qundef, use the - * default timeout. + * If Qnil, use the default timeout. If Qfalse + * or Qundef, wait forever. * @exception rb_eIOError `io` is not open. * @exception rb_eRangeError `timeout` is out of range. * @exception rb_eSystemCallError `select(2)` failed for some reason. diff --git a/io.c b/io.c index c41a8d4ed5..6cde02aaae 100644 --- a/io.c +++ b/io.c @@ -494,7 +494,7 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd) #if defined(_WIN32) #define WAIT_FD_IN_WIN32(fptr) \ - (rb_w32_io_cancelable_p((fptr)->fd) ? Qnil : rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), fptr->timeout)) + (rb_w32_io_cancelable_p((fptr)->fd) ? Qnil : rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), RUBY_IO_TIMEOUT_DEFAULT)) #else #define WAIT_FD_IN_WIN32(fptr) #endif @@ -866,6 +866,11 @@ rb_io_timeout(VALUE self) VALUE rb_io_set_timeout(VALUE self, VALUE timeout) { + // Validate it: + if (RTEST(timeout)) { + rb_time_interval(timeout); + } + rb_io_t *fptr = rb_io_get_fptr(self); fptr->timeout = timeout; @@ -1044,7 +1049,7 @@ void rb_io_read_check(rb_io_t *fptr) { if (!READ_DATA_PENDING(fptr)) { - rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), fptr->timeout); + rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), RUBY_IO_TIMEOUT_DEFAULT); } return; } @@ -1395,7 +1400,7 @@ io_fflush(rb_io_t *fptr) return 0; while (fptr->wbuf.len > 0 && io_flush_buffer(fptr) != 0) { - if (!rb_io_maybe_wait_writable(errno, fptr->self, fptr->timeout)) + if (!rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) return -1; rb_io_check_closed(fptr); @@ -1419,7 +1424,7 @@ rb_io_wait(VALUE io, VALUE events, VALUE timeout) struct timeval tv_storage; struct timeval *tv = NULL; - if (timeout == Qundef) { + if (timeout == Qnil || timeout == Qundef) { timeout = fptr->timeout; } @@ -1793,7 +1798,7 @@ io_binwrite_string(VALUE arg) remaining -= result; } // Wait for it to become writable: - else if (rb_io_maybe_wait_writable(errno, p->fptr->self, p->fptr->timeout)) { + else if (rb_io_maybe_wait_writable(errno, p->fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { rb_io_check_closed(p->fptr); } else { @@ -2060,7 +2065,7 @@ io_binwritev_internal(VALUE arg) iov->iov_base = (char *)iov->iov_base + result; iov->iov_len -= result; } - else if (rb_io_maybe_wait_writable(errno, fptr->self, fptr->timeout)) { + else if (rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { rb_io_check_closed(fptr); } else { @@ -2567,7 +2572,7 @@ rb_io_rewind(VALUE io) static int fptr_wait_readable(rb_io_t *fptr) { - int result = rb_io_maybe_wait_readable(errno, fptr->self, fptr->timeout); + int result = rb_io_maybe_wait_readable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT); if (result) rb_io_check_closed(fptr); @@ -5291,7 +5296,7 @@ finish_writeconv(rb_io_t *fptr, int noalloc) ds += result; if ((size_t)result == remaining) break; } - else if (rb_io_maybe_wait_writable(errno, fptr->self, fptr->timeout)) { + else if (rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { if (fptr->fd < 0) return noalloc ? Qtrue : rb_exc_new3(rb_eIOError, rb_str_new_cstr(closed_stream)); } @@ -12284,7 +12289,7 @@ fiber_scheduler_wait_for(void * _arguments) { struct fiber_scheduler_wait_for_arguments *arguments = (struct fiber_scheduler_wait_for_arguments *)_arguments; - arguments->result = rb_fiber_scheduler_io_wait(arguments->scheduler, arguments->fptr->self, INT2NUM(arguments->events), arguments->fptr->timeout); + arguments->result = rb_fiber_scheduler_io_wait(arguments->scheduler, arguments->fptr->self, INT2NUM(arguments->events), RUBY_IO_TIMEOUT_DEFAULT); return NULL; }