--- a/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java Thu Apr 05 15:01:57 2018 +0100
@@ -63,20 +63,14 @@
// maps file descriptor to selection key, synchronize on selector
private final Map<Integer, SelectionKeyImpl> fdToKey = new HashMap<>();
- // pending new registrations/updates, queued by implRegister and putEventOpos
+ // pending new registrations/updates, queued by setEventOps
private final Object updateLock = new Object();
- private final Deque<SelectionKeyImpl> newKeys = new ArrayDeque<>();
private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
- private final Deque<Integer> updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
private boolean interruptTriggered;
- /**
- * Package private constructor called by factory method in
- * the abstract superclass Selector.
- */
EPollSelectorImpl(SelectorProvider sp) throws IOException {
super(sp);
@@ -140,30 +134,21 @@
}
/**
- * Process new registrations and changes to the interest ops.
+ * Process changes to the interest ops.
*/
private void processUpdateQueue() {
assert Thread.holdsLock(this);
synchronized (updateLock) {
SelectionKeyImpl ski;
-
- // new registrations
- while ((ski = newKeys.pollFirst()) != null) {
+ while ((ski = updateKeys.pollFirst()) != null) {
if (ski.isValid()) {
- int fd = ski.channel.getFDVal();
- SelectionKeyImpl previous = fdToKey.put(fd, ski);
- assert previous == null;
- assert ski.registeredEvents() == 0;
- }
- }
+ int fd = ski.getFDVal();
+ // add to fdToKey if needed
+ SelectionKeyImpl previous = fdToKey.putIfAbsent(fd, ski);
+ assert (previous == null) || (previous == ski);
- // changes to interest ops
- assert updateKeys.size() == updateEvents.size();
- while ((ski = updateKeys.pollFirst()) != null) {
- int newEvents = updateEvents.pollFirst();
- int fd = ski.channel.getFDVal();
- if (ski.isValid() && fdToKey.containsKey(fd)) {
+ int newEvents = ski.translateInterestOps();
int registeredEvents = ski.registeredEvents();
if (newEvents != registeredEvents) {
if (newEvents == 0) {
@@ -206,11 +191,11 @@
if (ski != null) {
int rOps = EPoll.getEvents(event);
if (selectedKeys.contains(ski)) {
- if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
+ if (ski.translateAndSetReadyOps(rOps)) {
numKeysUpdated++;
}
} else {
- ski.channel.translateAndSetReadyOps(rOps, ski);
+ ski.translateAndSetReadyOps(rOps);
if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
selectedKeys.add(ski);
numKeysUpdated++;
@@ -244,19 +229,11 @@
}
@Override
- protected void implRegister(SelectionKeyImpl ski) {
- ensureOpen();
- synchronized (updateLock) {
- newKeys.addLast(ski);
- }
- }
-
- @Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- int fd = ski.channel.getFDVal();
+ int fd = ski.getFDVal();
if (fdToKey.remove(fd) != null) {
if (ski.registeredEvents() != 0) {
EPoll.ctl(epfd, EPOLL_CTL_DEL, fd, 0);
@@ -268,10 +245,9 @@
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int events) {
+ public void setEventOps(SelectionKeyImpl ski) {
ensureOpen();
synchronized (updateLock) {
- updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Thu Apr 05 15:01:57 2018 +0100
@@ -62,11 +62,9 @@
// maps file descriptor to selection key, synchronize on selector
private final Map<Integer, SelectionKeyImpl> fdToKey = new HashMap<>();
- // pending new registrations/updates, queued by implRegister and putEventOps
+ // pending new registrations/updates, queued by setEventOps
private final Object updateLock = new Object();
- private final Deque<SelectionKeyImpl> newKeys = new ArrayDeque<>();
private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
- private final Deque<Integer> updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
@@ -138,30 +136,21 @@
}
/**
- * Process new registrations and changes to the interest ops.
+ * Process changes to the interest ops.
*/
private void processUpdateQueue() {
assert Thread.holdsLock(this);
synchronized (updateLock) {
SelectionKeyImpl ski;
-
- // new registrations
- while ((ski = newKeys.pollFirst()) != null) {
+ while ((ski = updateKeys.pollFirst()) != null) {
if (ski.isValid()) {
- int fd = ski.channel.getFDVal();
- SelectionKeyImpl previous = fdToKey.put(fd, ski);
- assert previous == null;
- assert ski.registeredEvents() == 0;
- }
- }
+ int fd = ski.getFDVal();
+ // add to fdToKey if needed
+ SelectionKeyImpl previous = fdToKey.putIfAbsent(fd, ski);
+ assert (previous == null) || (previous == ski);
- // changes to interest ops
- assert updateKeys.size() == updateKeys.size();
- while ((ski = updateKeys.pollFirst()) != null) {
- int newEvents = updateEvents.pollFirst();
- int fd = ski.channel.getFDVal();
- if (ski.isValid() && fdToKey.containsKey(fd)) {
+ int newEvents = ski.translateInterestOps();
int registeredEvents = ski.registeredEvents();
if (newEvents != registeredEvents) {
@@ -229,16 +218,16 @@
if (selectedKeys.contains(ski)) {
// file descriptor may be polled more than once per poll
if (ski.lastPolled != pollCount) {
- if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
+ if (ski.translateAndSetReadyOps(rOps)) {
numKeysUpdated++;
ski.lastPolled = pollCount;
}
} else {
// ready ops have already been set on this update
- ski.channel.translateAndUpdateReadyOps(rOps, ski);
+ ski.translateAndUpdateReadyOps(rOps);
}
} else {
- ski.channel.translateAndSetReadyOps(rOps, ski);
+ ski.translateAndSetReadyOps(rOps);
if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
selectedKeys.add(ski);
numKeysUpdated++;
@@ -273,19 +262,11 @@
}
@Override
- protected void implRegister(SelectionKeyImpl ski) {
- ensureOpen();
- synchronized (updateLock) {
- newKeys.addLast(ski);
- }
- }
-
- @Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- int fd = ski.channel.getFDVal();
+ int fd = ski.getFDVal();
int registeredEvents = ski.registeredEvents();
if (fdToKey.remove(fd) != null) {
if (registeredEvents != 0) {
@@ -301,10 +282,9 @@
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int events) {
+ public void setEventOps(SelectionKeyImpl ski) {
ensureOpen();
synchronized (updateLock) {
- updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}
--- a/src/java.base/share/classes/sun/nio/ch/SelChImpl.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/SelChImpl.java Thu Apr 05 15:01:57 2018 +0100
@@ -49,7 +49,7 @@
* contains at least one bit that the previous value did not
* contain
*/
- boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk);
+ boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski);
/**
* Sets the specified ops if present in interestOps. The specified
@@ -59,7 +59,7 @@
* contains at least one bit that the previous value did not
* contain
*/
- boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk);
+ boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski);
/**
* Translates an interest operation set into a native event set
--- a/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java Thu Apr 05 15:01:57 2018 +0100
@@ -39,7 +39,7 @@
public final class SelectionKeyImpl
extends AbstractSelectionKey
{
- final SelChImpl channel; // package-private
+ private final SelChImpl channel;
private final SelectorImpl selector;
private volatile int interestOps;
@@ -61,6 +61,10 @@
throw new CancelledKeyException();
}
+ int getFDVal() {
+ return channel.getFDVal();
+ }
+
@Override
public SelectableChannel channel() {
return (SelectableChannel)channel;
@@ -103,8 +107,8 @@
public SelectionKey nioInterestOps(int ops) {
if ((ops & ~channel().validOps()) != 0)
throw new IllegalArgumentException();
- selector.putEventOps(this, channel.translateInterestOps(ops));
interestOps = ops;
+ selector.setEventOps(this);
return this;
}
@@ -112,6 +116,18 @@
return interestOps;
}
+ int translateInterestOps() {
+ return channel.translateInterestOps(interestOps);
+ }
+
+ boolean translateAndSetReadyOps(int ops) {
+ return channel.translateAndSetReadyOps(ops, this);
+ }
+
+ boolean translateAndUpdateReadyOps(int ops) {
+ return channel.translateAndUpdateReadyOps(ops, this);
+ }
+
void registeredEvents(int events) {
// assert Thread.holdsLock(selector);
this.registeredEvents = events;
--- a/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java Thu Apr 05 15:01:57 2018 +0100
@@ -64,17 +64,20 @@
publicSelectedKeys = Util.ungrowableSet(selectedKeys);
}
+ private void ensureOpen() {
+ if (!isOpen())
+ throw new ClosedSelectorException();
+ }
+
@Override
public final Set<SelectionKey> keys() {
- if (!isOpen())
- throw new ClosedSelectorException();
+ ensureOpen();
return publicKeys;
}
@Override
public final Set<SelectionKey> selectedKeys() {
- if (!isOpen())
- throw new ClosedSelectorException();
+ ensureOpen();
return publicSelectedKeys;
}
@@ -112,8 +115,7 @@
private int lockAndDoSelect(long timeout) throws IOException {
synchronized (this) {
- if (!isOpen())
- throw new ClosedSelectorException();
+ ensureOpen();
synchronized (publicKeys) {
synchronized (publicSelectedKeys) {
return doSelect(timeout);
@@ -176,7 +178,8 @@
throw new IllegalSelectorException();
SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);
k.attach(attachment);
- // register before adding to key set
+
+ // register with selector (if needed) before adding to key set
implRegister(k);
synchronized (publicKeys) {
keys.add(k);
@@ -185,7 +188,15 @@
return k;
}
- protected abstract void implRegister(SelectionKeyImpl ski);
+ /**
+ * Register the key in the selector.
+ *
+ * The default implementation checks if the selector is open. It should
+ * be overridden by selector implementations as needed.
+ */
+ protected void implRegister(SelectionKeyImpl ski) {
+ ensureOpen();
+ }
protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
@@ -222,5 +233,5 @@
/**
* Change the event set in the selector
*/
- protected abstract void putEventOps(SelectionKeyImpl ski, int events);
+ protected abstract void setEventOps(SelectionKeyImpl ski);
}
--- a/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Thu Apr 05 15:01:57 2018 +0100
@@ -55,17 +55,14 @@
// maps file descriptor to selection key, synchronize on selector
private final Map<Integer, SelectionKeyImpl> fdToKey = new HashMap<>();
- // pending new registrations/updates, queued by implRegister and putEventOps
+ // pending new registrations/updates, queued by setEventOps
private final Object updateLock = new Object();
- private final Deque<SelectionKeyImpl> newKeys = new ArrayDeque<>();
private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
- private final Deque<Integer> updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
private boolean interruptTriggered;
-
DevPollSelectorImpl(SelectorProvider sp) throws IOException {
super(sp);
this.pollWrapper = new DevPollArrayWrapper();
@@ -88,18 +85,34 @@
}
@Override
- protected int doSelect(long timeout)
- throws IOException
- {
+ protected int doSelect(long timeout) throws IOException {
assert Thread.holdsLock(this);
- boolean blocking = (timeout != 0);
+
+ long to = timeout;
+ boolean blocking = (to != 0);
+ boolean timedPoll = (to > 0);
int numEntries;
processUpdateQueue();
processDeregisterQueue();
try {
begin(blocking);
- numEntries = pollWrapper.poll(timeout);
+
+ do {
+ long startTime = timedPoll ? System.nanoTime() : 0;
+ numEntries = pollWrapper.poll(to);
+ if (numEntries == IOStatus.INTERRUPTED && timedPoll) {
+ // timed poll interrupted so need to adjust timeout
+ long adjust = System.nanoTime() - startTime;
+ to -= TimeUnit.MILLISECONDS.convert(adjust, TimeUnit.NANOSECONDS);
+ if (to <= 0) {
+ // timeout expired so no retry
+ numEntries = 0;
+ }
+ }
+ } while (numEntries == IOStatus.INTERRUPTED);
+ assert IOStatus.check(numEntries);
+
} finally {
end(blocking);
}
@@ -108,7 +121,7 @@
}
/**
- * Process new registrations and changes to the interest ops.
+ * Process changes to the interest ops.
*/
private void processUpdateQueue() throws IOException {
assert Thread.holdsLock(this);
@@ -116,25 +129,18 @@
synchronized (updateLock) {
SelectionKeyImpl ski;
- // new registrations
- while ((ski = newKeys.pollFirst()) != null) {
- if (ski.isValid()) {
- int fd = ski.channel.getFDVal();
- SelectionKeyImpl previous = fdToKey.put(fd, ski);
- assert previous == null;
- assert ski.registeredEvents() == 0;
- }
- }
-
// Translate the queued updates to changes to the set of monitored
// file descriptors. The changes are written to the /dev/poll driver
// in bulk.
- assert updateKeys.size() == updateEvents.size();
int index = 0;
while ((ski = updateKeys.pollFirst()) != null) {
- int newEvents = updateEvents.pollFirst();
- int fd = ski.channel.getFDVal();
- if (ski.isValid() && fdToKey.containsKey(fd)) {
+ if (ski.isValid()) {
+ int fd = ski.getFDVal();
+ // add to fdToKey if needed
+ SelectionKeyImpl previous = fdToKey.putIfAbsent(fd, ski);
+ assert (previous == null) || (previous == ski);
+
+ int newEvents = ski.translateInterestOps();
int registeredEvents = ski.registeredEvents();
if (newEvents != registeredEvents) {
if (registeredEvents != 0)
@@ -178,11 +184,11 @@
if (ski != null) {
int rOps = pollWrapper.getReventOps(i);
if (selectedKeys.contains(ski)) {
- if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
+ if (ski.translateAndSetReadyOps(rOps)) {
numKeysUpdated++;
}
} else {
- ski.channel.translateAndSetReadyOps(rOps, ski);
+ ski.translateAndSetReadyOps(rOps);
if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
selectedKeys.add(ski);
numKeysUpdated++;
@@ -214,20 +220,13 @@
FileDispatcherImpl.closeIntFD(fd1);
}
- @Override
- protected void implRegister(SelectionKeyImpl ski) {
- ensureOpen();
- synchronized (updateLock) {
- newKeys.addLast(ski);
- }
- }
@Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- int fd = ski.channel.getFDVal();
+ int fd = ski.getFDVal();
if (fdToKey.remove(fd) != null) {
if (ski.registeredEvents() != 0) {
pollWrapper.register(fd, POLLREMOVE);
@@ -239,10 +238,9 @@
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int events) {
+ public void setEventOps(SelectionKeyImpl ski) {
ensureOpen();
synchronized (updateLock) {
- updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}
--- a/src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java Thu Apr 05 15:01:57 2018 +0100
@@ -72,12 +72,10 @@
// the last update operation, incremented by processUpdateQueue
private int lastUpdate;
- // pending new registrations/updates, queued by implRegister, putEventOps,
- // and updateSelectedKeys
+ // pending new registrations/updates, queued by setEventOps and
+ // updateSelectedKeys
private final Object updateLock = new Object();
- private final Deque<SelectionKeyImpl> newKeys = new ArrayDeque<>();
private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
- private final Deque<Integer> updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
@@ -146,23 +144,14 @@
synchronized (updateLock) {
SelectionKeyImpl ski;
-
- // new registrations
- while ((ski = newKeys.pollFirst()) != null) {
+ while ((ski = updateKeys.pollFirst()) != null) {
if (ski.isValid()) {
- int fd = ski.channel.getFDVal();
- SelectionKeyImpl previous = fdToKey.put(fd, ski);
- assert previous == null;
- assert ski.registeredEvents() == 0;
- }
- }
+ int fd = ski.getFDVal();
+ // add to fdToKey if needed
+ SelectionKeyImpl previous = fdToKey.putIfAbsent(fd, ski);
+ assert (previous == null) || (previous == ski);
- // changes to interest ops
- assert updateKeys.size() == updateEvents.size();
- while ((ski = updateKeys.pollFirst()) != null) {
- int newEvents = updateEvents.pollFirst();
- int fd = ski.channel.getFDVal();
- if (ski.isValid() && fdToKey.containsKey(fd)) {
+ int newEvents = ski.translateInterestOps();
if (newEvents != ski.registeredEvents()) {
if (newEvents == 0) {
port_dissociate(pfd, PORT_SOURCE_FD, fd);
@@ -199,22 +188,20 @@
if (ski != null) {
int rOps = getEventOps(i);
if (selectedKeys.contains(ski)) {
- if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
+ if (ski.translateAndSetReadyOps(rOps)) {
numKeysUpdated++;
}
} else {
- ski.channel.translateAndSetReadyOps(rOps, ski);
+ ski.translateAndSetReadyOps(rOps);
if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
selectedKeys.add(ski);
numKeysUpdated++;
}
}
- // re-queue key to head so that it is re-associated at
- // next select (and before other changes)
- updateEvents.addFirst(ski.registeredEvents());
- updateKeys.addFirst(ski);
+ // re-queue key so it re-associated at next select
ski.registeredEvents(0);
+ updateKeys.addLast(ski);
}
} else if (source == PORT_SOURCE_USER) {
interrupted = true;
@@ -245,19 +232,11 @@
}
@Override
- protected void implRegister(SelectionKeyImpl ski) {
- ensureOpen();
- synchronized (updateLock) {
- newKeys.addLast(ski);
- }
- }
-
- @Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- int fd = ski.channel.getFDVal();
+ int fd = ski.getFDVal();
if (fdToKey.remove(fd) != null) {
if (ski.registeredEvents() != 0) {
port_dissociate(pfd, PORT_SOURCE_FD, fd);
@@ -269,10 +248,9 @@
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int events) {
+ public void setEventOps(SelectionKeyImpl ski) {
ensureOpen();
synchronized (updateLock) {
- updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}
--- a/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c Thu Apr 05 15:01:57 2018 +0100
@@ -23,84 +23,20 @@
* questions.
*/
+#include <sys/devpoll.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jlong.h"
-#include "sun_nio_ch_DevPollArrayWrapper.h"
-#include <poll.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef uint32_t caddr32_t;
-
-/* /dev/poll ioctl */
-#define DPIOC (0xD0 << 8)
-#define DP_POLL (DPIOC | 1) /* poll on fds in cached in /dev/poll */
-#define DP_ISPOLLED (DPIOC | 2) /* is this fd cached in /dev/poll */
-#define DEVPOLLSIZE 1000 /* /dev/poll table size increment */
-#define POLLREMOVE 0x0800 /* Removes fd from monitored set */
-
-/*
- * /dev/poll DP_POLL ioctl format
- */
-typedef struct dvpoll {
- pollfd_t *dp_fds; /* pollfd array */
- nfds_t dp_nfds; /* num of pollfd's in dp_fds[] */
- int dp_timeout; /* time out in millisec */
-} dvpoll_t;
-
-typedef struct dvpoll32 {
- caddr32_t dp_fds; /* pollfd array */
- uint32_t dp_nfds; /* num of pollfd's in dp_fds[] */
- int32_t dp_timeout; /* time out in millisec */
-} dvpoll32_t;
-
-#ifdef __cplusplus
-}
-#endif
+#include "nio.h"
+#include "nio_util.h"
-#define RESTARTABLE(_cmd, _result) do { \
- do { \
- _result = _cmd; \
- } while((_result == -1) && (errno == EINTR)); \
-} while(0)
-
-static int
-idevpoll(jint wfd, int dpctl, struct dvpoll a)
-{
- jlong start, now;
- int remaining = a.dp_timeout;
- struct timeval t;
- int diff;
-
- gettimeofday(&t, NULL);
- start = t.tv_sec * 1000 + t.tv_usec / 1000;
-
- for (;;) {
- /* poll(7d) ioctl does not return remaining count */
- int res = ioctl(wfd, dpctl, &a);
- if (res < 0 && errno == EINTR) {
- if (remaining >= 0) {
- gettimeofday(&t, NULL);
- now = t.tv_sec * 1000 + t.tv_usec / 1000;
- diff = now - start;
- remaining -= diff;
- if (diff < 0 || remaining <= 0) {
- return 0;
- }
- start = now;
- a.dp_timeout = remaining;
- }
- } else {
- return res;
- }
- }
-}
+#include "sun_nio_ch_DevPollArrayWrapper.h"
JNIEXPORT jint JNICALL
Java_sun_nio_ch_DevPollArrayWrapper_init(JNIEnv *env, jobject this)
@@ -153,26 +89,24 @@
JNIEXPORT jint JNICALL
Java_sun_nio_ch_DevPollArrayWrapper_poll0(JNIEnv *env, jobject this,
- jlong address, jint numfds,
- jlong timeout, jint wfd)
+ jlong address, jint numfds,
+ jlong timeout, jint wfd)
{
struct dvpoll a;
void *pfd = (void *) jlong_to_ptr(address);
- int result = 0;
+ int result;
a.dp_fds = pfd;
a.dp_nfds = numfds;
a.dp_timeout = (int)timeout;
-
- if (timeout <= 0) { /* Indefinite or no wait */
- RESTARTABLE (ioctl(wfd, DP_POLL, &a), result);
- } else { /* Bounded wait; bounded restarts */
- result = idevpoll(wfd, DP_POLL, a);
- }
-
+ result = ioctl(wfd, DP_POLL, &a);
if (result < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "Error reading driver");
- return -1;
+ if (errno == EINTR) {
+ return IOS_INTERRUPTED;
+ } else {
+ JNU_ThrowIOExceptionWithLastError(env, "Error reading driver");
+ return IOS_THROWN;
+ }
}
return result;
}
--- a/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java Thu Apr 05 15:01:57 2018 +0100
@@ -60,7 +60,6 @@
// pending updates, queued by putEventOps
private final Object updateLock = new Object();
private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
- private final Deque<Integer> updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
@@ -136,10 +135,9 @@
assert Thread.holdsLock(this);
synchronized (updateLock) {
- assert updateKeys.size() == updateEvents.size();
SelectionKeyImpl ski;
while ((ski = updateKeys.pollFirst()) != null) {
- int newEvents = updateEvents.pollFirst();
+ int newEvents = ski.translateInterestOps();
if (ski.isValid()) {
int index = ski.getIndex();
assert index >= 0 && index < pollArraySize;
@@ -173,14 +171,14 @@
int rOps = getReventOps(i);
if (rOps != 0) {
SelectionKeyImpl ski = pollKeys.get(i);
- assert ski.channel.getFDVal() == getDescriptor(i);
+ assert ski.getFDVal() == getDescriptor(i);
if (ski.isValid()) {
if (selectedKeys.contains(ski)) {
- if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
+ if (ski.translateAndSetReadyOps(rOps)) {
numKeysUpdated++;
}
} else {
- ski.channel.translateAndSetReadyOps(rOps, ski);
+ ski.translateAndSetReadyOps(rOps);
if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
selectedKeys.add(ski);
numKeysUpdated++;
@@ -233,10 +231,9 @@
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int events) {
+ public void setEventOps(SelectionKeyImpl ski) {
ensureOpen();
synchronized (updateLock) {
- updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}
@@ -285,7 +282,7 @@
int index = pollArraySize;
assert index > 0;
- putDescriptor(index, ski.channel.getFDVal());
+ putDescriptor(index, ski.getFDVal());
putEventOps(index, ops);
putReventOps(index, 0);
ski.setIndex(index);
@@ -301,7 +298,7 @@
private void update(SelectionKeyImpl ski, int ops) {
int index = ski.getIndex();
assert index > 0 && index < pollArraySize;
- assert getDescriptor(index) == ski.channel.getFDVal();
+ assert getDescriptor(index) == ski.getFDVal();
putEventOps(index, ops);
}
@@ -311,7 +308,7 @@
private void remove(SelectionKeyImpl ski) {
int index = ski.getIndex();
assert index > 0 && index < pollArraySize;
- assert getDescriptor(index) == ski.channel.getFDVal();
+ assert getDescriptor(index) == ski.getFDVal();
// replace pollfd at index with the last pollfd in array
int lastIndex = pollArraySize - 1;
@@ -321,7 +318,7 @@
int lastFd = getDescriptor(lastIndex);
int lastOps = getEventOps(lastIndex);
int lastRevents = getReventOps(lastIndex);
- assert lastKey.channel.getFDVal() == lastFd;
+ assert lastKey.getFDVal() == lastFd;
putDescriptor(index, lastFd);
putEventOps(index, lastOps);
putReventOps(index, lastRevents);
--- a/src/java.base/windows/classes/sun/nio/ch/PollArrayWrapper.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/windows/classes/sun/nio/ch/PollArrayWrapper.java Thu Apr 05 15:01:57 2018 +0100
@@ -64,7 +64,7 @@
// Prepare another pollfd struct for use.
void putEntry(int index, SelectionKeyImpl ski) {
- putDescriptor(index, ski.channel.getFDVal());
+ putDescriptor(index, ski.getFDVal());
putEventOps(index, 0);
}
--- a/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Thu Apr 05 09:55:16 2018 +0200
+++ b/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Thu Apr 05 15:01:57 2018 +0100
@@ -83,12 +83,12 @@
return get(Integer.valueOf(desc));
}
private MapEntry put(SelectionKeyImpl ski) {
- return put(Integer.valueOf(ski.channel.getFDVal()), new MapEntry(ski));
+ return put(Integer.valueOf(ski.getFDVal()), new MapEntry(ski));
}
private MapEntry remove(SelectionKeyImpl ski) {
- Integer fd = Integer.valueOf(ski.channel.getFDVal());
+ Integer fd = Integer.valueOf(ski.getFDVal());
MapEntry x = get(fd);
- if ((x != null) && (x.ski.channel == ski.channel))
+ if ((x != null) && (x.ski.channel() == ski.channel()))
return remove(fd);
return null;
}
@@ -114,11 +114,10 @@
private final Object interruptLock = new Object();
private volatile boolean interruptTriggered;
- // pending new registrations/updates, queued by implRegister and putEventOps
+ // pending new registrations/updates, queued by implRegister and setEventOps
private final Object updateLock = new Object();
private final Deque<SelectionKeyImpl> newKeys = new ArrayDeque<>();
private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
- private final Deque<Integer> updateEvents = new ArrayDeque<>();
WindowsSelectorImpl(SelectorProvider sp) throws IOException {
@@ -204,10 +203,9 @@
}
// changes to interest ops
- assert updateKeys.size() == updateEvents.size();
while ((ski = updateKeys.pollFirst()) != null) {
- int events = updateEvents.pollFirst();
- int fd = ski.channel.getFDVal();
+ int events = ski.translateInterestOps();
+ int fd = ski.getFDVal();
if (ski.isValid() && fdMap.containsKey(fd)) {
int index = ski.getIndex();
assert index >= 0 && index < totalChannels;
@@ -408,13 +406,13 @@
if (selectedKeys.contains(sk)) { // Key in selected set
if (me.clearedCount != updateCount) {
- if (sk.channel.translateAndSetReadyOps(rOps, sk) &&
+ if (sk.translateAndSetReadyOps(rOps) &&
(me.updateCount != updateCount)) {
me.updateCount = updateCount;
numKeysUpdated++;
}
} else { // The readyOps have been set; now add
- if (sk.channel.translateAndUpdateReadyOps(rOps, sk) &&
+ if (sk.translateAndUpdateReadyOps(rOps) &&
(me.updateCount != updateCount)) {
me.updateCount = updateCount;
numKeysUpdated++;
@@ -423,14 +421,14 @@
me.clearedCount = updateCount;
} else { // Key is not in selected set yet
if (me.clearedCount != updateCount) {
- sk.channel.translateAndSetReadyOps(rOps, sk);
+ sk.translateAndSetReadyOps(rOps);
if ((sk.nioReadyOps() & sk.nioInterestOps()) != 0) {
selectedKeys.add(sk);
me.updateCount = updateCount;
numKeysUpdated++;
}
} else { // The readyOps have been set; now add
- sk.channel.translateAndUpdateReadyOps(rOps, sk);
+ sk.translateAndUpdateReadyOps(rOps);
if ((sk.nioReadyOps() & sk.nioInterestOps()) != 0) {
selectedKeys.add(sk);
me.updateCount = updateCount;
@@ -613,10 +611,9 @@
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int events) {
+ public void setEventOps(SelectionKeyImpl ski) {
ensureOpen();
synchronized (updateLock) {
- updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}