1 /* |
1 /* |
2 * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
31 import java.nio.channels.SelectableChannel; |
31 import java.nio.channels.SelectableChannel; |
32 import java.nio.channels.SelectionKey; |
32 import java.nio.channels.SelectionKey; |
33 import java.nio.channels.spi.AbstractSelectableChannel; |
33 import java.nio.channels.spi.AbstractSelectableChannel; |
34 import java.nio.channels.spi.AbstractSelector; |
34 import java.nio.channels.spi.AbstractSelector; |
35 import java.nio.channels.spi.SelectorProvider; |
35 import java.nio.channels.spi.SelectorProvider; |
|
36 import java.util.ArrayDeque; |
36 import java.util.Collections; |
37 import java.util.Collections; |
|
38 import java.util.Deque; |
37 import java.util.HashSet; |
39 import java.util.HashSet; |
38 import java.util.Iterator; |
40 import java.util.Iterator; |
39 import java.util.Objects; |
41 import java.util.Objects; |
40 import java.util.Set; |
42 import java.util.Set; |
41 import java.util.concurrent.ConcurrentHashMap; |
43 import java.util.concurrent.ConcurrentHashMap; |
44 |
46 |
45 /** |
47 /** |
46 * Base Selector implementation class. |
48 * Base Selector implementation class. |
47 */ |
49 */ |
48 |
50 |
49 abstract class SelectorImpl |
51 public abstract class SelectorImpl |
50 extends AbstractSelector |
52 extends AbstractSelector |
51 { |
53 { |
52 // The set of keys registered with this Selector |
54 // The set of keys registered with this Selector |
53 private final Set<SelectionKey> keys; |
55 private final Set<SelectionKey> keys; |
54 |
56 |
56 private final Set<SelectionKey> selectedKeys; |
58 private final Set<SelectionKey> selectedKeys; |
57 |
59 |
58 // Public views of the key sets |
60 // Public views of the key sets |
59 private final Set<SelectionKey> publicKeys; // Immutable |
61 private final Set<SelectionKey> publicKeys; // Immutable |
60 private final Set<SelectionKey> publicSelectedKeys; // Removal allowed, but not addition |
62 private final Set<SelectionKey> publicSelectedKeys; // Removal allowed, but not addition |
|
63 |
|
64 // pending cancelled keys for deregistration |
|
65 private final Deque<SelectionKeyImpl> cancelledKeys = new ArrayDeque<>(); |
61 |
66 |
62 // used to check for reentrancy |
67 // used to check for reentrancy |
63 private boolean inSelect; |
68 private boolean inSelect; |
64 |
69 |
65 protected SelectorImpl(SelectorProvider sp) { |
70 protected SelectorImpl(SelectorProvider sp) { |
237 * Removes the key from the selector |
242 * Removes the key from the selector |
238 */ |
243 */ |
239 protected abstract void implDereg(SelectionKeyImpl ski) throws IOException; |
244 protected abstract void implDereg(SelectionKeyImpl ski) throws IOException; |
240 |
245 |
241 /** |
246 /** |
242 * Invoked by selection operations to process the cancelled-key set |
247 * Queue a cancelled key for the next selection operation |
|
248 */ |
|
249 public void cancel(SelectionKeyImpl ski) { |
|
250 synchronized (cancelledKeys) { |
|
251 cancelledKeys.addLast(ski); |
|
252 } |
|
253 } |
|
254 |
|
255 /** |
|
256 * Invoked by selection operations to process the cancelled keys |
243 */ |
257 */ |
244 protected final void processDeregisterQueue() throws IOException { |
258 protected final void processDeregisterQueue() throws IOException { |
245 assert Thread.holdsLock(this); |
259 assert Thread.holdsLock(this); |
246 assert Thread.holdsLock(publicSelectedKeys); |
260 assert Thread.holdsLock(publicSelectedKeys); |
247 |
261 |
248 Set<SelectionKey> cks = cancelledKeys(); |
262 synchronized (cancelledKeys) { |
249 synchronized (cks) { |
263 SelectionKeyImpl ski; |
250 if (!cks.isEmpty()) { |
264 while ((ski = cancelledKeys.pollFirst()) != null) { |
251 Iterator<SelectionKey> i = cks.iterator(); |
265 // remove the key from the selector |
252 while (i.hasNext()) { |
266 implDereg(ski); |
253 SelectionKeyImpl ski = (SelectionKeyImpl)i.next(); |
267 |
254 i.remove(); |
268 selectedKeys.remove(ski); |
255 |
269 keys.remove(ski); |
256 // remove the key from the selector |
270 |
257 implDereg(ski); |
271 // remove from channel's key set |
258 |
272 deregister(ski); |
259 selectedKeys.remove(ski); |
273 |
260 keys.remove(ski); |
274 SelectableChannel ch = ski.channel(); |
261 |
275 if (!ch.isOpen() && !ch.isRegistered()) |
262 // remove from channel's key set |
276 ((SelChImpl)ch).kill(); |
263 deregister(ski); |
|
264 |
|
265 SelectableChannel ch = ski.channel(); |
|
266 if (!ch.isOpen() && !ch.isRegistered()) |
|
267 ((SelChImpl)ch).kill(); |
|
268 } |
|
269 } |
277 } |
270 } |
278 } |
271 } |
279 } |
272 |
280 |
273 /** |
281 /** |