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 }