Path: blob/master/src/java.base/share/classes/java/nio/channels/SelectionKey.java
41159 views
/*1* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.nio.channels;2627import java.lang.invoke.MethodHandles;28import java.lang.invoke.VarHandle;2930/**31* A token representing the registration of a {@link SelectableChannel} with a32* {@link Selector}.33*34* <p> A selection key is created each time a channel is registered with a35* selector. A key remains valid until it is <i>cancelled</i> by invoking its36* {@link #cancel cancel} method, by closing its channel, or by closing its37* selector. Cancelling a key does not immediately remove it from its38* selector; it is instead added to the selector's <a39* href="Selector.html#ks"><i>cancelled-key set</i></a> for removal during the40* next selection operation. The validity of a key may be tested by invoking41* its {@link #isValid isValid} method.42*43* <a id="opsets"></a>44*45* <p> A selection key contains two <i>operation sets</i> represented as46* integer values. Each bit of an operation set denotes a category of47* selectable operations that are supported by the key's channel.48*49* <ul>50*51* <li><p> The <i>interest set</i> determines which operation categories will52* be tested for readiness the next time one of the selector's selection53* methods is invoked. The interest set is initialized with the value given54* when the key is created; it may later be changed via the {@link55* #interestOps(int)} method. </p></li>56*57* <li><p> The <i>ready set</i> identifies the operation categories for which58* the key's channel has been detected to be ready by the key's selector.59* The ready set is initialized to zero when the key is created; it may later60* be updated by the selector during a selection operation, but it cannot be61* updated directly. </p></li>62*63* </ul>64*65* <p> That a selection key's ready set indicates that its channel is ready for66* some operation category is a hint, but not a guarantee, that an operation in67* such a category may be performed by a thread without causing the thread to68* block. A ready set is most likely to be accurate immediately after the69* completion of a selection operation. It is likely to be made inaccurate by70* external events and by I/O operations that are invoked upon the71* corresponding channel.72*73* <p> This class defines all known operation-set bits, but precisely which74* bits are supported by a given channel depends upon the type of the channel.75* Each subclass of {@link SelectableChannel} defines a {@link76* SelectableChannel#validOps() validOps()} method which returns a set77* identifying just those operations that are supported by the channel. An78* attempt to set or test an operation-set bit that is not supported by a key's79* channel will result in an appropriate run-time exception.80*81* <p> It is often necessary to associate some application-specific data with a82* selection key, for example an object that represents the state of a83* higher-level protocol and handles readiness notifications in order to84* implement that protocol. Selection keys therefore support the85* <i>attachment</i> of a single arbitrary object to a key. An object can be86* attached via the {@link #attach attach} method and then later retrieved via87* the {@link #attachment() attachment} method.88*89* <p> Selection keys are safe for use by multiple concurrent threads. A90* selection operation will always use the interest-set value that was current91* at the moment that the operation began. </p>92*93*94* @author Mark Reinhold95* @author JSR-51 Expert Group96* @since 1.497*98* @see SelectableChannel99* @see Selector100*/101102public abstract class SelectionKey {103104/**105* Constructs an instance of this class.106*/107protected SelectionKey() { }108109110// -- Channel and selector operations --111112/**113* Returns the channel for which this key was created. This method will114* continue to return the channel even after the key is cancelled.115*116* @return This key's channel117*/118public abstract SelectableChannel channel();119120/**121* Returns the selector for which this key was created. This method will122* continue to return the selector even after the key is cancelled.123*124* @return This key's selector125*/126public abstract Selector selector();127128/**129* Tells whether or not this key is valid.130*131* <p> A key is valid upon creation and remains so until it is cancelled,132* its channel is closed, or its selector is closed. </p>133*134* @return {@code true} if, and only if, this key is valid135*/136public abstract boolean isValid();137138/**139* Requests that the registration of this key's channel with its selector140* be cancelled. Upon return the key will be invalid and will have been141* added to its selector's cancelled-key set. The key will be removed from142* all of the selector's key sets during the next selection operation.143*144* <p> If this key has already been cancelled then invoking this method has145* no effect. Once cancelled, a key remains forever invalid. </p>146*147* <p> This method may be invoked at any time. It synchronizes on the148* selector's cancelled-key set, and therefore may block briefly if invoked149* concurrently with a cancellation or selection operation involving the150* same selector. </p>151*/152public abstract void cancel();153154155// -- Operation-set accessors --156157/**158* Retrieves this key's interest set.159*160* <p> It is guaranteed that the returned set will only contain operation161* bits that are valid for this key's channel. </p>162*163* @return This key's interest set164*165* @throws CancelledKeyException166* If this key has been cancelled167*/168public abstract int interestOps();169170/**171* Sets this key's interest set to the given value.172*173* <p> This method may be invoked at any time. If this method is invoked174* while a selection operation is in progress then it has no effect upon175* that operation; the change to the key's interest set will be seen by the176* next selection operation.177*178* @param ops The new interest set179*180* @return This selection key181*182* @throws IllegalArgumentException183* If a bit in the set does not correspond to an operation that184* is supported by this key's channel, that is, if185* {@code (ops & ~channel().validOps()) != 0}186*187* @throws CancelledKeyException188* If this key has been cancelled189*/190public abstract SelectionKey interestOps(int ops);191192/**193* Atomically sets this key's interest set to the bitwise union ("or") of194* the existing interest set and the given value. This method is guaranteed195* to be atomic with respect to other concurrent calls to this method or to196* {@link #interestOpsAnd(int)}.197*198* <p> This method may be invoked at any time. If this method is invoked199* while a selection operation is in progress then it has no effect upon200* that operation; the change to the key's interest set will be seen by the201* next selection operation.202*203* @implSpec The default implementation synchronizes on this key and invokes204* {@code interestOps()} and {@code interestOps(int)} to retrieve and set205* this key's interest set.206*207* @param ops The interest set to apply208*209* @return The previous interest set210*211* @throws IllegalArgumentException212* If a bit in the set does not correspond to an operation that213* is supported by this key's channel, that is, if214* {@code (ops & ~channel().validOps()) != 0}215*216* @throws CancelledKeyException217* If this key has been cancelled218*219* @since 11220*/221public int interestOpsOr(int ops) {222synchronized (this) {223int oldVal = interestOps();224interestOps(oldVal | ops);225return oldVal;226}227}228229/**230* Atomically sets this key's interest set to the bitwise intersection ("and")231* of the existing interest set and the given value. This method is guaranteed232* to be atomic with respect to other concurrent calls to this method or to233* {@link #interestOpsOr(int)}.234*235* <p> This method may be invoked at any time. If this method is invoked236* while a selection operation is in progress then it has no effect upon237* that operation; the change to the key's interest set will be seen by the238* next selection operation.239*240* @apiNote Unlike the {@code interestOps(int)} and {@code interestOpsOr(int)}241* methods, this method does not throw {@code IllegalArgumentException} when242* invoked with bits in the interest set that do not correspond to an243* operation that is supported by this key's channel. This is to allow244* operation bits in the interest set to be cleared using bitwise complement245* values, e.g., {@code interestOpsAnd(~SelectionKey.OP_READ)} will remove246* the {@code OP_READ} from the interest set without affecting other bits.247*248* @implSpec The default implementation synchronizes on this key and invokes249* {@code interestOps()} and {@code interestOps(int)} to retrieve and set250* this key's interest set.251*252* @param ops The interest set to apply253*254* @return The previous interest set255*256* @throws CancelledKeyException257* If this key has been cancelled258*259* @since 11260*/261public int interestOpsAnd(int ops) {262synchronized (this) {263int oldVal = interestOps();264interestOps(oldVal & ops);265return oldVal;266}267}268269/**270* Retrieves this key's ready-operation set.271*272* <p> It is guaranteed that the returned set will only contain operation273* bits that are valid for this key's channel. </p>274*275* @return This key's ready-operation set276*277* @throws CancelledKeyException278* If this key has been cancelled279*/280public abstract int readyOps();281282283// -- Operation bits and bit-testing convenience methods --284285/**286* Operation-set bit for read operations.287*288* <p> Suppose that a selection key's interest set contains289* {@code OP_READ} at the start of a <a290* href="Selector.html#selop">selection operation</a>. If the selector291* detects that the corresponding channel is ready for reading, has reached292* end-of-stream, has been remotely shut down for further writing, or has293* an error pending, then it will add {@code OP_READ} to the key's294* ready-operation set. </p>295*/296public static final int OP_READ = 1 << 0;297298/**299* Operation-set bit for write operations.300*301* <p> Suppose that a selection key's interest set contains302* {@code OP_WRITE} at the start of a <a303* href="Selector.html#selop">selection operation</a>. If the selector304* detects that the corresponding channel is ready for writing, has been305* remotely shut down for further reading, or has an error pending, then it306* will add {@code OP_WRITE} to the key's ready set. </p>307*/308public static final int OP_WRITE = 1 << 2;309310/**311* Operation-set bit for socket-connect operations.312*313* <p> Suppose that a selection key's interest set contains314* {@code OP_CONNECT} at the start of a <a315* href="Selector.html#selop">selection operation</a>. If the selector316* detects that the corresponding socket channel is ready to complete its317* connection sequence, or has an error pending, then it will add318* {@code OP_CONNECT} to the key's ready set. </p>319*/320public static final int OP_CONNECT = 1 << 3;321322/**323* Operation-set bit for socket-accept operations.324*325* <p> Suppose that a selection key's interest set contains326* {@code OP_ACCEPT} at the start of a <a327* href="Selector.html#selop">selection operation</a>. If the selector328* detects that the corresponding server-socket channel is ready to accept329* another connection, or has an error pending, then it will add330* {@code OP_ACCEPT} to the key's ready set. </p>331*/332public static final int OP_ACCEPT = 1 << 4;333334/**335* Tests whether this key's channel is ready for reading.336*337* <p> An invocation of this method of the form {@code k.isReadable()}338* behaves in exactly the same way as the expression339*340* <blockquote><pre>{@code341* k.readyOps() & OP_READ != 0342* }</pre></blockquote>343*344* <p> If this key's channel does not support read operations then this345* method always returns {@code false}. </p>346*347* @return {@code true} if, and only if,348* {@code readyOps() & OP_READ} is nonzero349*350* @throws CancelledKeyException351* If this key has been cancelled352*/353public final boolean isReadable() {354return (readyOps() & OP_READ) != 0;355}356357/**358* Tests whether this key's channel is ready for writing.359*360* <p> An invocation of this method of the form {@code k.isWritable()}361* behaves in exactly the same way as the expression362*363* <blockquote><pre>{@code364* k.readyOps() & OP_WRITE != 0365* }</pre></blockquote>366*367* <p> If this key's channel does not support write operations then this368* method always returns {@code false}. </p>369*370* @return {@code true} if, and only if,371* {@code readyOps() & OP_WRITE} is nonzero372*373* @throws CancelledKeyException374* If this key has been cancelled375*/376public final boolean isWritable() {377return (readyOps() & OP_WRITE) != 0;378}379380/**381* Tests whether this key's channel has either finished, or failed to382* finish, its socket-connection operation.383*384* <p> An invocation of this method of the form {@code k.isConnectable()}385* behaves in exactly the same way as the expression386*387* <blockquote><pre>{@code388* k.readyOps() & OP_CONNECT != 0389* }</pre></blockquote>390*391* <p> If this key's channel does not support socket-connect operations392* then this method always returns {@code false}. </p>393*394* @return {@code true} if, and only if,395* {@code readyOps() & OP_CONNECT} is nonzero396*397* @throws CancelledKeyException398* If this key has been cancelled399*/400public final boolean isConnectable() {401return (readyOps() & OP_CONNECT) != 0;402}403404/**405* Tests whether this key's channel is ready to accept a new socket406* connection.407*408* <p> An invocation of this method of the form {@code k.isAcceptable()}409* behaves in exactly the same way as the expression410*411* <blockquote><pre>{@code412* k.readyOps() & OP_ACCEPT != 0413* }</pre></blockquote>414*415* <p> If this key's channel does not support socket-accept operations then416* this method always returns {@code false}. </p>417*418* @return {@code true} if, and only if,419* {@code readyOps() & OP_ACCEPT} is nonzero420*421* @throws CancelledKeyException422* If this key has been cancelled423*/424public final boolean isAcceptable() {425return (readyOps() & OP_ACCEPT) != 0;426}427428429// -- Attachments --430431private static final VarHandle ATTACHMENT;432static {433try {434MethodHandles.Lookup l = MethodHandles.lookup();435ATTACHMENT = l.findVarHandle(SelectionKey.class, "attachment", Object.class);436} catch (Exception e) {437throw new InternalError(e);438}439}440private volatile Object attachment;441442/**443* Attaches the given object to this key.444*445* <p> An attached object may later be retrieved via the {@link #attachment()446* attachment} method. Only one object may be attached at a time; invoking447* this method causes any previous attachment to be discarded. The current448* attachment may be discarded by attaching {@code null}. </p>449*450* @param ob451* The object to be attached; may be {@code null}452*453* @return The previously-attached object, if any,454* otherwise {@code null}455*/456public final Object attach(Object ob) {457return ATTACHMENT.getAndSet(this, ob);458}459460/**461* Retrieves the current attachment.462*463* @return The object currently attached to this key,464* or {@code null} if there is no attachment465*/466public final Object attachment() {467return attachment;468}469470}471472473