--- a/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Thu Mar 29 22:12:05 2018 -0700
+++ b/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Fri Mar 30 08:28:09 2018 +0100
@@ -27,15 +27,11 @@
import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
import java.util.ArrayDeque;
-import java.util.BitSet;
import java.util.Deque;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -59,14 +55,11 @@
// maps file descriptor to selection key, synchronize on selector
private final Map<Integer, SelectionKeyImpl> fdToKey = new HashMap<>();
- // file descriptors registered with /dev/poll, synchronize on selector
- private final BitSet registered = new BitSet();
-
// pending new registrations/updates, queued by implRegister and putEventOps
private final Object updateLock = new Object();
private final Deque<SelectionKeyImpl> newKeys = new ArrayDeque<>();
private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
- private final Deque<Integer> updateOps = new ArrayDeque<>();
+ private final Deque<Integer> updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
@@ -99,15 +92,16 @@
throws IOException
{
assert Thread.holdsLock(this);
+ boolean blocking = (timeout != 0);
int numEntries;
processUpdateQueue();
processDeregisterQueue();
try {
- begin();
+ begin(blocking);
numEntries = pollWrapper.poll(timeout);
} finally {
- end();
+ end(blocking);
}
processDeregisterQueue();
return updateSelectedKeys(numEntries);
@@ -125,41 +119,35 @@
// new registrations
while ((ski = newKeys.pollFirst()) != null) {
if (ski.isValid()) {
- SelChImpl ch = ski.channel;
- int fd = ch.getFDVal();
+ int fd = ski.channel.getFDVal();
SelectionKeyImpl previous = fdToKey.put(fd, ski);
assert previous == null;
- assert registered.get(fd) == false;
+ 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() == updateOps.size();
+ assert updateKeys.size() == updateEvents.size();
int index = 0;
while ((ski = updateKeys.pollFirst()) != null) {
- int ops = updateOps.pollFirst();
+ int newEvents = updateEvents.pollFirst();
int fd = ski.channel.getFDVal();
if (ski.isValid() && fdToKey.containsKey(fd)) {
- if (registered.get(fd)) {
- if (ops == 0) {
- // remove file descriptor
- pollWrapper.putPollFD(index++, fd, POLLREMOVE);
- registered.clear(fd);
- } else {
- // change events
+ int registeredEvents = ski.registeredEvents();
+ if (newEvents != registeredEvents) {
+ if (registeredEvents != 0)
pollWrapper.putPollFD(index++, fd, POLLREMOVE);
- pollWrapper.putPollFD(index++, fd, (short)ops);
+ if (newEvents != 0)
+ pollWrapper.putPollFD(index++, fd, (short)newEvents);
+ ski.registeredEvents(newEvents);
+
+ // write to /dev/poll
+ if (index > (NUM_POLLFDS-2)) {
+ pollWrapper.registerMultiple(index);
+ index = 0;
}
- } else if (ops != 0) {
- // add file descriptor
- pollWrapper.putPollFD(index++, fd, (short)ops);
- registered.set(fd);
- }
- if (index > (NUM_POLLFDS-2)) {
- pollWrapper.registerMultiple(index);
- index = 0;
}
}
}
@@ -171,8 +159,9 @@
}
/**
- * Update the keys whose fd's have been selected by the /dev/poll.
- * Add the ready keys to the ready queue.
+ * Update the keys of file descriptors that were polled and add them to
+ * the selected-key set.
+ * If the interrupt fd has been selected, drain it and clear the interrupt.
*/
private int updateSelectedKeys(int numEntries) throws IOException {
assert Thread.holdsLock(this);
@@ -214,7 +203,6 @@
protected void implClose() throws IOException {
assert !isOpen();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
// prevent further wakeup
synchronized (interruptLock) {
@@ -224,59 +212,37 @@
pollWrapper.close();
FileDispatcherImpl.closeIntFD(fd0);
FileDispatcherImpl.closeIntFD(fd1);
-
- // Deregister channels
- Iterator<SelectionKey> i = keys.iterator();
- while (i.hasNext()) {
- SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
- deregister(ski);
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
- i.remove();
- }
}
@Override
protected void implRegister(SelectionKeyImpl ski) {
- assert Thread.holdsLock(nioKeys());
ensureOpen();
synchronized (updateLock) {
newKeys.addLast(ski);
}
- keys.add(ski);
}
@Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
- assert Thread.holdsLock(nioSelectedKeys());
int fd = ski.channel.getFDVal();
- fdToKey.remove(fd);
- if (registered.get(fd)) {
- pollWrapper.register(fd, POLLREMOVE);
- registered.clear(fd);
+ if (fdToKey.remove(fd) != null) {
+ if (ski.registeredEvents() != 0) {
+ pollWrapper.register(fd, POLLREMOVE);
+ ski.registeredEvents(0);
+ }
+ } else {
+ assert ski.registeredEvents() == 0;
}
-
- selectedKeys.remove(ski);
- keys.remove(ski);
-
- // remove from channel's key set
- deregister(ski);
-
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl) selch).kill();
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int ops) {
+ public void putEventOps(SelectionKeyImpl ski, int events) {
ensureOpen();
synchronized (updateLock) {
- updateOps.addLast(ops); // ops first in case adding the key fails
+ updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}