HEX
Server: Apache
System: Linux s198.coreserver.jp 5.15.0-151-generic #161-Ubuntu SMP Tue Jul 22 14:25:40 UTC 2025 x86_64
User: nagasaki (10062)
PHP: 7.1.33
Disabled: NONE
Upload Files
File: //usr/local/rvm/gems/ruby-2.6.8/doc/nio4r-2.5.8/ri/ext/nio4r/org/nio4r/page-Selector_java.ri
U:RDoc::TopLevel[	iI"&ext/nio4r/org/nio4r/Selector.java:ETcRDoc::Parser::Simpleo:RDoc::Markup::Document:@parts[o:RDoc::Markup::Paragraph;[I"package org.nio4r;;To:RDoc::Markup::BlankLineo;	;[I" import java.util.Iterator; ;TI"import java.util.Map; ;TI"import java.util.HashMap; ;TI"!import java.io.IOException; ;TI"'import java.nio.channels.Channel; ;TI"1import java.nio.channels.SelectableChannel; ;TI"+import java.nio.channels.SelectionKey;;T@o;	;[I"import org.jruby.Ruby; ;TI"!import org.jruby.RubyArray; ;TI"!import org.jruby.RubyClass; ;TI"import org.jruby.RubyIO; ;TI"#import org.jruby.RubyNumeric; ;TI""import org.jruby.RubyObject; ;TI"(import org.jruby.anno.JRubyMethod; ;TI"%import org.jruby.runtime.Block; ;TI"-import org.jruby.runtime.ThreadContext; ;TI"3import org.jruby.runtime.builtin.IRubyObject; ;TI"'import org.jruby.util.io.OpenFile;;T@o;	;[I"/public class Selector extends RubyObject {;To:RDoc::Markup::Verbatim;[I"Gprivate static final long serialVersionUID = -14562818539414873L;
;TI"2private java.nio.channels.Selector selector;
;TI"Dprivate HashMap<SelectableChannel,SelectionKey> cancelledKeys;
;TI"+private volatile boolean wakeupFired;
;TI"
;TI"=public Selector(final Ruby ruby, RubyClass rubyClass) {
;TI"!    super(ruby, rubyClass);
;TI"}
;TI"
;TI"@JRubyMethod(meta = true)
;TI"Spublic static IRubyObject backends(ThreadContext context, IRubyObject self) {
;TI"M    return context.runtime.newArray(context.runtime.newSymbol("java"));
;TI"}
;TI"
;TI"@JRubyMethod
;TI"<public IRubyObject initialize(ThreadContext context) {
;TI"A    initialize(context, context.runtime.newSymbol("java"));
;TI"    return context.nil;
;TI"}
;TI"
;TI"@JRubyMethod
;TI"Qpublic IRubyObject initialize(ThreadContext context, IRubyObject backend) {
;TI"P    if(backend != context.runtime.newSymbol("java") && !backend.isNil()) {
;TI"\        throw context.runtime.newArgumentError(":java is the only supported backend");
;TI"    }
;TI"
;TI"M    this.cancelledKeys = new HashMap<SelectableChannel,SelectionKey>();
;TI"#    this.wakeupFired = false;
;TI"
;TI"    try {
;TI"@        this.selector = java.nio.channels.Selector.open();
;TI"#    } catch(IOException ie) {
;TI"I        throw context.runtime.newIOError(ie.getLocalizedMessage());
;TI"    }
;TI"
;TI"    return context.nil;
;TI"}
;TI"
;TI"@JRubyMethod
;TI"9public IRubyObject backend(ThreadContext context) {
;TI"3    return context.runtime.newSymbol("java");
;TI"}
;TI"
;TI"@JRubyMethod
;TI"7public IRubyObject close(ThreadContext context) {
;TI"    try {
;TI"$        this.selector.close();
;TI"#    } catch(IOException ie) {
;TI"I        throw context.runtime.newIOError(ie.getLocalizedMessage());
;TI"    }
;TI"
;TI"    return context.nil;
;TI"}
;TI"
;TI"$@JRubyMethod(name = "closed?")
;TI":public IRubyObject isClosed(ThreadContext context) {
;TI".    Ruby runtime = context.getRuntime();
;TI"Q    return this.selector.isOpen() ? runtime.getFalse() : runtime.getTrue();
;TI"}
;TI"
;TI"#@JRubyMethod(name = "empty?")
;TI"9public IRubyObject isEmpty(ThreadContext context) {
;TI".    Ruby runtime = context.getRuntime();
;TI"Y    return this.selector.keys().isEmpty() ? runtime.getTrue() : runtime.getFalse();
;TI"}
;TI"
;TI"@JRubyMethod
;TI"apublic IRubyObject register(ThreadContext context, IRubyObject io, IRubyObject interests) {
;TI".    Ruby runtime = context.getRuntime();
;TI"L    Channel rawChannel = RubyIO.convertToIO(context, io).getChannel();
;TI"
;TI"'    if(!this.selector.isOpen()) {
;TI"J        throw context.getRuntime().newIOError("selector is closed");
;TI"    }
;TI"
;TI":    if(!(rawChannel instanceof SelectableChannel)) {
;TI"K        throw runtime.newArgumentError("not a selectable IO object");
;TI"    }
;TI"
;TI"D    SelectableChannel channel = (SelectableChannel)rawChannel;
;TI"
;TI"    try {
;TI"/        channel.configureBlocking(false);
;TI"#    } catch(IOException ie) {
;TI"A        throw runtime.newIOError(ie.getLocalizedMessage());
;TI"    }
;TI"
;TI"S    int interestOps = Nio4r.symbolToInterestOps(runtime, channel, interests);
;TI"    SelectionKey key;
;TI"
;TI"3    key = this.cancelledKeys.remove(channel);
;TI"
;TI"    if(key != null) {
;TI"+        key.interestOps(interestOps);
;TI"    } else {
;TI"        try {
;TI"E            key = channel.register(this.selector, interestOps);
;TI">        } catch(java.lang.IllegalArgumentException ia) {
;TI"e            throw runtime.newArgumentError("mode not supported for this object: " + interests);
;TI"E        } catch(java.nio.channels.ClosedChannelException cce) {
;TI"N            throw context.runtime.newIOError(cce.getLocalizedMessage());
;TI"        }
;TI"    }
;TI"
;TI"P    RubyClass monitorClass = runtime.getModule("NIO").getClass("Monitor");
;TI"b    Monitor monitor = (Monitor)monitorClass.newInstance(context, io, interests, this, null);
;TI"'    monitor.setSelectionKey(key);
;TI"
;TI"    return monitor;
;TI"}
;TI"
;TI"@JRubyMethod
;TI"Lpublic IRubyObject deregister(ThreadContext context, IRubyObject io) {
;TI".    Ruby runtime = context.getRuntime();
;TI"S    OpenFile file = RubyIO.convertToIO(context, io).getOpenFileInitialized();
;TI"     if (file.fd() == null)
;TI"!        return context.nil;
;TI".    Channel rawChannel = file.channel();
;TI"
;TI":    if(!(rawChannel instanceof SelectableChannel)) {
;TI"K        throw runtime.newArgumentError("not a selectable IO object");
;TI"    }
;TI"
;TI"D    SelectableChannel channel = (SelectableChannel)rawChannel;
;TI";    SelectionKey key = channel.keyFor(this.selector);
;TI"
;TI"    if(key == null)
;TI"!        return context.nil;
;TI"
;TI"6    Monitor monitor = (Monitor)key.attachment();
;TI"5    monitor.close(context, runtime.getFalse());
;TI"*    cancelledKeys.put(channel, key);
;TI"
;TI"    return monitor;
;TI"}
;TI"
;TI"(@JRubyMethod(name = "registered?")
;TI"Npublic IRubyObject isRegistered(ThreadContext context, IRubyObject io) {
;TI".    Ruby runtime = context.getRuntime();
;TI"L    Channel rawChannel = RubyIO.convertToIO(context, io).getChannel();
;TI"
;TI":    if(!(rawChannel instanceof SelectableChannel)) {
;TI"K        throw runtime.newArgumentError("not a selectable IO object");
;TI"    }
;TI"
;TI"D    SelectableChannel channel = (SelectableChannel)rawChannel;
;TI";    SelectionKey key = channel.keyFor(this.selector);
;TI"
;TI"    if(key == null)
;TI"!        return context.nil;
;TI"
;TI"R    if(((Monitor)key.attachment()).isClosed(context) == runtime.getTrue()) {
;TI"(        return runtime.getFalse();
;TI"    } else {
;TI"'        return runtime.getTrue();
;TI"    }
;TI"}
;TI"
;TI"@JRubyMethod
;TI"Rpublic synchronized IRubyObject select(ThreadContext context, Block block) {
;TI"5    return select(context, context.nil, block);
;TI"}
;TI"
;TI"@JRubyMethod
;TI"gpublic synchronized IRubyObject select(ThreadContext context, IRubyObject timeout, Block block) {
;TI".    Ruby runtime = context.getRuntime();
;TI"
;TI"'    if(!this.selector.isOpen()) {
;TI"J        throw context.getRuntime().newIOError("selector is closed");
;TI"    }
;TI"
;TI"#    this.wakeupFired = false;
;TI":    int ready = doSelect(runtime, context, timeout);
;TI"
;TI"       Timeout   
;TI"/    if(ready <= 0 && !this.wakeupFired) {
;TI"!        return context.nil;
;TI"    }
;TI"
;TI"$    RubyArray<?> array = null;
;TI"
;TI"     if(!block.isGiven()) {
;TI"L        array = runtime.newArray(this.selector.selectedKeys().size());
;TI"    }
;TI"
;TI"X    Iterator<SelectionKey> selectedKeys = this.selector.selectedKeys().iterator();
;TI")    while(selectedKeys.hasNext()) {
;TI"5        SelectionKey key = selectedKeys.next();
;TI"        processKey(key);
;TI"
;TI"$        selectedKeys.remove();
;TI"
;TI"#        if(block.isGiven()) {
;TI"E            block.call(context, (IRubyObject)key.attachment());
;TI"        } else {
;TI".            array.add(key.attachment());
;TI"        }
;TI"    }
;TI"
;TI"    if(block.isGiven()) {
;TI"9        return RubyNumeric.int2fix(runtime, ready);
;TI"    } else {
;TI"        return array;
;TI"    }
;TI"}
;TI"
;TI"   Run the selector   
;TI"Vprivate int doSelect(Ruby runtime, ThreadContext context, IRubyObject timeout) {
;TI"    int result;
;TI"
;TI"    cancelKeys();
;TI"    try {
;TI"7        context.getThread().beforeBlockingCall();
;TI"#        if(timeout.isNil()) {
;TI"2            result = this.selector.select();
;TI"        } else {
;TI":            double t = RubyNumeric.num2dbl(timeout);
;TI"            if(t == 0) {
;TI"9                result = this.selector.selectNow();
;TI"$            } else if(t < 0) {
;TI"W                throw runtime.newArgumentError("time interval must be positive");
;TI"            } else {
;TI"B                long timeoutMilliSeconds = (long)(t * 1000);
;TI"4                if(timeoutMilliSeconds == 0) {
;TI";                  result = this.selector.selectNow();
;TI"                } else {
;TI"K                  result = this.selector.select(timeoutMilliSeconds);
;TI"                }
;TI"            }
;TI"        }
;TI"6        context.getThread().afterBlockingCall();
;TI"        return result;
;TI"#    } catch(IOException ie) {
;TI"A        throw runtime.newIOError(ie.getLocalizedMessage());
;TI"    }
;TI"}
;TI"
;TI"7/* Flush our internal buffer of cancelled keys */
;TI"!private void cancelKeys() {
;TI"x    Iterator<Map.Entry<SelectableChannel, SelectionKey>> cancelledKeys = this.cancelledKeys.entrySet().iterator();
;TI"*    while(cancelledKeys.hasNext()) {
;TI"V        Map.Entry<SelectableChannel, SelectionKey> entry = cancelledKeys.next();
;TI"2        SelectionKey key = entry.getValue();
;TI"        key.cancel();
;TI"%        cancelledKeys.remove();
;TI"    }
;TI"}
;TI"
;TI"7// Remove connect interest from connected sockets
;TI"i// See: http://stackoverflow.com/questions/204186/java-nio-select-returns-without-selected-keys-why
;TI"1private void processKey(SelectionKey key) {
;TI"P    if(key.isValid() && (key.readyOps() & SelectionKey.OP_CONNECT) != 0) {
;TI"2        int interestOps = key.interestOps();
;TI"
;TI"6        interestOps &= ~SelectionKey.OP_CONNECT;
;TI"4        interestOps |=  SelectionKey.OP_WRITE;
;TI"
;TI"+        key.interestOps(interestOps);
;TI"    }
;TI"}
;TI"
;TI"@JRubyMethod
;TI"8public IRubyObject wakeup(ThreadContext context) {
;TI"'    if(!this.selector.isOpen()) {
;TI"J        throw context.getRuntime().newIOError("selector is closed");
;TI"    }
;TI"
;TI""    this.wakeupFired = true;
;TI"!    this.selector.wakeup();
;TI"
;TI"    return context.nil;
;TI"}
;T:@format0o;	;[I"};T:
@file@:0@omit_headings_from_table_of_contents_below0