GNU Classpath (0.17) | ||
Frames | No Frames |
1: /* AbstractSelectableChannel.java 2: Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.nio.channels.spi; 40: 41: import java.io.IOException; 42: import java.nio.channels.ClosedChannelException; 43: import java.nio.channels.SelectableChannel; 44: import java.nio.channels.SelectionKey; 45: import java.nio.channels.Selector; 46: import java.util.LinkedList; 47: import java.util.ListIterator; 48: 49: public abstract class AbstractSelectableChannel extends SelectableChannel 50: { 51: private boolean blocking = true; 52: private Object LOCK = new Object(); 53: private SelectorProvider provider; 54: private LinkedList keys = new LinkedList(); 55: 56: /** 57: * Initializes the channel 58: * 59: * @param provider the provider that created this channel 60: */ 61: protected AbstractSelectableChannel(SelectorProvider provider) 62: { 63: this.provider = provider; 64: } 65: 66: /** 67: * Retrieves the object upon which the configureBlocking and register 68: * methods synchronize. 69: * 70: * @return the blocking lock 71: */ 72: public final Object blockingLock() 73: { 74: return LOCK; 75: } 76: 77: /** 78: * Adjusts this channel's blocking mode. 79: * 80: * @param blocking true if blocking should be enabled, false otherwise 81: * 82: * @return this channel 83: * 84: * @exception IOException If an error occurs 85: */ 86: public final SelectableChannel configureBlocking(boolean blocking) 87: throws IOException 88: { 89: synchronized (blockingLock()) 90: { 91: if (this.blocking != blocking) 92: { 93: implConfigureBlocking(blocking); 94: this.blocking = blocking; 95: } 96: } 97: 98: return this; 99: } 100: 101: /** 102: * Closes this channel. 103: * 104: * @exception IOException If an error occurs 105: */ 106: protected final void implCloseChannel() throws IOException 107: { 108: implCloseSelectableChannel(); 109: } 110: 111: /** 112: * Closes this selectable channel. 113: * 114: * @exception IOException If an error occurs 115: */ 116: protected abstract void implCloseSelectableChannel() 117: throws IOException; 118: 119: /** 120: * Adjusts this channel's blocking mode. 121: * 122: * @param blocking true if blocking should be enabled, false otherwise 123: * 124: * @exception IOException If an error occurs 125: */ 126: protected abstract void implConfigureBlocking(boolean blocking) 127: throws IOException; 128: 129: /** 130: * Tells whether or not every I/O operation on this channel will block 131: * until it completes. 132: * 133: * @return true of this channel is blocking, false otherwise 134: */ 135: public final boolean isBlocking() 136: { 137: return blocking; 138: } 139: 140: /** 141: * Tells whether or not this channel is currently registered with 142: * any selectors. 143: * 144: * @return true if this channel is registered, false otherwise 145: */ 146: public final boolean isRegistered() 147: { 148: return ! keys.isEmpty(); 149: } 150: 151: /** 152: * Retrieves the key representing the channel's registration with the 153: * given selector. 154: * 155: * @param selector the selector to get a selection key for 156: * 157: * @return the selection key this channel is registered with 158: */ 159: public final SelectionKey keyFor(Selector selector) 160: { 161: if (! isOpen()) 162: return null; 163: 164: try 165: { 166: synchronized (blockingLock()) 167: { 168: return locate(selector); 169: } 170: } 171: catch (Exception e) 172: { 173: return null; 174: } 175: } 176: 177: /** 178: * Returns the provider that created this channel. 179: * 180: * @return the selector provider that created this channel 181: */ 182: public final SelectorProvider provider() 183: { 184: return provider; 185: } 186: 187: private SelectionKey locate(Selector selector) 188: { 189: ListIterator it = keys.listIterator(); 190: 191: while (it.hasNext()) 192: { 193: SelectionKey key = (SelectionKey) it.next(); 194: 195: if (key.selector() == selector) 196: return key; 197: } 198: 199: return null; 200: } 201: 202: /** 203: * Registers this channel with the given selector, returning a selection key. 204: * 205: * @param selin the seletor to use 206: * @param ops the interested operations 207: * @param att an attachment for the returned selection key 208: * 209: * @return the registered selection key 210: * 211: * @exception ClosedChannelException If the channel is already closed. 212: */ 213: public final SelectionKey register(Selector selin, int ops, Object att) 214: throws ClosedChannelException 215: { 216: if (! isOpen()) 217: throw new ClosedChannelException(); 218: 219: if ((ops & ~validOps()) != 0) 220: throw new IllegalArgumentException(); 221: 222: SelectionKey key = null; 223: AbstractSelector selector = (AbstractSelector) selin; 224: 225: synchronized (blockingLock()) 226: { 227: key = locate(selector); 228: 229: if (key != null && key.isValid()) 230: { 231: if (att != null) 232: key.attach(att); 233: } 234: else 235: { 236: key = selector.register(this, ops, att); 237: 238: if (key != null) 239: addSelectionKey(key); 240: } 241: } 242: 243: return key; 244: } 245: 246: void addSelectionKey(SelectionKey key) 247: { 248: keys.add(key); 249: } 250: 251: // This method gets called by AbstractSelector.deregister(). 252: void removeSelectionKey(SelectionKey key) 253: { 254: keys.remove(key); 255: } 256: }
GNU Classpath (0.17) |