Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 8cd8901f156b
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8bd23fbfe7a3
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Nov 5, 2014

  1. Fixes for selector shutdown logic.

    Without this logic the ENXIO selectors went back into the pool,
    carrying along their still-ready pipes. As a result, subsequent
    uses of those selectors returned immediately, and select would
    fail to produce results forever.
    headius committed Nov 5, 2014
    Copy the full SHA
    4e40345 View commit details
  2. Copy the full SHA
    8bd23fb View commit details
Showing with 36 additions and 6 deletions.
  1. +36 −5 core/src/main/java/org/jruby/util/io/SelectExecutor.java
  2. +0 −1 spec/tags/ruby/core/io/select_tags.txt
41 changes: 36 additions & 5 deletions core/src/main/java/org/jruby/util/io/SelectExecutor.java
Original file line number Diff line number Diff line change
@@ -58,15 +58,46 @@ IRubyObject selectEnd(ThreadContext context) throws IOException {
fdTerm(writeKeyList);
fdTerm(errorKeyList);

// clear cancelled keys (with selectNow) and return to pool
for (Selector selector : selectors.values()) {
try {
// if it is a JDK selector, cache it
if (selector.provider() == SelectorProvider.provider()) {
// clear cancelled keys (with selectNow) and return to pool
selector.selectNow();
} finally {
context.runtime.getSelectorPool().put(selector);
} else {
selector.close();
}
}

for (ENXIOSelector enxioSelector : enxioSelectors) {
enxioSelector.pipe.sink().close();
enxioSelector.pipe.source().close();
}

// TODO: reset blocking status
// if (readBlocking != null) {
// for (int i = 0; i < readBlocking.length; i++) {
// if (readBlocking[i] != null) {
// try {
// ((SelectableChannel) readIOs[i].getChannel()).configureBlocking(readBlocking[i]);
// } catch (IllegalBlockingModeException ibme) {
// throw runtime.newConcurrencyError("can not set IO blocking after select; concurrent select detected?");
// }
// }
// }
// }
// if (writeBlocking != null) {
// for (int i = 0; i < writeBlocking.length; i++) {
// if (writeBlocking[i] != null) {
// try {
// ((SelectableChannel) writeIOs[i].getChannel()).configureBlocking(writeBlocking[i]);
// } catch (IllegalBlockingModeException ibme) {
// throw runtime.newConcurrencyError("can not set IO blocking after select; concurrent select detected?");
// }
// }
// }
// }

return context.nil;
}

@@ -127,7 +158,7 @@ IRubyObject selectInternal(ThreadContext context) throws IOException {

int n = threadFdSelect(context);

if (pendingReadFDs != null && n == 0 && unselectableReadFDs == null && unselectableWriteFDs == null) return context.nil; /* returns nil on timeout */
if (pendingReadFDs == null && n == 0 && unselectableReadFDs == null && unselectableWriteFDs == null) return context.nil; /* returns nil on timeout */

res = RubyArray.newArray(runtime, 3);
res.push(runtime.newArray());
@@ -232,7 +263,7 @@ private boolean fdIsSet(List<SelectionKey> fds, ChannelFD fd, int operations) {
if (fds == null) return false;

for (SelectionKey key : fds) {
if (key.isValid() && ((Set<ChannelFD>)key.attachment()).contains(fd) && (key.readyOps() & operations) != 0) return true;
if (key.isValid() && (key.readyOps() & operations) != 0 && ((Set<ChannelFD>)key.attachment()).contains(fd)) return true;
}
return false;
}
1 change: 0 additions & 1 deletion spec/tags/ruby/core/io/select_tags.txt

This file was deleted.