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 id="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      */
 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.
 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 {@code true} 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.
 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 {@code null} if this channel is not
 150      *          currently registered with that selector
 151      */
 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 {@code ops}, as if by invoking
 163      * the {@link SelectionKey#interestOps(int) interestOps(int)} method.  If
 164      * the {@code att} argument is not {@code null} 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 {@code ops} and its attachment
 171      * will be {@code att}.
 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 {@code null}
 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 {@code ops} 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      */
 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>{@code sc.register(sel, ops)}</blockquote>
 239      *
 240      * behaves in exactly the same way as the invocation
 241      *
 242      * <blockquote>{@code sc.}{@link
 243      * #register(java.nio.channels.Selector,int,java.lang.Object)
 244      * register(sel, ops, null)}</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 {@code ops} 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      */
 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 {@code true} then this channel will be placed in
 300      *                blocking mode; if {@code false} 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 {@code block} is {@code true} and this channel is
 310      *          registered with one or more selectors
 311      *
 312      * @throws IOException
 313      *         If an I/O error occurs
 314      */
 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 {@code true} if, and only if, this channel is in blocking mode
 331      */
 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      */
 342     public abstract Object blockingLock();
 343 
 344 }