src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
changeset 49493 814bd31f8da0
parent 49417 1d3139252c1c
child 49526 cad4c844902a
--- 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);
         }
     }