1 /* 2 * Copyright (c) 2000, 2018, 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 sun.nio.ch; 27 28 import java.lang.invoke.ConstantBootstraps; 29 import java.lang.invoke.MethodHandles; 30 import java.lang.invoke.VarHandle; 31 import java.nio.channels.CancelledKeyException; 32 import java.nio.channels.SelectableChannel; 33 import java.nio.channels.SelectionKey; 34 import java.nio.channels.Selector; 35 import java.nio.channels.spi.AbstractSelectionKey; 36 37 38 /** 39 * An implementation of SelectionKey. 40 */ 41 42 public final class SelectionKeyImpl 43 extends AbstractSelectionKey 44 { 45 private static final VarHandle INTERESTOPS = 46 ConstantBootstraps.fieldVarHandle( 47 MethodHandles.lookup(), 48 "interestOps", 49 VarHandle.class, 50 SelectionKeyImpl.class, int.class); 51 52 private final SelChImpl channel; 53 private final SelectorImpl selector; 54 55 private volatile int interestOps; 56 private volatile int readyOps; 57 58 // registered events in kernel, used by some Selector implementations 59 private int registeredEvents; 60 61 // index of key in pollfd array, used by some Selector implementations 62 private int index; 63 SelectionKeyImpl(SelChImpl ch, SelectorImpl sel)64 SelectionKeyImpl(SelChImpl ch, SelectorImpl sel) { 65 channel = ch; 66 selector = sel; 67 } 68 ensureValid()69 private void ensureValid() { 70 if (!isValid()) 71 throw new CancelledKeyException(); 72 } 73 getFDVal()74 int getFDVal() { 75 return channel.getFDVal(); 76 } 77 78 @Override channel()79 public SelectableChannel channel() { 80 return (SelectableChannel)channel; 81 } 82 83 @Override selector()84 public Selector selector() { 85 return selector; 86 } 87 88 @Override interestOps()89 public int interestOps() { 90 ensureValid(); 91 return interestOps; 92 } 93 94 @Override interestOps(int ops)95 public SelectionKey interestOps(int ops) { 96 ensureValid(); 97 if ((ops & ~channel().validOps()) != 0) 98 throw new IllegalArgumentException(); 99 int oldOps = (int) INTERESTOPS.getAndSet(this, ops); 100 if (ops != oldOps) { 101 selector.setEventOps(this); 102 } 103 return this; 104 } 105 106 @Override interestOpsOr(int ops)107 public int interestOpsOr(int ops) { 108 ensureValid(); 109 if ((ops & ~channel().validOps()) != 0) 110 throw new IllegalArgumentException(); 111 int oldVal = (int) INTERESTOPS.getAndBitwiseOr(this, ops); 112 if (oldVal != (oldVal | ops)) { 113 selector.setEventOps(this); 114 } 115 return oldVal; 116 } 117 118 @Override interestOpsAnd(int ops)119 public int interestOpsAnd(int ops) { 120 ensureValid(); 121 int oldVal = (int) INTERESTOPS.getAndBitwiseAnd(this, ops); 122 if (oldVal != (oldVal & ops)) { 123 selector.setEventOps(this); 124 } 125 return oldVal; 126 } 127 128 @Override readyOps()129 public int readyOps() { 130 ensureValid(); 131 return readyOps; 132 } 133 134 // The nio versions of these operations do not care if a key 135 // has been invalidated. They are for internal use by nio code. 136 nioReadyOps(int ops)137 public void nioReadyOps(int ops) { 138 readyOps = ops; 139 } 140 nioReadyOps()141 public int nioReadyOps() { 142 return readyOps; 143 } 144 nioInterestOps(int ops)145 public SelectionKey nioInterestOps(int ops) { 146 if ((ops & ~channel().validOps()) != 0) 147 throw new IllegalArgumentException(); 148 interestOps = ops; 149 selector.setEventOps(this); 150 return this; 151 } 152 nioInterestOps()153 public int nioInterestOps() { 154 return interestOps; 155 } 156 translateInterestOps()157 int translateInterestOps() { 158 return channel.translateInterestOps(interestOps); 159 } 160 translateAndSetReadyOps(int ops)161 boolean translateAndSetReadyOps(int ops) { 162 return channel.translateAndSetReadyOps(ops, this); 163 } 164 translateAndUpdateReadyOps(int ops)165 boolean translateAndUpdateReadyOps(int ops) { 166 return channel.translateAndUpdateReadyOps(ops, this); 167 } 168 registeredEvents(int events)169 void registeredEvents(int events) { 170 // assert Thread.holdsLock(selector); 171 this.registeredEvents = events; 172 } 173 registeredEvents()174 int registeredEvents() { 175 // assert Thread.holdsLock(selector); 176 return registeredEvents; 177 } 178 getIndex()179 int getIndex() { 180 return index; 181 } 182 setIndex(int i)183 void setIndex(int i) { 184 index = i; 185 } 186 187 @Override toString()188 public String toString() { 189 StringBuilder sb = new StringBuilder(); 190 sb.append("channel=") 191 .append(channel) 192 .append(", selector=") 193 .append(selector); 194 if (isValid()) { 195 sb.append(", interestOps=") 196 .append(interestOps) 197 .append(", readyOps=") 198 .append(readyOps); 199 } else { 200 sb.append(", invalid"); 201 } 202 return sb.toString(); 203 } 204 205 // used by Selector implementations to record when the key was selected 206 int lastPolled; 207 } 208