From 792a511466bbfcfbdbe166582a36db1706600672 Mon Sep 17 00:00:00 2001 From: Sampo Kuokkanen Date: Wed, 9 Sep 2026 11:44:56 +0900 Subject: [PATCH] Stop redefining IO's wait methods in the java extension JRuby has had wait, wait_readable and wait_writable in IO since 10.0, so these copies shadow them. They have not kept up either: JRuby 10.1 takes an events mask and a timeout, or a timeout in any position among mode symbols, while these still only understand (timeout, mode). Requiring io/wait takes those forms away again. The C extension already did this, Init_wait has been empty since the methods moved into io.c. The library still loads, it just defines nothing. --- .../org/jruby/ext/io/wait/IOWaitLibrary.java | 122 +----------------- 1 file changed, 2 insertions(+), 120 deletions(-) diff --git a/ext/java/org/jruby/ext/io/wait/IOWaitLibrary.java b/ext/java/org/jruby/ext/io/wait/IOWaitLibrary.java index 5c49544..14ef2b5 100644 --- a/ext/java/org/jruby/ext/io/wait/IOWaitLibrary.java +++ b/ext/java/org/jruby/ext/io/wait/IOWaitLibrary.java @@ -29,133 +29,15 @@ package org.jruby.ext.io.wait; import org.jruby.Ruby; -import org.jruby.RubyBoolean; -import org.jruby.RubyClass; -import org.jruby.RubyIO; -import org.jruby.RubyNumeric; -import org.jruby.RubySymbol; -import org.jruby.RubyTime; -import org.jruby.anno.JRubyMethod; -import org.jruby.runtime.Helpers; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.load.Library; -import org.jruby.util.io.OpenFile; - -import java.nio.channels.SelectionKey; - -import static org.jruby.api.Warn.warnDeprecated; /** + * IO wait methods are built in JRuby now, just for backward compatibility. + * * @author Nick Sieger */ public class IOWaitLibrary implements Library { public void load(Ruby runtime, boolean wrap) { - RubyClass ioClass = runtime.getIO(); - ioClass.defineAnnotatedMethods(IOWaitLibrary.class); - } - - @JRubyMethod(optional = 1) - public static IRubyObject wait_readable(ThreadContext context, IRubyObject _io, IRubyObject[] argv) { - RubyIO io = (RubyIO)_io; - OpenFile fptr = io.getOpenFileChecked(); - - fptr.checkReadable(context); - - long tv = prepareTimeout(context, argv); - - if (fptr.readPending() != 0) return context.tru; - - return doWait(context, io, fptr, tv, SelectionKey.OP_READ | SelectionKey.OP_ACCEPT); - } - - /** - * waits until input available or timed out and returns self, or nil when EOF reached. - */ - @JRubyMethod(optional = 1) - public static IRubyObject wait_writable(ThreadContext context, IRubyObject _io, IRubyObject[] argv) { - RubyIO io = (RubyIO)_io; - - OpenFile fptr = io.getOpenFileChecked(); - - fptr.checkWritable(context); - - long tv = prepareTimeout(context, argv); - - return doWait(context, io, fptr, tv, SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE); - } - - @JRubyMethod(optional = 2) - public static IRubyObject wait(ThreadContext context, IRubyObject _io, IRubyObject[] argv) { - RubyIO io = (RubyIO)_io; - - OpenFile fptr = io.getOpenFileChecked(); - - int ops = 0; - - if (argv.length == 2) { - if (argv[1] instanceof RubySymbol) { - RubySymbol sym = (RubySymbol) argv[1]; - switch (sym.asJavaString()) { // 7 bit comparison - case "r": - case "read": - case "readable": - ops |= SelectionKey.OP_ACCEPT | SelectionKey.OP_READ; - break; - case "w": - case "write": - case "writable": - ops |= SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE; - break; - case "rw": - case "read_write": - case "readable_writable": - ops |= SelectionKey.OP_ACCEPT | SelectionKey.OP_READ | SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE; - break; - default: - throw context.runtime.newArgumentError("unsupported mode: " + sym); - } - } else { - throw context.runtime.newArgumentError("unsupported mode: " + argv[1].getType()); - } - } else { - ops |= SelectionKey.OP_ACCEPT | SelectionKey.OP_READ; - } - - if ((ops & SelectionKey.OP_READ) == SelectionKey.OP_READ && fptr.readPending() != 0) return context.tru; - - long tv = prepareTimeout(context, argv); - - return doWait(context, io, fptr, tv, ops); - } - - private static IRubyObject doWait(ThreadContext context, RubyIO io, OpenFile fptr, long tv, int ops) { - boolean ready = fptr.ready(context.runtime, context.getThread(), ops, tv); - fptr.checkClosed(); - if (ready) return io; - return context.nil; - } - - private static long prepareTimeout(ThreadContext context, IRubyObject[] argv) { - IRubyObject timeout; - long tv; - switch (argv.length) { - case 2: - case 1: - timeout = argv[0]; - break; - default: - timeout = context.nil; - } - - if (timeout.isNil()) { - tv = -1; - } - else { - tv = (long)(RubyTime.convertTimeInterval(context, timeout) * 1000); - if (tv < 0) throw context.runtime.newArgumentError("time interval must be positive"); - } - return tv; } }