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.Map; 32 import java.util.HashMap; 33 import java.util.Iterator; 34 35 /** 36 * Selector implementation based on the Solaris event port mechanism. 37 */ 38 39 class EventPortSelectorImpl 40 extends SelectorImpl 41 { 42 private final EventPortWrapper pollWrapper; 43 44 // Maps from file descriptors to keys 45 private Map<Integer,SelectionKeyImpl> fdToKey; 46 47 // True if this Selector has been closed 48 private boolean closed = false; 49 50 // Lock for interrupt triggering and clearing 51 private final Object interruptLock = new Object(); 52 private boolean interruptTriggered = false; 53 54 /** 55 * Package private constructor called by factory method in 56 * the abstract superclass Selector. 57 */ 58 EventPortSelectorImpl(SelectorProvider sp) throws IOException { 59 super(sp); 60 pollWrapper = new EventPortWrapper(); 61 fdToKey = new HashMap<>(); 62 } 63 64 protected int doSelect(long timeout) throws IOException { 65 if (closed) 66 throw new ClosedSelectorException(); 67 processDeregisterQueue(); 68 int entries; 69 try { 70 begin(); 71 entries = pollWrapper.poll(timeout); 72 } finally { 73 end(); 74 } 75 processDeregisterQueue(); 76 int numKeysUpdated = updateSelectedKeys(entries); 77 if (pollWrapper.interrupted()) { 78 synchronized (interruptLock) { 79 interruptTriggered = false; 80 } 81 } 82 return numKeysUpdated; 83 } 84 85 private int updateSelectedKeys(int entries) { 86 int numKeysUpdated = 0; 87 for (int i=0; i<entries; i++) { 88 int nextFD = pollWrapper.getDescriptor(i); 89 SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD)); 90 if (ski != null) { 91 int rOps = pollWrapper.getEventOps(i); 92 if (selectedKeys.contains(ski)) { 93 if (ski.channel.translateAndSetReadyOps(rOps, ski)) { 94 numKeysUpdated++; 95 } 96 } else { 97 ski.channel.translateAndSetReadyOps(rOps, ski); 98 if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) { 99 selectedKeys.add(ski); 100 numKeysUpdated++; 101 } 102 } 103 } 104 } 105 return numKeysUpdated; 106 } 107 108 protected void implClose() throws IOException { 109 if (closed) 110 return; 111 closed = true; 112 113 // prevent further wakeup 114 synchronized (interruptLock) { 115 interruptTriggered = true; 116 } 117 118 pollWrapper.close(); | 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.Map; 32 import java.util.HashMap; 33 import java.util.Iterator; 34 import java.util.function.Consumer; 35 36 /** 37 * Selector implementation based on the Solaris event port mechanism. 38 */ 39 40 class EventPortSelectorImpl 41 extends SelectorImpl 42 { 43 private final EventPortWrapper pollWrapper; 44 45 // Maps from file descriptors to keys 46 private Map<Integer,SelectionKeyImpl> fdToKey; 47 48 // True if this Selector has been closed 49 private boolean closed = false; 50 51 // Lock for interrupt triggering and clearing 52 private final Object interruptLock = new Object(); 53 private boolean interruptTriggered = false; 54 55 /** 56 * Package private constructor called by factory method in 57 * the abstract superclass Selector. 58 */ 59 EventPortSelectorImpl(SelectorProvider sp) throws IOException { 60 super(sp); 61 pollWrapper = new EventPortWrapper(); 62 fdToKey = new HashMap<>(); 63 } 64 65 @Override 66 protected int doSelect(long timeout) throws IOException { 67 int entries = pollEventPortWrapper(timeout); 68 int numKeysUpdated = updateSelectedKeys(entries); 69 storeInterruptTrigger(); 70 return numKeysUpdated; 71 } 72 73 @Override 74 protected int doSelect(Consumer<SelectionKey> handler, long timeout) throws IOException { 75 int entries = pollEventPortWrapper(timeout); 76 int numKeysUpdated = 0; 77 for (int i = 0; i < entries; i++) { 78 int nextFD = pollWrapper.getDescriptor(i); 79 SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD)); 80 if (ski != null) { 81 int rOps = pollWrapper.getEventOps(i); 82 ski.channel.translateAndSetReadyOps(rOps, ski); 83 if (ski.hasOps()) { 84 handler.accept(ski); 85 numKeysUpdated++; 86 } 87 } 88 } 89 storeInterruptTrigger(); 90 return numKeysUpdated; 91 } 92 93 private void storeInterruptTrigger() { 94 if (pollWrapper.interrupted()) { 95 synchronized (interruptLock) { 96 interruptTriggered = false; 97 } 98 } 99 } 100 101 private int pollEventPortWrapper(long timeout) throws ClosedSelectorException, IOException { 102 if (closed) 103 throw new ClosedSelectorException(); 104 processDeregisterQueue(); 105 int entries; 106 try { 107 begin(); 108 entries = pollWrapper.poll(timeout); 109 } finally { 110 end(); 111 } 112 processDeregisterQueue(); 113 return entries; 114 } 115 116 private int updateSelectedKeys(int entries) { 117 int numKeysUpdated = 0; 118 for (int i=0; i<entries; i++) { 119 int nextFD = pollWrapper.getDescriptor(i); 120 SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD)); 121 if (ski != null) { 122 int rOps = pollWrapper.getEventOps(i); 123 if (selectedKeys.contains(ski)) { 124 if (ski.channel.translateAndSetReadyOps(rOps, ski)) { 125 numKeysUpdated++; 126 } 127 } else { 128 ski.channel.translateAndSetReadyOps(rOps, ski); 129 if (ski.hasOps()) { 130 selectedKeys.add(ski); 131 numKeysUpdated++; 132 } 133 } 134 } 135 } 136 return numKeysUpdated; 137 } 138 139 protected void implClose() throws IOException { 140 if (closed) 141 return; 142 closed = true; 143 144 // prevent further wakeup 145 synchronized (interruptLock) { 146 interruptTriggered = true; 147 } 148 149 pollWrapper.close(); |