1 /* 2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 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.net.SocketException; 32 import java.util.*; 33 import sun.misc.*; 34 35 36 /** 37 * Base Selector implementation class. 38 */ 39 40 abstract class SelectorImpl 41 extends AbstractSelector 42 { 43 44 // The set of keys with data ready for an operation 45 protected Set<SelectionKey> selectedKeys; 46 47 // The set of keys registered with this Selector 48 protected HashSet<SelectionKey> keys; 49 50 // Public views of the key sets 51 private Set<SelectionKey> publicKeys; // Immutable 52 private Set<SelectionKey> publicSelectedKeys; // Removal allowed, but not addition 53 SelectorImpl(SelectorProvider sp)54 protected SelectorImpl(SelectorProvider sp) { 55 super(sp); 56 keys = new HashSet<SelectionKey>(); 57 selectedKeys = new HashSet<SelectionKey>(); 58 if (Util.atBugLevel("1.4")) { 59 publicKeys = keys; 60 publicSelectedKeys = selectedKeys; 61 } else { 62 publicKeys = Collections.unmodifiableSet(keys); 63 publicSelectedKeys = Util.ungrowableSet(selectedKeys); 64 } 65 } 66 keys()67 public Set<SelectionKey> keys() { 68 if (!isOpen() && !Util.atBugLevel("1.4")) 69 throw new ClosedSelectorException(); 70 return publicKeys; 71 } 72 selectedKeys()73 public Set<SelectionKey> selectedKeys() { 74 if (!isOpen() && !Util.atBugLevel("1.4")) 75 throw new ClosedSelectorException(); 76 return publicSelectedKeys; 77 } 78 doSelect(long timeout)79 protected abstract int doSelect(long timeout) throws IOException; 80 lockAndDoSelect(long timeout)81 private int lockAndDoSelect(long timeout) throws IOException { 82 synchronized (this) { 83 if (!isOpen()) 84 throw new ClosedSelectorException(); 85 synchronized (publicKeys) { 86 synchronized (publicSelectedKeys) { 87 return doSelect(timeout); 88 } 89 } 90 } 91 } 92 select(long timeout)93 public int select(long timeout) 94 throws IOException 95 { 96 if (timeout < 0) 97 throw new IllegalArgumentException("Negative timeout"); 98 return lockAndDoSelect((timeout == 0) ? -1 : timeout); 99 } 100 select()101 public int select() throws IOException { 102 return select(0); 103 } 104 selectNow()105 public int selectNow() throws IOException { 106 return lockAndDoSelect(0); 107 } 108 implCloseSelector()109 public void implCloseSelector() throws IOException { 110 wakeup(); 111 synchronized (this) { 112 synchronized (publicKeys) { 113 synchronized (publicSelectedKeys) { 114 implClose(); 115 } 116 } 117 } 118 } 119 implClose()120 protected abstract void implClose() throws IOException; 121 putEventOps(SelectionKeyImpl sk, int ops)122 void putEventOps(SelectionKeyImpl sk, int ops) { } 123 register(AbstractSelectableChannel ch, int ops, Object attachment)124 protected final SelectionKey register(AbstractSelectableChannel ch, 125 int ops, 126 Object attachment) 127 { 128 if (!(ch instanceof SelChImpl)) 129 throw new IllegalSelectorException(); 130 SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this); 131 k.attach(attachment); 132 synchronized (publicKeys) { 133 implRegister(k); 134 } 135 k.interestOps(ops); 136 return k; 137 } 138 implRegister(SelectionKeyImpl ski)139 protected abstract void implRegister(SelectionKeyImpl ski); 140 processDeregisterQueue()141 void processDeregisterQueue() throws IOException { 142 // Precondition: Synchronized on this, keys, and selectedKeys 143 Set cks = cancelledKeys(); 144 synchronized (cks) { 145 if (!cks.isEmpty()) { 146 Iterator i = cks.iterator(); 147 while (i.hasNext()) { 148 SelectionKeyImpl ski = (SelectionKeyImpl)i.next(); 149 try { 150 implDereg(ski); 151 } catch (SocketException se) { 152 IOException ioe = new IOException( 153 "Error deregistering key"); 154 ioe.initCause(se); 155 throw ioe; 156 } finally { 157 i.remove(); 158 } 159 } 160 } 161 } 162 } 163 implDereg(SelectionKeyImpl ski)164 protected abstract void implDereg(SelectionKeyImpl ski) throws IOException; 165 wakeup()166 abstract public Selector wakeup(); 167 168 } 169