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); |