src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java

Print this page




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.nio.ch;
  27 
  28 import java.io.IOException;
  29 import java.nio.channels.*;
  30 import java.nio.channels.spi.*;
  31 import java.util.*;
  32 import sun.misc.*;
  33 
  34 
  35 /**
  36  * An implementation of Selector for Solaris.
  37  */
  38 class DevPollSelectorImpl
  39     extends SelectorImpl
  40 {
  41 
  42     // File descriptors used for interrupt
  43     protected int fd0;
  44     protected int fd1;
  45 
  46     // The poll object
  47     DevPollArrayWrapper pollWrapper;
  48 
  49     // Maps from file descriptors to keys
  50     private Map<Integer,SelectionKeyImpl> fdToKey;
  51 
  52     // True if this Selector has been closed
  53     private boolean closed = false;
  54 
  55     // Lock for close/cleanup
  56     private Object closeLock = new Object();
  57 
  58     // Lock for interrupt triggering and clearing
  59     private Object interruptLock = new Object();
  60     private boolean interruptTriggered = false;
  61 
  62     /**
  63      * Package private constructor called by factory method in
  64      * the abstract superclass Selector.
  65      */
  66     DevPollSelectorImpl(SelectorProvider sp) {
  67         super(sp);
  68         long pipeFds = IOUtil.makePipe(false);
  69         fd0 = (int) (pipeFds >>> 32);
  70         fd1 = (int) pipeFds;
  71         pollWrapper = new DevPollArrayWrapper();
  72         pollWrapper.initInterrupt(fd0, fd1);
  73         fdToKey = new HashMap<Integer,SelectionKeyImpl>();
  74     }
  75 
  76     protected int doSelect(long timeout)
  77         throws IOException
  78     {
  79         if (closed)
  80             throw new ClosedSelectorException();
  81         processDeregisterQueue();
  82         try {
  83             begin();
  84             pollWrapper.poll(timeout);
  85         } finally {
  86             end();
  87         }
  88         processDeregisterQueue();
  89         int numKeysUpdated = updateSelectedKeys();


























  90         if (pollWrapper.interrupted()) {
  91             // Clear the wakeup pipe
  92             pollWrapper.putReventOps(pollWrapper.interruptedIndex(), 0);
  93             synchronized (interruptLock) {
  94                 pollWrapper.clearInterrupted();
  95                 IOUtil.drain(fd0);
  96                 interruptTriggered = false;
  97             }
  98         }
  99         return numKeysUpdated;












 100     }
 101 
 102     /**
 103      * Update the keys whose fd's have been selected by the devpoll
 104      * driver. Add the ready keys to the ready queue.
 105      */
 106     private int updateSelectedKeys() {
 107         int entries = pollWrapper.updated;
 108         int numKeysUpdated = 0;
 109         for (int i=0; i<entries; i++) {
 110             int nextFD = pollWrapper.getDescriptor(i);
 111             SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
 112             // ski is null in the case of an interrupt
 113             if (ski != null) {
 114                 int rOps = pollWrapper.getReventOps(i);
 115                 if (selectedKeys.contains(ski)) {
 116                     if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
 117                         numKeysUpdated++;
 118                     }
 119                 } else {
 120                     ski.channel.translateAndSetReadyOps(rOps, ski);
 121                     if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
 122                         selectedKeys.add(ski);
 123                         numKeysUpdated++;
 124                     }
 125                 }
 126             }
 127         }
 128         return numKeysUpdated;
 129     }
 130 
 131     protected void implClose() throws IOException {
 132         if (closed)
 133             return;
 134         closed = true;
 135 
 136         // prevent further wakeup
 137         synchronized (interruptLock) {
 138             interruptTriggered = true;
 139         }
 140 
 141         FileDispatcherImpl.closeIntFD(fd0);




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.nio.ch;
  27 
  28 import java.io.IOException;
  29 import java.nio.channels.*;
  30 import java.nio.channels.spi.*;
  31 import java.util.*;
  32 import java.util.function.Consumer;
  33 
  34 
  35 /**
  36  * An implementation of Selector for Solaris.
  37  */
  38 class DevPollSelectorImpl
  39     extends SelectorImpl
  40 {
  41 
  42     // File descriptors used for interrupt
  43     protected int fd0;
  44     protected int fd1;
  45 
  46     // The poll object
  47     DevPollArrayWrapper pollWrapper;
  48 
  49     // Maps from file descriptors to keys
  50     private Map<Integer,SelectionKeyImpl> fdToKey;
  51 
  52     // True if this Selector has been closed
  53     private boolean closed = false;
  54 



  55     // Lock for interrupt triggering and clearing
  56     private Object interruptLock = new Object();
  57     private boolean interruptTriggered = false;
  58 
  59     /**
  60      * Package private constructor called by factory method in
  61      * the abstract superclass Selector.
  62      */
  63     DevPollSelectorImpl(SelectorProvider sp) {
  64         super(sp);
  65         long pipeFds = IOUtil.makePipe(false);
  66         fd0 = (int) (pipeFds >>> 32);
  67         fd1 = (int) pipeFds;
  68         pollWrapper = new DevPollArrayWrapper();
  69         pollWrapper.initInterrupt(fd0, fd1);
  70         fdToKey = new HashMap<>();
  71     }
  72 
  73     @Override
  74     protected int doSelect(long timeout) throws IOException {
  75         pollDevPollWrapper(timeout);



  76         try {
  77             return updateSelectedKeys();

  78         } finally {
  79             clearWakeupPipeIfInterrupted();
  80         }
  81     }
  82 
  83     @Override
  84     protected int doSelect(Consumer<SelectionKey> handler, long timeout) throws IOException {
  85         pollDevPollWrapper(timeout);
  86         try {
  87             int entries = pollWrapper.updated;
  88             int numKeysUpdated = 0;
  89             for (int i=0; i<entries; i++) {
  90                 int nextFD = pollWrapper.getDescriptor(i);
  91                 SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
  92                 // ski is null in the case of an interrupt
  93                 if (ski != null) {
  94                     int rOps = pollWrapper.getReventOps(i);
  95                     ski.channel.translateAndSetReadyOps(rOps, ski);
  96                     if (ski.hasOps()) {
  97                         handler.accept(ski);
  98                         numKeysUpdated++;
  99                     }
 100                 }
 101             }
 102             return numKeysUpdated;
 103         } finally {
 104             clearWakeupPipeIfInterrupted();
 105         }
 106     }
 107 
 108     private void clearWakeupPipeIfInterrupted() throws IOException {
 109         if (pollWrapper.interrupted()) {
 110             // Clear the wakeup pipe
 111             pollWrapper.putReventOps(pollWrapper.interruptedIndex(), 0);
 112             synchronized (interruptLock) {
 113                 pollWrapper.clearInterrupted();
 114                 IOUtil.drain(fd0);
 115                 interruptTriggered = false;
 116             }
 117         }
 118     }
 119 
 120     private void pollDevPollWrapper(long timeout) throws ClosedSelectorException, IOException {
 121         if (closed)
 122             throw new ClosedSelectorException();
 123         processDeregisterQueue();
 124         try {
 125             begin();
 126             pollWrapper.poll(timeout);
 127         } finally {
 128             end();
 129         }
 130         processDeregisterQueue();
 131     }
 132 
 133     /**
 134      * Update the keys whose fd's have been selected by the devpoll
 135      * driver. Add the ready keys to the ready queue.
 136      */
 137     private int updateSelectedKeys() {
 138         int entries = pollWrapper.updated;
 139         int numKeysUpdated = 0;
 140         for (int i=0; i<entries; i++) {
 141             int nextFD = pollWrapper.getDescriptor(i);
 142             SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
 143             // ski is null in the case of an interrupt
 144             if (ski != null) {
 145                 int rOps = pollWrapper.getReventOps(i);
 146                 if (selectedKeys.contains(ski)) {
 147                     if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
 148                         numKeysUpdated++;
 149                     }
 150                 } else {
 151                     ski.channel.translateAndSetReadyOps(rOps, ski);
 152                     if (ski.hasOps()) {
 153                         selectedKeys.add(ski);
 154                         numKeysUpdated++;
 155                     }
 156                 }
 157             }
 158         }
 159         return numKeysUpdated;
 160     }
 161 
 162     protected void implClose() throws IOException {
 163         if (closed)
 164             return;
 165         closed = true;
 166 
 167         // prevent further wakeup
 168         synchronized (interruptLock) {
 169             interruptTriggered = true;
 170         }
 171 
 172         FileDispatcherImpl.closeIntFD(fd0);