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 java.nio.channels; 27 28 import java.io.IOException; 29 import java.nio.channels.spi.AbstractInterruptibleChannel; 30 import java.nio.channels.spi.SelectorProvider; 31 32 33 /** 34 * A channel that can be multiplexed via a {@link Selector}. 35 * 36 * <p> In order to be used with a selector, an instance of this class must 37 * first be <i>registered</i> via the {@link #register(Selector,int,Object) 38 * register} method. This method returns a new {@link SelectionKey} object 39 * that represents the channel's registration with the selector. 40 * 41 * <p> Once registered with a selector, a channel remains registered until it 42 * is <i>deregistered</i>. This involves deallocating whatever resources were 43 * allocated to the channel by the selector. 44 * 45 * <p> A channel cannot be deregistered directly; instead, the key representing 46 * its registration must be <i>cancelled</i>. Cancelling a key requests that 47 * the channel be deregistered during the selector's next selection operation. 48 * A key may be cancelled explicitly by invoking its {@link 49 * SelectionKey#cancel() cancel} method. All of a channel's keys are cancelled 50 * implicitly when the channel is closed, whether by invoking its {@link 51 * Channel#close close} method or by interrupting a thread blocked in an I/O 52 * operation upon the channel. 53 * 54 * <p> If the selector itself is closed then the channel will be deregistered, 55 * and the key representing its registration will be invalidated, without 56 * further delay. 57 * 58 * <p> A channel may be registered at most once with any particular selector. 59 * 60 * <p> Whether or not a channel is registered with one or more selectors may be 61 * determined by invoking the {@link #isRegistered isRegistered} method. 62 * 63 * <p> Selectable channels are safe for use by multiple concurrent 64 * threads. </p> 65 * 66 * 67 * <a name="bm"> 68 * <h4>Blocking mode</h4> 69 * 70 * A selectable channel is either in <i>blocking</i> mode or in 71 * <i>non-blocking</i> mode. In blocking mode, every I/O operation invoked 72 * upon the channel will block until it completes. In non-blocking mode an I/O 73 * operation will never block and may transfer fewer bytes than were requested 74 * or possibly no bytes at all. The blocking mode of a selectable channel may 75 * be determined by invoking its {@link #isBlocking isBlocking} method. 76 * 77 * <p> Newly-created selectable channels are always in blocking mode. 78 * Non-blocking mode is most useful in conjunction with selector-based 79 * multiplexing. A channel must be placed into non-blocking mode before being 80 * registered with a selector, and may not be returned to blocking mode until 81 * it has been deregistered. 82 * 83 * 84 * @author Mark Reinhold 85 * @author JSR-51 Expert Group 86 * @since 1.4 87 * 88 * @see SelectionKey 89 * @see Selector 90 */ 91 92 public abstract class SelectableChannel 93 extends AbstractInterruptibleChannel 94 implements Channel 95 { 96 97 /** 98 * Initializes a new instance of this class. 99 */ 100 protected SelectableChannel() { } 101 102 /** 103 * Returns the provider that created this channel. 104 * 105 * @return The provider that created this channel 106 */ 107 public abstract SelectorProvider provider(); 108 109 /** 110 * Returns an <a href="SelectionKey.html#opsets">operation set</a> 111 * identifying this channel's supported operations. The bits that are set 112 * in this integer value denote exactly the operations that are valid for 113 * this channel. This method always returns the same value for a given 114 * concrete channel class. </p> 115 * 116 * @return The valid-operation set 117 */ 118 public abstract int validOps(); 119 120 // Internal state: 121 // keySet, may be empty but is never null, typ. a tiny array 122 // boolean isRegistered, protected by key set 123 // regLock, lock object to prevent duplicate registrations 124 // boolean isBlocking, protected by regLock 125 126 /** 127 * Tells whether or not this channel is currently registered with any 128 * selectors. A newly-created channel is not registered. 129 * 130 * <p> Due to the inherent delay between key cancellation and channel 131 * deregistration, a channel may remain registered for some time after all 132 * of its keys have been cancelled. A channel may also remain registered 133 * for some time after it is closed. </p> 134 * 135 * @return <tt>true</tt> if, and only if, this channel is registered 136 */ 137 public abstract boolean isRegistered(); 138 // 139 // sync(keySet) { return isRegistered; } 140 141 /** 142 * Retrieves the key representing the channel's registration with the given 143 * selector. </p> 144 * 145 * @return The key returned when this channel was last registered with the 146 * given selector, or <tt>null</tt> if this channel is not 147 * currently registered with that selector 148 */ 149 public abstract SelectionKey keyFor(Selector sel); 150 // 151 // sync(keySet) { return findKey(sel); } 152 153 /** 154 * Registers this channel with the given selector, returning a selection 155 * key. 156 * 157 * <p> If this channel is currently registered with the given selector then 158 * the selection key representing that registration is returned. The key's 159 * interest set will have been changed to <tt>ops</tt>, as if by invoking 160 * the {@link SelectionKey#interestOps(int) interestOps(int)} method. If 161 * the <tt>att</tt> argument is not <tt>null</tt> then the key's attachment 162 * will have been set to that value. A {@link CancelledKeyException} will 163 * be thrown if the key has already been cancelled. 164 * 165 * <p> Otherwise this channel has not yet been registered with the given 166 * selector, so it is registered and the resulting new key is returned. 167 * The key's initial interest set will be <tt>ops</tt> and its attachment 168 * will be <tt>att</tt>. 169 * 170 * <p> This method may be invoked at any time. If this method is invoked 171 * while another invocation of this method or of the {@link 172 * #configureBlocking(boolean) configureBlocking} method is in progress 173 * then it will first block until the other operation is complete. This 174 * method will then synchronize on the selector's key set and therefore may 175 * block if invoked concurrently with another registration or selection 176 * operation involving the same selector. </p> 177 * 178 * <p> If this channel is closed while this operation is in progress then 179 * the key returned by this method will have been cancelled and will 180 * therefore be invalid. </p> 181 * 182 * @param sel 183 * The selector with which this channel is to be registered 184 * 185 * @param ops 186 * The interest set for the resulting key 187 * 188 * @param att 189 * The attachment for the resulting key; may be <tt>null</tt> 190 * 191 * @throws ClosedChannelException 192 * If this channel is closed 193 * 194 * @throws ClosedSelectorException 195 * If the selector is closed 196 * 197 * @throws IllegalBlockingModeException 198 * If this channel is in blocking mode 199 * 200 * @throws IllegalSelectorException 201 * If this channel was not created by the same provider 202 * as the given selector 203 * 204 * @throws CancelledKeyException 205 * If this channel is currently registered with the given selector 206 * but the corresponding key has already been cancelled 207 * 208 * @throws IllegalArgumentException 209 * If a bit in the <tt>ops</tt> set does not correspond to an 210 * operation that is supported by this channel, that is, if 211 * <tt>set & ~validOps() != 0</tt> 212 * 213 * @return A key representing the registration of this channel with 214 * the given selector 215 */ 216 public abstract SelectionKey register(Selector sel, int ops, Object att) 217 throws ClosedChannelException; 218 // 219 // sync(regLock) { 220 // sync(keySet) { look for selector } 221 // if (channel found) { set interest ops -- may block in selector; 222 // return key; } 223 // create new key -- may block somewhere in selector; 224 // sync(keySet) { add key; } 225 // attach(attachment); 226 // return key; 227 // } 228 229 /** 230 * Registers this channel with the given selector, returning a selection 231 * key. 232 * 233 * <p> An invocation of this convenience method of the form 234 * 235 * <blockquote><tt>sc.register(sel, ops)</tt></blockquote> 236 * 237 * behaves in exactly the same way as the invocation 238 * 239 * <blockquote><tt>sc.{@link 240 * #register(java.nio.channels.Selector,int,java.lang.Object) 241 * register}(sel, ops, null)</tt></blockquote> 242 * 243 * @param sel 244 * The selector with which this channel is to be registered 245 * 246 * @param ops 247 * The interest set for the resulting key 248 * 249 * @throws ClosedChannelException 250 * If this channel is closed 251 * 252 * @throws ClosedSelectorException 253 * If the selector is closed 254 * 255 * @throws IllegalBlockingModeException 256 * If this channel is in blocking mode 257 * 258 * @throws IllegalSelectorException 259 * If this channel was not created by the same provider 260 * as the given selector 261 * 262 * @throws CancelledKeyException 263 * If this channel is currently registered with the given selector 264 * but the corresponding key has already been cancelled 265 * 266 * @throws IllegalArgumentException 267 * If a bit in <tt>ops</tt> does not correspond to an operation 268 * that is supported by this channel, that is, if <tt>set & 269 * ~validOps() != 0</tt> 270 * 271 * @return A key representing the registration of this channel with 272 * the given selector 273 */ 274 public final SelectionKey register(Selector sel, int ops) 275 throws ClosedChannelException 276 { 277 return register(sel, ops, null); 278 } 279 280 /** 281 * Adjusts this channel's blocking mode. 282 * 283 * <p> If this channel is registered with one or more selectors then an 284 * attempt to place it into blocking mode will cause an {@link 285 * IllegalBlockingModeException} to be thrown. 286 * 287 * <p> This method may be invoked at any time. The new blocking mode will 288 * only affect I/O operations that are initiated after this method returns. 289 * For some implementations this may require blocking until all pending I/O 290 * operations are complete. 291 * 292 * <p> If this method is invoked while another invocation of this method or 293 * of the {@link #register(Selector, int) register} method is in progress 294 * then it will first block until the other operation is complete. </p> 295 * 296 * @param block If <tt>true</tt> then this channel will be placed in 297 * blocking mode; if <tt>false</tt> then it will be placed 298 * non-blocking mode 299 * 300 * @return This selectable channel 301 * 302 * @throws ClosedChannelException 303 * If this channel is closed 304 * 305 * @throws IllegalBlockingModeException 306 * If <tt>block</tt> is <tt>true</tt> and this channel is 307 * registered with one or more selectors 308 * 309 * @throws IOException 310 * If an I/O error occurs 311 */ 312 public abstract SelectableChannel configureBlocking(boolean block) 313 throws IOException; 314 // 315 // sync(regLock) { 316 // sync(keySet) { throw IBME if block && isRegistered; } 317 // change mode; 318 // } 319 320 /** 321 * Tells whether or not every I/O operation on this channel will block 322 * until it completes. A newly-created channel is always in blocking mode. 323 * 324 * <p> If this channel is closed then the value returned by this method is 325 * not specified. </p> 326 * 327 * @return <tt>true</tt> if, and only if, this channel is in blocking mode 328 */ 329 public abstract boolean isBlocking(); 330 331 /** 332 * Retrieves the object upon which the {@link #configureBlocking 333 * configureBlocking} and {@link #register register} methods synchronize. 334 * This is often useful in the implementation of adaptors that require a 335 * specific blocking mode to be maintained for a short period of time. 336 * </p> 337 * 338 * @return The blocking-mode lock object 339 */ 340 public abstract Object blockingLock(); 341 342 }