View Javadoc
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       */
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 <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.
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      */
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      */
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      */
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      */
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      */
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 }