1 /* 2 * Copyright (c) 2000, 2013, 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"></a> 68 * <h2>Blocking mode</h2> 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 */ SelectableChannel()100 protected SelectableChannel() { } 101 102 /** 103 * Returns the provider that created this channel. 104 * 105 * @return The provider that created this channel 106 */ provider()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. 115 * 116 * @return The valid-operation set 117 */ validOps()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 */ isRegistered()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. 144 * 145 * @param sel 146 * The selector 147 * 148 * @return The key returned when this channel was last registered with the 149 * given selector, or <tt>null</tt> if this channel is not 150 * currently registered with that selector 151 */ keyFor(Selector sel)152 public abstract SelectionKey keyFor(Selector sel); 153 // 154 // sync(keySet) { return findKey(sel); } 155 156 /** 157 * Registers this channel with the given selector, returning a selection 158 * key. 159 * 160 * <p> If this channel is currently registered with the given selector then 161 * the selection key representing that registration is returned. The key's 162 * interest set will have been changed to <tt>ops</tt>, as if by invoking 163 * the {@link SelectionKey#interestOps(int) interestOps(int)} method. If 164 * the <tt>att</tt> argument is not <tt>null</tt> then the key's attachment 165 * will have been set to that value. A {@link CancelledKeyException} will 166 * be thrown if the key has already been cancelled. 167 * 168 * <p> Otherwise this channel has not yet been registered with the given 169 * selector, so it is registered and the resulting new key is returned. 170 * The key's initial interest set will be <tt>ops</tt> and its attachment 171 * will be <tt>att</tt>. 172 * 173 * <p> This method may be invoked at any time. If this method is invoked 174 * while another invocation of this method or of the {@link 175 * #configureBlocking(boolean) configureBlocking} method is in progress 176 * then it will first block until the other operation is complete. This 177 * method will then synchronize on the selector's key set and therefore may 178 * block if invoked concurrently with another registration or selection 179 * operation involving the same selector. </p> 180 * 181 * <p> If this channel is closed while this operation is in progress then 182 * the key returned by this method will have been cancelled and will 183 * therefore be invalid. </p> 184 * 185 * @param sel 186 * The selector with which this channel is to be registered 187 * 188 * @param ops 189 * The interest set for the resulting key 190 * 191 * @param att 192 * The attachment for the resulting key; may be <tt>null</tt> 193 * 194 * @throws ClosedChannelException 195 * If this channel is closed 196 * 197 * @throws ClosedSelectorException 198 * If the selector is closed 199 * 200 * @throws IllegalBlockingModeException 201 * If this channel is in blocking mode 202 * 203 * @throws IllegalSelectorException 204 * If this channel was not created by the same provider 205 * as the given selector 206 * 207 * @throws CancelledKeyException 208 * If this channel is currently registered with the given selector 209 * but the corresponding key has already been cancelled 210 * 211 * @throws IllegalArgumentException 212 * If a bit in the <tt>ops</tt> set does not correspond to an 213 * operation that is supported by this channel, that is, if 214 * {@code set & ~validOps() != 0} 215 * 216 * @return A key representing the registration of this channel with 217 * the given selector 218 */ register(Selector sel, int ops, Object att)219 public abstract SelectionKey register(Selector sel, int ops, Object att) 220 throws ClosedChannelException; 221 // 222 // sync(regLock) { 223 // sync(keySet) { look for selector } 224 // if (channel found) { set interest ops -- may block in selector; 225 // return key; } 226 // create new key -- may block somewhere in selector; 227 // sync(keySet) { add key; } 228 // attach(attachment); 229 // return key; 230 // } 231 232 /** 233 * Registers this channel with the given selector, returning a selection 234 * key. 235 * 236 * <p> An invocation of this convenience method of the form 237 * 238 * <blockquote><tt>sc.register(sel, ops)</tt></blockquote> 239 * 240 * behaves in exactly the same way as the invocation 241 * 242 * <blockquote><tt>sc.{@link 243 * #register(java.nio.channels.Selector,int,java.lang.Object) 244 * register}(sel, ops, null)</tt></blockquote> 245 * 246 * @param sel 247 * The selector with which this channel is to be registered 248 * 249 * @param ops 250 * The interest set for the resulting key 251 * 252 * @throws ClosedChannelException 253 * If this channel is closed 254 * 255 * @throws ClosedSelectorException 256 * If the selector is closed 257 * 258 * @throws IllegalBlockingModeException 259 * If this channel is in blocking mode 260 * 261 * @throws IllegalSelectorException 262 * If this channel was not created by the same provider 263 * as the given selector 264 * 265 * @throws CancelledKeyException 266 * If this channel is currently registered with the given selector 267 * but the corresponding key has already been cancelled 268 * 269 * @throws IllegalArgumentException 270 * If a bit in <tt>ops</tt> does not correspond to an operation 271 * that is supported by this channel, that is, if {@code set & 272 * ~validOps() != 0} 273 * 274 * @return A key representing the registration of this channel with 275 * the given selector 276 */ register(Selector sel, int ops)277 public final SelectionKey register(Selector sel, int ops) 278 throws ClosedChannelException 279 { 280 return register(sel, ops, null); 281 } 282 283 /** 284 * Adjusts this channel's blocking mode. 285 * 286 * <p> If this channel is registered with one or more selectors then an 287 * attempt to place it into blocking mode will cause an {@link 288 * IllegalBlockingModeException} to be thrown. 289 * 290 * <p> This method may be invoked at any time. The new blocking mode will 291 * only affect I/O operations that are initiated after this method returns. 292 * For some implementations this may require blocking until all pending I/O 293 * operations are complete. 294 * 295 * <p> If this method is invoked while another invocation of this method or 296 * of the {@link #register(Selector, int) register} method is in progress 297 * then it will first block until the other operation is complete. </p> 298 * 299 * @param block If <tt>true</tt> then this channel will be placed in 300 * blocking mode; if <tt>false</tt> then it will be placed 301 * non-blocking mode 302 * 303 * @return This selectable channel 304 * 305 * @throws ClosedChannelException 306 * If this channel is closed 307 * 308 * @throws IllegalBlockingModeException 309 * If <tt>block</tt> is <tt>true</tt> and this channel is 310 * registered with one or more selectors 311 * 312 * @throws IOException 313 * If an I/O error occurs 314 */ configureBlocking(boolean block)315 public abstract SelectableChannel configureBlocking(boolean block) 316 throws IOException; 317 // 318 // sync(regLock) { 319 // sync(keySet) { throw IBME if block && isRegistered; } 320 // change mode; 321 // } 322 323 /** 324 * Tells whether or not every I/O operation on this channel will block 325 * until it completes. A newly-created channel is always in blocking mode. 326 * 327 * <p> If this channel is closed then the value returned by this method is 328 * not specified. </p> 329 * 330 * @return <tt>true</tt> if, and only if, this channel is in blocking mode 331 */ isBlocking()332 public abstract boolean isBlocking(); 333 334 /** 335 * Retrieves the object upon which the {@link #configureBlocking 336 * configureBlocking} and {@link #register register} methods synchronize. 337 * This is often useful in the implementation of adaptors that require a 338 * specific blocking mode to be maintained for a short period of time. 339 * 340 * @return The blocking-mode lock object 341 */ blockingLock()342 public abstract Object blockingLock(); 343 344 } 345