1 7 8 package java.nio.channels.spi; 9 10 import java.io.IOException ; 11 import java.nio.channels.*; 12 13 14 32 33 public abstract class AbstractSelectableChannel 34 extends SelectableChannel 35 { 36 37 private final SelectorProvider provider; 39 40 private SelectionKey[] keys = null; 45 private int keyCount = 0; 46 47 private final Object keyLock = new Object (); 49 50 private final Object regLock = new Object (); 52 53 boolean blocking = true; 55 56 59 protected AbstractSelectableChannel(SelectorProvider provider) { 60 this.provider = provider; 61 } 62 63 68 public final SelectorProvider provider() { 69 return provider; 70 } 71 72 73 75 private void addKey(SelectionKey k) { 76 synchronized (keyLock) { 77 int i = 0; 78 if ((keys != null) && (keyCount < keys.length)) { 79 for (i = 0; i < keys.length; i++) 81 if (keys[i] == null) 82 break; 83 } else if (keys == null) { 84 keys = new SelectionKey[3]; 85 } else { 86 int n = keys.length * 2; 88 SelectionKey[] ks = new SelectionKey[n]; 89 for (i = 0; i < keys.length; i++) 90 ks[i] = keys[i]; 91 keys = ks; 92 i = keyCount; 93 } 94 keys[i] = k; 95 keyCount++; 96 } 97 } 98 99 private SelectionKey findKey(Selector sel) { 100 synchronized (keyLock) { 101 if (keys == null) 102 return null; 103 for (int i = 0; i < keys.length; i++) 104 if ((keys[i] != null) && (keys[i].selector() == sel)) 105 return keys[i]; 106 return null; 107 } 108 } 109 110 void removeKey(SelectionKey k) { synchronized (keyLock) { 112 for (int i = 0; i < keys.length; i++) 113 if (keys[i] == k) { 114 keys[i] = null; 115 keyCount--; 116 } 117 ((AbstractSelectionKey )k).invalidate(); 118 } 119 } 120 121 private boolean haveValidKeys() { 122 synchronized (keyLock) { 123 if (keyCount == 0) 124 return false; 125 for (int i = 0; i < keys.length; i++) { 126 if ((keys[i] != null) && keys[i].isValid()) 127 return true; 128 } 129 return false; 130 } 131 } 132 133 134 136 public final boolean isRegistered() { 137 synchronized (keyLock) { 138 return keyCount != 0; 139 } 140 } 141 142 public final SelectionKey keyFor(Selector sel) { 143 return findKey(sel); 144 } 145 146 162 public final SelectionKey register(Selector sel, int ops, 163 Object att) 164 throws ClosedChannelException 165 { 166 if (!isOpen()) 167 throw new ClosedChannelException(); 168 if ((ops & ~validOps()) != 0) 169 throw new IllegalArgumentException (); 170 synchronized (regLock) { 171 if (blocking) 172 throw new IllegalBlockingModeException(); 173 SelectionKey k = findKey(sel); 174 if (k != null) { 175 k.interestOps(ops); 176 k.attach(att); 177 } 178 if (k == null) { 179 k = ((AbstractSelector )sel).register(this, ops, att); 181 addKey(k); 182 } 183 return k; 184 } 185 } 186 187 188 190 200 protected final void implCloseChannel() throws IOException { 201 implCloseSelectableChannel(); 202 synchronized (keyLock) { 203 int count = (keys == null) ? 0 : keys.length; 204 for (int i = 0; i < count; i++) { 205 SelectionKey k = keys[i]; 206 if (k != null) 207 k.cancel(); 208 } 209 } 210 } 211 212 225 protected abstract void implCloseSelectableChannel() throws IOException ; 226 227 228 230 public final boolean isBlocking() { 231 synchronized (regLock) { 232 return blocking; 233 } 234 } 235 236 public final Object blockingLock() { 237 return regLock; 238 } 239 240 248 public final SelectableChannel configureBlocking(boolean block) 249 throws IOException 250 { 251 if (!isOpen()) 252 throw new ClosedChannelException(); 253 synchronized (regLock) { 254 if (blocking == block) 255 return this; 256 if (block && haveValidKeys()) 257 throw new IllegalBlockingModeException(); 258 implConfigureBlocking(block); 259 blocking = block; 260 } 261 return this; 262 } 263 264 275 protected abstract void implConfigureBlocking(boolean block) 276 throws IOException ; 277 278 } 279 | Popular Tags |