From aa86257ae333f0c97290ba88d8864315cc684438 Mon Sep 17 00:00:00 2001 From: alanb Date: Wed, 18 Sep 2013 14:10:24 +0100 Subject: [PATCH] 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx) Reviewed-by: alanb, coffeys Contributed-by: nmaurer@redhat.com, alan.bateman@oracle.com --- .../sun/nio/ch/DevPollArrayWrapper.java | 7 +++++-- .../classes/sun/nio/ch/EPollArrayWrapper.java | 18 +++++++++++++++--- .../classes/sun/nio/ch/EventPortWrapper.java | 12 +++++++++--- .../nio/channels/Selector/LotsOfChannels.java | 5 +++-- .../nio/channels/Selector/SelectorLimit.java | 3 ++- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java b/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java index df30e2924..6eeee2a75 100644 --- a/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java +++ b/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java @@ -26,9 +26,11 @@ package sun.nio.ch; import java.io.IOException; +import java.security.AccessController; import java.util.BitSet; import java.util.Map; import java.util.HashMap; +import sun.security.action.GetIntegerAction; /** @@ -78,10 +80,11 @@ class DevPollArrayWrapper { static final int NUM_POLLFDS = Math.min(OPEN_MAX-1, 8192); // Initial size of arrays for fd registration changes - private final int INITIAL_PENDING_UPDATE_SIZE = 64; + private static final int INITIAL_PENDING_UPDATE_SIZE = 64; // maximum size of updatesLow - private final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); + private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( + new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); // The pollfd array for results from devpoll driver private final AllocatedNativeObject pollArray; diff --git a/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java b/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java index a73d3c2df..f64feb24c 100644 --- a/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java +++ b/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java @@ -26,9 +26,11 @@ package sun.nio.ch; import java.io.IOException; +import java.security.AccessController; import java.util.BitSet; import java.util.HashMap; import java.util.Map; +import sun.security.action.GetIntegerAction; /** * Manipulates a native array of epoll_event structs on Linux: @@ -78,8 +80,8 @@ class EPollArrayWrapper { private static final int INITIAL_PENDING_UPDATE_SIZE = 64; // maximum size of updatesLow - private static final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); - + private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( + new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); // The fd of the epoll driver private final int epfd; @@ -163,6 +165,16 @@ class EPollArrayWrapper { return pollArray.getInt(offset); } + /** + * Returns {@code true} if updates for the given key (file + * descriptor) are killed. + */ + private boolean isEventsHighKilled(Integer key) { + assert key >= MAX_UPDATE_ARRAY_SIZE; + Byte value = eventsHigh.get(key); + return (value != null && value == KILLED); + } + /** * Sets the pending update events for the given file descriptor. This * method has no effect if the update events is already set to KILLED, @@ -175,7 +187,7 @@ class EPollArrayWrapper { } } else { Integer key = Integer.valueOf(fd); - if ((eventsHigh.get(key) != KILLED) || force) { + if (!isEventsHighKilled(key) || force) { eventsHigh.put(key, Byte.valueOf(events)); } } diff --git a/src/solaris/classes/sun/nio/ch/EventPortWrapper.java b/src/solaris/classes/sun/nio/ch/EventPortWrapper.java index bec373606..d9383eb7e 100644 --- a/src/solaris/classes/sun/nio/ch/EventPortWrapper.java +++ b/src/solaris/classes/sun/nio/ch/EventPortWrapper.java @@ -25,9 +25,14 @@ package sun.nio.ch; -import sun.misc.Unsafe; import java.io.IOException; -import java.util.*; +import java.security.AccessController; +import java.util.BitSet; +import java.util.HashMap; +import java.util.Map; + +import sun.misc.Unsafe; +import sun.security.action.GetIntegerAction; import static sun.nio.ch.SolarisEventPort.*; /** @@ -49,7 +54,8 @@ class EventPortWrapper { private final int INITIAL_PENDING_UPDATE_SIZE = 256; // maximum size of updateArray - private final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); + private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( + new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); // special update status to indicate that it should be ignored private static final byte IGNORE = -1; diff --git a/test/java/nio/channels/Selector/LotsOfChannels.java b/test/java/nio/channels/Selector/LotsOfChannels.java index d88655d80..2db6366a7 100644 --- a/test/java/nio/channels/Selector/LotsOfChannels.java +++ b/test/java/nio/channels/Selector/LotsOfChannels.java @@ -22,9 +22,10 @@ */ /* @test - * @bug 4503092 + * @bug 4503092 8024883 * @summary Tests that Windows Selector can use more than 63 channels - * @run main/timeout=300 LotsOfChannels + * @run main LotsOfChannels + * @run main/othervm -Dsun.nio.ch.maxUpdateArraySize=64 LotsOfChannels * @author kladko */ diff --git a/test/java/nio/channels/Selector/SelectorLimit.java b/test/java/nio/channels/Selector/SelectorLimit.java index 27589e246..69963db8e 100644 --- a/test/java/nio/channels/Selector/SelectorLimit.java +++ b/test/java/nio/channels/Selector/SelectorLimit.java @@ -22,12 +22,13 @@ */ /* @test - * @bug 4777504 + * @bug 4777504 8024883 * @summary Ensure that a Selector can return at least 100 selected keys * @author Mark Reinhold * @library .. * @build SelectorLimit * @run main/othervm SelectorLimit + * @run main/othervm -Dsun.nio.ch.maxUpdateArraySize=128 SelectorLimit */ import java.io.*; -- GitLab