From acfe2f2655ab25d52c4347783c4de99fa2daaf62 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Fri, 24 Dec 2021 23:11:02 +1300 Subject: [PATCH] Improvements to `rb_io_wait` return value handling and internal implementation. (#5340) --- include/ruby/fiber/scheduler.h | 2 +- io.c | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/include/ruby/fiber/scheduler.h b/include/ruby/fiber/scheduler.h index a255a1a712..14e36ffb3a 100644 --- a/include/ruby/fiber/scheduler.h +++ b/include/ruby/fiber/scheduler.h @@ -205,7 +205,7 @@ VALUE rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber); * this for instance switches to another fiber etc. * * The "events" here is a Ruby level integer, which is an OR-ed value of - * `IO::READABLE`, `IO::WRITable`, and `IO::PRIORITY`. + * `IO::READABLE`, `IO::WRITABLE`, and `IO::PRIORITY`. * * @param[in] scheduler Target scheduler. * @param[in] io An io object to wait. diff --git a/io.c b/io.c index ba8a632757..957d36aa22 100644 --- a/io.c +++ b/io.c @@ -500,15 +500,15 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd) #if defined(_WIN32) #define WAIT_FD_IN_WIN32(fptr) \ - (rb_w32_io_cancelable_p((fptr)->fd) ? 0 : RB_NUM2INT(rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil))) + (rb_w32_io_cancelable_p((fptr)->fd) ? Qnil : rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil)) #else #define WAIT_FD_IN_WIN32(fptr) #endif #define READ_CHECK(fptr) do {\ if (!READ_DATA_PENDING(fptr)) {\ - WAIT_FD_IN_WIN32(fptr);\ - rb_io_check_closed(fptr);\ + WAIT_FD_IN_WIN32(fptr);\ + rb_io_check_closed(fptr);\ }\ } while(0) @@ -1323,10 +1323,9 @@ rb_io_wait(VALUE io, VALUE events, VALUE timeout) // Not sure if this is necessary: rb_io_check_closed(fptr); - if (ready > 0) { + if (ready) { return RB_INT2NUM(ready); - } - else { + } else { return Qfalse; } } @@ -1490,13 +1489,25 @@ rb_io_maybe_wait(int error, VALUE io, VALUE events, VALUE timeout) int rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout) { - return RB_NUM2INT(rb_io_maybe_wait(error, io, RB_INT2NUM(RUBY_IO_READABLE), timeout)); + VALUE result = rb_io_maybe_wait(error, io, RB_INT2NUM(RUBY_IO_READABLE), timeout); + + if (RTEST(result)) { + return RB_NUM2INT(result); + } else { + return 0; + } } int rb_io_maybe_wait_writable(int error, VALUE io, VALUE timeout) { - return RB_NUM2INT(rb_io_maybe_wait(error, io, RB_INT2NUM(RUBY_IO_WRITABLE), timeout)); + VALUE result = rb_io_maybe_wait(error, io, RB_INT2NUM(RUBY_IO_WRITABLE), timeout); + + if (RTEST(result)) { + return RB_NUM2INT(result); + } else { + return 0; + } } static void