From f5c81139ddc1900a7f6004b0eb5ff49a1754dfe5 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 12 Nov 2025 17:29:28 +0900 Subject: [PATCH 1/2] Start 0.4.0 --- io-wait.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io-wait.gemspec b/io-wait.gemspec index e54c2db..4a79131 100644 --- a/io-wait.gemspec +++ b/io-wait.gemspec @@ -1,4 +1,4 @@ -_VERSION = "0.3.6" +_VERSION = "0.4.0.dev" Gem::Specification.new do |spec| spec.name = "io-wait" From 1decadc7f9485b5827b9e327b704b83dc626d971 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 4 Nov 2025 21:42:54 +0900 Subject: [PATCH 2/2] Remove `IO#nread` and `IO#ready? --- ext/io/wait/extconf.rb | 17 +--- ext/io/wait/wait.c | 94 ------------------- .../org/jruby/ext/io/wait/IOWaitLibrary.java | 41 -------- test/io/wait/test_io_wait.rb | 30 ------ test/io/wait/test_io_wait_uncommon.rb | 15 --- 5 files changed, 1 insertion(+), 196 deletions(-) diff --git a/ext/io/wait/extconf.rb b/ext/io/wait/extconf.rb index e97efa1..c199463 100644 --- a/ext/io/wait/extconf.rb +++ b/ext/io/wait/extconf.rb @@ -1,21 +1,6 @@ # frozen_string_literal: false require 'mkmf' -target = "io/wait" have_func("rb_io_wait", "ruby/io.h") have_func("rb_io_descriptor", "ruby/io.h") -unless macro_defined?("DOSISH", "#include ") - have_header(ioctl_h = "sys/ioctl.h") or ioctl_h = nil - fionread = %w[sys/ioctl.h sys/filio.h sys/socket.h].find do |h| - have_macro("FIONREAD", [h, ioctl_h].compact) - end - if fionread - $defs << "-DFIONREAD_HEADER=\"<#{fionread}>\"" - create_makefile(target) - end -else - if have_func("rb_w32_ioctlsocket", "ruby.h") - have_func("rb_w32_is_socket", "ruby.h") - create_makefile(target) - end -end +create_makefile("io/wait") diff --git a/ext/io/wait/wait.c b/ext/io/wait/wait.c index d9653e9..23d37e1 100644 --- a/ext/io/wait/wait.c +++ b/ext/io/wait/wait.c @@ -14,32 +14,6 @@ #include "ruby.h" #include "ruby/io.h" -#include -#if defined(HAVE_UNISTD_H) && (defined(__sun)) -#include -#endif -#if defined(HAVE_SYS_IOCTL_H) -#include -#endif -#if defined(FIONREAD_HEADER) -#include FIONREAD_HEADER -#endif - -#ifdef HAVE_RB_W32_IOCTLSOCKET -#define ioctl ioctlsocket -#define ioctl_arg u_long -#define ioctl_arg2num(i) ULONG2NUM(i) -#else -#define ioctl_arg int -#define ioctl_arg2num(i) INT2NUM(i) -#endif - -#ifdef HAVE_RB_W32_IS_SOCKET -#define FIONREAD_POSSIBLE_P(fd) rb_w32_is_socket(fd) -#else -#define FIONREAD_POSSIBLE_P(fd) ((void)(fd),Qtrue) -#endif - #ifndef HAVE_RB_IO_WAIT static struct timeval * get_timeout(int argc, VALUE *argv, struct timeval *timerec) @@ -66,41 +40,6 @@ wait_for_single_fd(rb_io_t *fptr, int events, struct timeval *tv) } #endif -/* - * call-seq: - * io.nread -> int - * - * Returns number of bytes that can be read without blocking. - * Returns zero if no information available. - * - * You must require 'io/wait' to use this method. - */ - -static VALUE -io_nread(VALUE io) -{ - rb_io_t *fptr; - int len; - ioctl_arg n; - - rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "IO#nread is deprecated; use wait_readable instead"); - GetOpenFile(io, fptr); - rb_io_check_char_readable(fptr); - len = rb_io_read_pending(fptr); - if (len > 0) return INT2FIX(len); - -#ifdef HAVE_RB_IO_DESCRIPTOR - int fd = rb_io_descriptor(io); -#else - int fd = fptr->fd; -#endif - - if (!FIONREAD_POSSIBLE_P(fd)) return INT2FIX(0); - if (ioctl(fd, FIONREAD, &n)) return INT2FIX(0); - if (n > 0) return ioctl_arg2num(n); - return INT2FIX(0); -} - #ifdef HAVE_RB_IO_WAIT static VALUE io_wait_event(VALUE io, int event, VALUE timeout, int return_io) @@ -125,36 +64,6 @@ io_wait_event(VALUE io, int event, VALUE timeout, int return_io) } #endif -/* - * call-seq: - * io.ready? -> truthy or falsy - * - * Returns a truthy value if input available without blocking, or a - * falsy value. - * - * You must require 'io/wait' to use this method. - */ - -static VALUE -io_ready_p(VALUE io) -{ - rb_io_t *fptr; -#ifndef HAVE_RB_IO_WAIT - struct timeval tv = {0, 0}; -#endif - - rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "IO#ready? is deprecated; use wait_readable instead"); - GetOpenFile(io, fptr); - rb_io_check_char_readable(fptr); - if (rb_io_read_pending(fptr)) return Qtrue; - -#ifndef HAVE_RB_IO_WAIT - return wait_for_single_fd(fptr, RB_WAITFD_IN, &tv) ? Qtrue : Qfalse; -#else - return io_wait_event(io, RUBY_IO_READABLE, RB_INT2NUM(0), 1); -#endif -} - /* Ruby 3.2+ can define these methods. This macro indicates that case. */ #ifndef RUBY_IO_WAIT_METHODS @@ -424,9 +333,6 @@ Init_wait(void) RB_EXT_RACTOR_SAFE(true); #endif - rb_define_method(rb_cIO, "nread", io_nread, 0); - rb_define_method(rb_cIO, "ready?", io_ready_p, 0); - #ifndef RUBY_IO_WAIT_METHODS rb_define_method(rb_cIO, "wait", io_wait, -1); diff --git a/ext/java/org/jruby/ext/io/wait/IOWaitLibrary.java b/ext/java/org/jruby/ext/io/wait/IOWaitLibrary.java index b0ec03f..5c49544 100644 --- a/ext/java/org/jruby/ext/io/wait/IOWaitLibrary.java +++ b/ext/java/org/jruby/ext/io/wait/IOWaitLibrary.java @@ -56,47 +56,6 @@ public void load(Ruby runtime, boolean wrap) { ioClass.defineAnnotatedMethods(IOWaitLibrary.class); } - @JRubyMethod - public static IRubyObject nread(ThreadContext context, IRubyObject _io) { - Ruby runtime = context.runtime; - OpenFile fptr; - int len; -// ioctl_arg n; - RubyIO io = (RubyIO)_io; - - warnDeprecated(context, "IO#nread is deprecated; use wait_readable instead"); - fptr = io.getOpenFileChecked(); - fptr.checkReadable(context); - len = fptr.readPending(); - if (len > 0) return runtime.newFixnum(len); - // TODO: better effort to get available bytes from our channel -// if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0); -// if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0); -// if (n > 0) return ioctl_arg2num(n); - // Because we can't get an actual system-level buffer available count, we fake it by returning 1 if ready - return RubyNumeric.int2fix(runtime, fptr.readyNow(context) ? 1 : 0); - } - - /** - * returns non-nil if input available without blocking, false if EOF or not open/readable, otherwise nil. - */ - @JRubyMethod(name = "ready?") - public static IRubyObject ready(ThreadContext context, IRubyObject _io) { - RubyIO io = (RubyIO)_io; - OpenFile fptr; -// ioctl_arg n; - - warnDeprecated(context, "IO#ready? is deprecated; use wait_readable instead"); - fptr = io.getOpenFileChecked(); - fptr.checkReadable(context); - if (fptr.readPending() != 0) return context.tru; - // TODO: better effort to get available bytes from our channel -// if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qnil; -// if (ioctl(fptr->fd, FIONREAD, &n)) return Qnil; -// if (n > 0) return Qtrue; - return RubyBoolean.newBoolean(context, fptr.readyNow(context)); - } - @JRubyMethod(optional = 1) public static IRubyObject wait_readable(ThreadContext context, IRubyObject _io, IRubyObject[] argv) { RubyIO io = (RubyIO)_io; diff --git a/test/io/wait/test_io_wait.rb b/test/io/wait/test_io_wait.rb index 4453637..ffe3b1f 100644 --- a/test/io/wait/test_io_wait.rb +++ b/test/io/wait/test_io_wait.rb @@ -4,9 +4,6 @@ require 'timeout' require 'socket' -# For `IO#ready?` and `IO#nread`: -require 'io/wait' - class TestIOWait < Test::Unit::TestCase def setup @@ -22,33 +19,6 @@ def teardown @w.close unless @w.closed? end - def test_nread - assert_equal 0, @r.nread - @w.syswrite "." - sleep 0.1 - assert_equal 1, @r.nread - end - - def test_nread_buffered - @w.syswrite ".\n!" - assert_equal ".\n", @r.gets - assert_equal 1, @r.nread - end - - def test_ready? - omit 'unstable on MinGW' if /mingw/ =~ RUBY_PLATFORM - assert_not_predicate @r, :ready?, "shouldn't ready, but ready" - @w.syswrite "." - sleep 0.1 - assert_predicate @r, :ready?, "should ready, but not" - end - - def test_buffered_ready? - @w.syswrite ".\n!" - assert_equal ".\n", @r.gets - assert_predicate @r, :ready? - end - def test_wait omit 'unstable on MinGW' if /mingw/ =~ RUBY_PLATFORM assert_nil @r.wait(0) diff --git a/test/io/wait/test_io_wait_uncommon.rb b/test/io/wait/test_io_wait_uncommon.rb index 0f97ac3..15b13b5 100644 --- a/test/io/wait/test_io_wait_uncommon.rb +++ b/test/io/wait/test_io_wait_uncommon.rb @@ -76,14 +76,6 @@ def test_wait_writable_null check_dev(IO::NULL, :wait_writable) end - def test_after_ungetc_ready? - check_dev(IO::NULL, mode: "r") {|fp| - assert_respond_to fp, :ready? - fp.ungetc(?a) - assert_predicate fp, :ready? - } - end - def test_after_ungetc_wait_readable check_dev(IO::NULL, mode: "r") {|fp| fp.ungetc(?a) @@ -91,13 +83,6 @@ def test_after_ungetc_wait_readable } end - def test_after_ungetc_in_text_ready? - check_dev(IO::NULL, mode: "rt") {|fp| - fp.ungetc(?a) - assert_predicate fp, :ready? - } - end - def test_after_ungetc_in_text_wait_readable check_dev(IO::NULL, mode: "rt") {|fp| fp.ungetc(?a)