--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.ch;
+
+import java.io.IOException;
+import java.net.SocketException;
+import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.IllegalSelectorException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.AbstractSelector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+
+/**
+ * Base Selector implementation class.
+ */
+
+public abstract class SelectorImpl
+ extends AbstractSelector
+{
+
+ // The set of keys with data ready for an operation
+ protected Set<SelectionKey> selectedKeys;
+
+ // The set of keys registered with this Selector
+ protected HashSet<SelectionKey> keys;
+
+ // Public views of the key sets
+ private Set<SelectionKey> publicKeys; // Immutable
+ private Set<SelectionKey> publicSelectedKeys; // Removal allowed, but not addition
+
+ protected SelectorImpl(SelectorProvider sp) {
+ super(sp);
+ keys = new HashSet<>();
+ selectedKeys = new HashSet<>();
+ publicKeys = Collections.unmodifiableSet(keys);
+ publicSelectedKeys = Util.ungrowableSet(selectedKeys);
+ }
+
+ public Set<SelectionKey> keys() {
+ if (!isOpen())
+ throw new ClosedSelectorException();
+ return publicKeys;
+ }
+
+ public Set<SelectionKey> selectedKeys() {
+ if (!isOpen())
+ throw new ClosedSelectorException();
+ return publicSelectedKeys;
+ }
+
+ protected abstract int doSelect(long timeout) throws IOException;
+
+ private int lockAndDoSelect(long timeout) throws IOException {
+ synchronized (this) {
+ if (!isOpen())
+ throw new ClosedSelectorException();
+ synchronized (publicKeys) {
+ synchronized (publicSelectedKeys) {
+ return doSelect(timeout);
+ }
+ }
+ }
+ }
+
+ public int select(long timeout)
+ throws IOException
+ {
+ if (timeout < 0)
+ throw new IllegalArgumentException("Negative timeout");
+ return lockAndDoSelect((timeout == 0) ? -1 : timeout);
+ }
+
+ public int select() throws IOException {
+ return select(0);
+ }
+
+ public int selectNow() throws IOException {
+ return lockAndDoSelect(0);
+ }
+
+ public void implCloseSelector() throws IOException {
+ wakeup();
+ synchronized (this) {
+ synchronized (publicKeys) {
+ synchronized (publicSelectedKeys) {
+ implClose();
+ }
+ }
+ }
+ }
+
+ protected abstract void implClose() throws IOException;
+
+ public void putEventOps(SelectionKeyImpl sk, int ops) { }
+
+ protected final SelectionKey register(AbstractSelectableChannel ch,
+ int ops,
+ Object attachment)
+ {
+ if (!(ch instanceof SelChImpl))
+ throw new IllegalSelectorException();
+ SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);
+ k.attach(attachment);
+ synchronized (publicKeys) {
+ implRegister(k);
+ }
+ k.interestOps(ops);
+ return k;
+ }
+
+ protected abstract void implRegister(SelectionKeyImpl ski);
+
+ void processDeregisterQueue() throws IOException {
+ // Precondition: Synchronized on this, keys, and selectedKeys
+ Set<SelectionKey> cks = cancelledKeys();
+ synchronized (cks) {
+ if (!cks.isEmpty()) {
+ Iterator<SelectionKey> i = cks.iterator();
+ while (i.hasNext()) {
+ SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
+ try {
+ implDereg(ski);
+ } catch (SocketException se) {
+ throw new IOException("Error deregistering key", se);
+ } finally {
+ i.remove();
+ }
+ }
+ }
+ }
+ }
+
+ protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
+
+ public abstract Selector wakeup();
+
+}