--- old/src/java.base/linux/classes/sun/nio/ch/EPoll.java 2018-03-14 18:37:32.000000000 +0000 +++ new/src/java.base/linux/classes/sun/nio/ch/EPoll.java 2018-03-14 18:37:32.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, 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 @@ -59,6 +59,10 @@ static final int EPOLL_CTL_DEL = 2; static final int EPOLL_CTL_MOD = 3; + // events + static final int EPOLLIN = 0x1; + static final int EPOLLOUT = 0x4; + // flags static final int EPOLLONESHOT = (1 << 30); --- old/src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java 2018-03-14 18:37:34.000000000 +0000 +++ new/src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java 2018-03-14 18:37:34.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2018, 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 @@ -93,16 +93,10 @@ private final long pollArrayAddress; // The fd of the interrupt line going out - private int outgoingInterruptFD; - - // The fd of the interrupt line coming in - private int incomingInterruptFD; - - // The index of the interrupt FD - private int interruptedIndex; + private final int outgoingInterruptFD; // Number of updated pollfd entries - int updated; + private int updated; // object to synchronize fd registration changes private final Object updateLock = new Object(); @@ -125,7 +119,7 @@ private final BitSet registered = new BitSet(); - EPollArrayWrapper() throws IOException { + EPollArrayWrapper(int fd0, int fd1) throws IOException { // creates the epoll file descriptor epfd = epollCreate(); @@ -133,11 +127,8 @@ int allocationSize = NUM_EPOLLEVENTS * SIZE_EPOLLEVENT; pollArray = new AllocatedNativeObject(allocationSize, true); pollArrayAddress = pollArray.address(); - } - void initInterrupt(int fd0, int fd1) { outgoingInterruptFD = fd1; - incomingInterruptFD = fd0; epollCtl(epfd, EPOLL_CTL_ADD, fd0, EPOLLIN); } @@ -255,22 +246,14 @@ /** * Close epoll file descriptor and free poll array */ - void closeEPollFD() throws IOException { + void close() throws IOException { FileDispatcherImpl.closeIntFD(epfd); pollArray.free(); } int poll(long timeout) throws IOException { updateRegistrations(); - updated = epollWait(pollArrayAddress, NUM_EPOLLEVENTS, timeout, epfd); - for (int i=0; i fdToKey; + private final Map fdToKey; // True if this Selector has been closed private volatile boolean closed; @@ -65,8 +64,7 @@ fd0 = (int) (pipeFds >>> 32); fd1 = (int) pipeFds; try { - pollWrapper = new EPollArrayWrapper(); - pollWrapper.initInterrupt(fd0, fd1); + pollWrapper = new EPollArrayWrapper(fd0, fd1); fdToKey = new HashMap<>(); } catch (Throwable t) { try { @@ -83,59 +81,64 @@ } } - protected int doSelect(long timeout) throws IOException { + private void ensureOpen() { if (closed) throw new ClosedSelectorException(); + } + + @Override + protected int doSelect(long timeout) throws IOException { + ensureOpen(); + int numEntries; processDeregisterQueue(); try { begin(); - pollWrapper.poll(timeout); + numEntries = pollWrapper.poll(timeout); } finally { end(); } processDeregisterQueue(); - int numKeysUpdated = updateSelectedKeys(); - if (pollWrapper.interrupted()) { - // Clear the wakeup pipe - pollWrapper.putEventOps(pollWrapper.interruptedIndex(), 0); - synchronized (interruptLock) { - pollWrapper.clearInterrupted(); - IOUtil.drain(fd0); - interruptTriggered = false; - } - } - return numKeysUpdated; + return updateSelectedKeys(numEntries); } /** * Update the keys whose fd's have been selected by the epoll. * Add the ready keys to the ready queue. */ - private int updateSelectedKeys() { - int entries = pollWrapper.updated; + private int updateSelectedKeys(int numEntries) throws IOException { + boolean interrupted = false; int numKeysUpdated = 0; - for (int i=0; i i = keys.iterator(); while (i.hasNext()) { @@ -163,14 +163,11 @@ ((SelChImpl)selch).kill(); i.remove(); } - - fd0 = -1; - fd1 = -1; } + @Override protected void implRegister(SelectionKeyImpl ski) { - if (closed) - throw new ClosedSelectorException(); + ensureOpen(); SelChImpl ch = ski.channel; int fd = Integer.valueOf(ch.getFDVal()); fdToKey.put(fd, ski); @@ -178,6 +175,7 @@ keys.add(ski); } + @Override protected void implDereg(SelectionKeyImpl ski) throws IOException { assert (ski.getIndex() >= 0); SelChImpl ch = ski.channel; @@ -187,19 +185,20 @@ ski.setIndex(-1); keys.remove(ski); selectedKeys.remove(ski); - deregister((AbstractSelectionKey)ski); + deregister(ski); SelectableChannel selch = ski.channel(); if (!selch.isOpen() && !selch.isRegistered()) ((SelChImpl)selch).kill(); } + @Override public void putEventOps(SelectionKeyImpl ski, int ops) { - if (closed) - throw new ClosedSelectorException(); + ensureOpen(); SelChImpl ch = ski.channel; pollWrapper.setInterest(ch.getFDVal(), ops); } + @Override public Selector wakeup() { synchronized (interruptLock) { if (!interruptTriggered) { @@ -209,4 +208,11 @@ } return this; } + + private void clearInterrupt() throws IOException { + synchronized (interruptLock) { + IOUtil.drain(fd0); + interruptTriggered = false; + } + } } --- old/src/java.base/macosx/classes/sun/nio/ch/KQueue.java 2018-03-14 18:37:39.000000000 +0000 +++ new/src/java.base/macosx/classes/sun/nio/ch/KQueue.java 2018-03-14 18:37:39.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, 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 @@ -58,6 +58,7 @@ // flags static final int EV_ADD = 0x0001; + static final int EV_DELETE = 0x0002; static final int EV_ONESHOT = 0x0010; static final int EV_CLEAR = 0x0020; --- old/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java 2018-03-14 18:37:41.000000000 +0000 +++ new/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java 2018-03-14 18:37:41.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2018, 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 @@ -66,20 +66,18 @@ static final int NUM_KEVENTS = 128; // Are we in a 64-bit VM? - static boolean is64bit = false; + static boolean is64bit; // The kevent array (used for outcoming events only) - private AllocatedNativeObject keventArray = null; - private long keventArrayAddress; + private final AllocatedNativeObject keventArray; + private final long keventArrayAddress; // The kqueue fd - private int kq = -1; + private final int kq; // The fd of the interrupt line going out - private int outgoingInterruptFD; + private final int outgoingInterruptFD; - // The fd of the interrupt line coming in - private int incomingInterruptFD; static { IOUtil.load(); @@ -89,11 +87,13 @@ is64bit = "64".equals(datamodel); } - KQueueArrayWrapper() { + KQueueArrayWrapper(int fd0, int fd1) throws IOException { int allocationSize = SIZEOF_KEVENT * NUM_KEVENTS; keventArray = new AllocatedNativeObject(allocationSize, true); keventArrayAddress = keventArray.address(); kq = init(); + register0(kq, fd0, 1, 0); + outgoingInterruptFD = fd1; } // Used to update file description registrations @@ -108,12 +108,6 @@ private LinkedList updateList = new LinkedList(); - void initInterrupt(int fd0, int fd1) { - outgoingInterruptFD = fd1; - incomingInterruptFD = fd0; - register0(kq, fd0, 1, 0); - } - int getReventOps(int index) { int result = 0; int offset = SIZEOF_KEVENT*index + FILTER_OFFSET; @@ -137,11 +131,11 @@ * to return an int. Hence read the 8 bytes but return as an int. */ if (is64bit) { - long fd = keventArray.getLong(offset); - assert fd <= Integer.MAX_VALUE; - return (int) fd; + long fd = keventArray.getLong(offset); + assert fd <= Integer.MAX_VALUE; + return (int) fd; } else { - return keventArray.getInt(offset); + return keventArray.getInt(offset); } } @@ -168,7 +162,7 @@ void updateRegistrations() { synchronized (updateList) { - Update u = null; + Update u; while ((u = updateList.poll()) != null) { SelChImpl ch = u.channel; if (!ch.isOpen()) @@ -179,22 +173,14 @@ } } - void close() throws IOException { - if (keventArray != null) { - keventArray.free(); - keventArray = null; - } - if (kq >= 0) { - FileDispatcherImpl.closeIntFD(kq); - kq = -1; - } + FileDispatcherImpl.closeIntFD(kq); + keventArray.free(); } int poll(long timeout) { updateRegistrations(); - int updated = kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout); - return updated; + return kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout); } void interrupt() { --- old/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java 2018-03-14 18:37:43.000000000 +0000 +++ new/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java 2018-03-14 18:37:43.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2018, 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 @@ -26,39 +26,38 @@ /* * KQueueSelectorImpl.java * Implementation of Selector using FreeBSD / Mac OS X kqueues - * Derived from Sun's DevPollSelectorImpl */ package sun.nio.ch; import java.io.IOException; -import java.io.FileDescriptor; -import java.nio.channels.*; -import java.nio.channels.spi.*; -import java.util.*; +import java.nio.channels.ClosedSelectorException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.spi.SelectorProvider; +import java.util.HashMap; +import java.util.Iterator; class KQueueSelectorImpl extends SelectorImpl { // File descriptors used for interrupt - protected int fd0; - protected int fd1; + private final int fd0; + private final int fd1; // The kqueue manipulator - KQueueArrayWrapper kqueueWrapper; - - // Count of registered descriptors (including interrupt) - private int totalChannels; + private final KQueueArrayWrapper kqueueWrapper; // Map from a file descriptor to an entry containing the selection key - private HashMap fdMap; + private final HashMap fdMap; // True if this Selector has been closed - private boolean closed = false; + private boolean closed; // Lock for interrupt triggering and clearing - private Object interruptLock = new Object(); - private boolean interruptTriggered = false; + private final Object interruptLock = new Object(); + private boolean interruptTriggered; // used by updateSelectedKeys to handle cases where the same file // descriptor is polled by more than one filter @@ -78,16 +77,14 @@ * Package private constructor called by factory method in * the abstract superclass Selector. */ - KQueueSelectorImpl(SelectorProvider sp) { + KQueueSelectorImpl(SelectorProvider sp) throws IOException { super(sp); long fds = IOUtil.makePipe(false); fd0 = (int)(fds >>> 32); fd1 = (int)fds; try { - kqueueWrapper = new KQueueArrayWrapper(); - kqueueWrapper.initInterrupt(fd0, fd1); + kqueueWrapper = new KQueueArrayWrapper(fd0, fd1); fdMap = new HashMap<>(); - totalChannels = 1; } catch (Throwable t) { try { FileDispatcherImpl.closeIntFD(fd0); @@ -103,22 +100,26 @@ } } + private void ensureOpen() { + if (closed) + throw new ClosedSelectorException(); + } + @Override protected int doSelect(long timeout) throws IOException { - int entries = 0; - if (closed) - throw new ClosedSelectorException(); + ensureOpen(); + int numEntries; processDeregisterQueue(); try { begin(); - entries = kqueueWrapper.poll(timeout); + numEntries = kqueueWrapper.poll(timeout); } finally { end(); } processDeregisterQueue(); - return updateSelectedKeys(entries); + return updateSelectedKeys(numEntries); } /** @@ -126,7 +127,7 @@ * Add the ready keys to the selected key set. * If the interrupt fd has been selected, drain it and clear the interrupt. */ - private int updateSelectedKeys(int entries) + private int updateSelectedKeys(int numEntries) throws IOException { int numKeysUpdated = 0; @@ -139,14 +140,12 @@ // second or subsequent event. updateCount++; - for (int i = 0; i < entries; i++) { + for (int i = 0; i < numEntries; i++) { int nextFD = kqueueWrapper.getDescriptor(i); if (nextFD == fd0) { interrupted = true; } else { MapEntry me = fdMap.get(Integer.valueOf(nextFD)); - - // entry is null in the case of an interrupt if (me != null) { int rOps = kqueueWrapper.getReventOps(i); SelectionKeyImpl ski = me.ski; @@ -175,16 +174,12 @@ } if (interrupted) { - // Clear the wakeup pipe - synchronized (interruptLock) { - IOUtil.drain(fd0); - interruptTriggered = false; - } + clearInterrupt(); } return numKeysUpdated; } - + @Override protected void implClose() throws IOException { if (!closed) { closed = true; @@ -194,62 +189,51 @@ interruptTriggered = true; } + kqueueWrapper.close(); FileDispatcherImpl.closeIntFD(fd0); FileDispatcherImpl.closeIntFD(fd1); - if (kqueueWrapper != null) { - kqueueWrapper.close(); - kqueueWrapper = null; - selectedKeys = null; - - // Deregister channels - Iterator i = keys.iterator(); - while (i.hasNext()) { - SelectionKeyImpl ski = (SelectionKeyImpl)i.next(); - deregister(ski); - SelectableChannel selch = ski.channel(); - if (!selch.isOpen() && !selch.isRegistered()) - ((SelChImpl)selch).kill(); - i.remove(); - } - totalChannels = 0; + + // Deregister channels + Iterator i = keys.iterator(); + while (i.hasNext()) { + SelectionKeyImpl ski = (SelectionKeyImpl)i.next(); + deregister(ski); + SelectableChannel selch = ski.channel(); + if (!selch.isOpen() && !selch.isRegistered()) + ((SelChImpl)selch).kill(); + i.remove(); } - fd0 = -1; - fd1 = -1; } } - + @Override protected void implRegister(SelectionKeyImpl ski) { - if (closed) - throw new ClosedSelectorException(); + ensureOpen(); int fd = IOUtil.fdVal(ski.channel.getFD()); fdMap.put(Integer.valueOf(fd), new MapEntry(ski)); - totalChannels++; keys.add(ski); } - + @Override protected void implDereg(SelectionKeyImpl ski) throws IOException { int fd = ski.channel.getFDVal(); fdMap.remove(Integer.valueOf(fd)); kqueueWrapper.release(ski.channel); - totalChannels--; keys.remove(ski); selectedKeys.remove(ski); - deregister((AbstractSelectionKey)ski); + deregister(ski); SelectableChannel selch = ski.channel(); if (!selch.isOpen() && !selch.isRegistered()) ((SelChImpl)selch).kill(); } - + @Override public void putEventOps(SelectionKeyImpl ski, int ops) { - if (closed) - throw new ClosedSelectorException(); + ensureOpen(); kqueueWrapper.setInterest(ski.channel, ops); } - + @Override public Selector wakeup() { synchronized (interruptLock) { if (!interruptTriggered) { @@ -259,4 +243,11 @@ } return this; } + + private void clearInterrupt() throws IOException { + synchronized (interruptLock) { + IOUtil.drain(fd0); + interruptTriggered = false; + } + } } --- old/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java 2018-03-14 18:37:44.000000000 +0000 +++ new/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java 2018-03-14 18:37:44.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2018, 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 @@ -36,7 +36,7 @@ import java.nio.channels.spi.*; public class KQueueSelectorProvider -extends SelectorProviderImpl + extends SelectorProviderImpl { public AbstractSelector openSelector() throws IOException { return new KQueueSelectorImpl(this); --- old/src/java.base/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java 2018-03-14 18:37:46.000000000 +0000 +++ new/src/java.base/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java 2018-03-14 18:37:46.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2018, 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 @@ -99,7 +99,6 @@ implCloseInterrupt(); pollWrapper.free(); pollWrapper = null; - selectedKeys = null; channelArray = null; totalChannels = 0; } --- old/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java 2018-03-14 18:37:48.000000000 +0000 +++ new/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java 2018-03-14 18:37:48.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -25,9 +25,11 @@ package sun.nio.ch; -import java.io.IOException; -import java.nio.channels.*; -import java.nio.channels.spi.*; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.spi.AbstractSelectionKey; /** @@ -45,7 +47,7 @@ private int index; private volatile int interestOps; - private int readyOps; + private volatile int readyOps; SelectionKeyImpl(SelChImpl ch, SelectorImpl sel) { channel = ch; @@ -111,4 +113,22 @@ return interestOps; } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("channel=") + .append(channel) + .append(", selector=") + .append(selector); + if (isValid()) { + sb.append(", interestOps=") + .append(interestOps) + .append(", readyOps=") + .append(readyOps); + } else { + sb.append(", invalid"); + } + return sb.toString(); + } + } --- old/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java 2018-03-14 18:37:50.000000000 +0000 +++ new/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java 2018-03-14 18:37:50.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -30,7 +30,6 @@ 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; @@ -47,16 +46,15 @@ public abstract class SelectorImpl extends AbstractSelector { + // The set of keys registered with this Selector + protected final HashSet keys; // The set of keys with data ready for an operation - protected Set selectedKeys; - - // The set of keys registered with this Selector - protected HashSet keys; + protected final Set selectedKeys; // Public views of the key sets - private Set publicKeys; // Immutable - private Set publicSelectedKeys; // Removal allowed, but not addition + private final Set publicKeys; // Immutable + private final Set publicSelectedKeys; // Removal allowed, but not addition protected SelectorImpl(SelectorProvider sp) { super(sp); @@ -66,18 +64,20 @@ publicSelectedKeys = Util.ungrowableSet(selectedKeys); } - public Set keys() { + @Override + public final Set keys() { if (!isOpen()) throw new ClosedSelectorException(); return publicKeys; } - public Set selectedKeys() { + @Override + public final Set selectedKeys() { if (!isOpen()) throw new ClosedSelectorException(); return publicSelectedKeys; } - + protected abstract int doSelect(long timeout) throws IOException; private int lockAndDoSelect(long timeout) throws IOException { @@ -92,7 +92,8 @@ } } - public int select(long timeout) + @Override + public final int select(long timeout) throws IOException { if (timeout < 0) @@ -100,15 +101,18 @@ return lockAndDoSelect((timeout == 0) ? -1 : timeout); } - public int select() throws IOException { + @Override + public final int select() throws IOException { return select(0); } - public int selectNow() throws IOException { + @Override + public final int selectNow() throws IOException { return lockAndDoSelect(0); } - public void implCloseSelector() throws IOException { + @Override + public final void implCloseSelector() throws IOException { wakeup(); synchronized (this) { synchronized (publicKeys) { @@ -121,8 +125,9 @@ protected abstract void implClose() throws IOException; - public void putEventOps(SelectionKeyImpl sk, int ops) { } + public abstract void putEventOps(SelectionKeyImpl sk, int ops); + @Override protected final SelectionKey register(AbstractSelectableChannel ch, int ops, Object attachment) @@ -140,7 +145,9 @@ protected abstract void implRegister(SelectionKeyImpl ski); - void processDeregisterQueue() throws IOException { + protected abstract void implDereg(SelectionKeyImpl ski) throws IOException; + + protected final void processDeregisterQueue() throws IOException { // Precondition: Synchronized on this, keys, and selectedKeys Set cks = cancelledKeys(); synchronized (cks) { @@ -159,9 +166,4 @@ } } } - - protected abstract void implDereg(SelectionKeyImpl ski) throws IOException; - - public abstract Selector wakeup(); - } --- old/src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java 2018-03-14 18:37:52.000000000 +0000 +++ new/src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java 2018-03-14 18:37:51.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2018, 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 @@ -213,7 +213,7 @@ } } - void closeDevPollFD() throws IOException { + void close() throws IOException { FileDispatcherImpl.closeIntFD(wfd); pollArray.free(); } --- old/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java 2018-03-14 18:37:53.000000000 +0000 +++ new/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java 2018-03-14 18:37:53.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2018, 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 @@ -37,26 +37,25 @@ class DevPollSelectorImpl extends SelectorImpl { - // File descriptors used for interrupt - protected int fd0; - protected int fd1; + private final int fd0; + private final int fd1; // The poll object - DevPollArrayWrapper pollWrapper; + private final DevPollArrayWrapper pollWrapper; // Maps from file descriptors to keys - private Map fdToKey; + private final Map fdToKey; // True if this Selector has been closed - private boolean closed = false; + private boolean closed; // Lock for close/cleanup - private Object closeLock = new Object(); + private final Object closeLock = new Object(); // Lock for interrupt triggering and clearing - private Object interruptLock = new Object(); - private boolean interruptTriggered = false; + private final Object interruptLock = new Object(); + private boolean interruptTriggered; /** * Package private constructor called by factory method in @@ -86,11 +85,16 @@ } } + private void ensureOpen() { + if (closed) + throw new ClosedSelectorException(); + } + + @Override protected int doSelect(long timeout) throws IOException { - if (closed) - throw new ClosedSelectorException(); + ensureOpen(); processDeregisterQueue(); try { begin(); @@ -141,6 +145,7 @@ return numKeysUpdated; } + @Override protected void implClose() throws IOException { if (closed) return; @@ -151,13 +156,10 @@ interruptTriggered = true; } + pollWrapper.close(); FileDispatcherImpl.closeIntFD(fd0); FileDispatcherImpl.closeIntFD(fd1); - pollWrapper.release(fd0); - pollWrapper.closeDevPollFD(); - selectedKeys = null; - // Deregister channels Iterator i = keys.iterator(); while (i.hasNext()) { @@ -168,16 +170,16 @@ ((SelChImpl)selch).kill(); i.remove(); } - fd0 = -1; - fd1 = -1; } + @Override protected void implRegister(SelectionKeyImpl ski) { int fd = IOUtil.fdVal(ski.channel.getFD()); fdToKey.put(Integer.valueOf(fd), ski); keys.add(ski); } + @Override protected void implDereg(SelectionKeyImpl ski) throws IOException { int i = ski.getIndex(); assert (i >= 0); @@ -193,13 +195,14 @@ ((SelChImpl)selch).kill(); } + @Override public void putEventOps(SelectionKeyImpl sk, int ops) { - if (closed) - throw new ClosedSelectorException(); + ensureOpen(); int fd = IOUtil.fdVal(sk.channel.getFD()); pollWrapper.setInterest(fd, ops); } + @Override public Selector wakeup() { synchronized (interruptLock) { if (!interruptTriggered) { --- old/src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java 2018-03-14 18:37:55.000000000 +0000 +++ new/src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java 2018-03-14 18:37:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, 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 @@ -42,14 +42,14 @@ private final EventPortWrapper pollWrapper; // Maps from file descriptors to keys - private Map fdToKey; + private final Map fdToKey; // True if this Selector has been closed - private boolean closed = false; + private boolean closed; // Lock for interrupt triggering and clearing private final Object interruptLock = new Object(); - private boolean interruptTriggered = false; + private boolean interruptTriggered; /** * Package private constructor called by factory method in @@ -61,9 +61,14 @@ fdToKey = new HashMap<>(); } - protected int doSelect(long timeout) throws IOException { + private void ensureOpen() { if (closed) throw new ClosedSelectorException(); + } + + @Override + protected int doSelect(long timeout) throws IOException { + ensureOpen(); processDeregisterQueue(); int entries; try { @@ -105,6 +110,7 @@ return numKeysUpdated; } + @Override protected void implClose() throws IOException { if (closed) return; @@ -116,7 +122,6 @@ } pollWrapper.close(); - selectedKeys = null; // Deregister channels Iterator i = keys.iterator(); @@ -130,12 +135,14 @@ } } + @Override protected void implRegister(SelectionKeyImpl ski) { int fd = IOUtil.fdVal(ski.channel.getFD()); fdToKey.put(Integer.valueOf(fd), ski); keys.add(ski); } + @Override protected void implDereg(SelectionKeyImpl ski) throws IOException { int i = ski.getIndex(); assert (i >= 0); @@ -151,13 +158,14 @@ ((SelChImpl)selch).kill(); } + @Override public void putEventOps(SelectionKeyImpl sk, int ops) { - if (closed) - throw new ClosedSelectorException(); + ensureOpen(); int fd = sk.channel.getFDVal(); pollWrapper.setInterest(fd, ops); } + @Override public Selector wakeup() { synchronized (interruptLock) { if (!interruptTriggered) { --- old/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java 2018-03-14 18:37:57.000000000 +0000 +++ new/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java 2018-03-14 18:37:57.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2018, 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 @@ -48,7 +48,7 @@ * @author Mark Reinhold */ -final class WindowsSelectorImpl extends SelectorImpl { +class WindowsSelectorImpl extends SelectorImpl { // Initial capacity of the poll array private final int INIT_CAP = 8; // Maximum number of sockets for select(). @@ -81,7 +81,7 @@ private final int wakeupSourceFd, wakeupSinkFd; // Lock for close cleanup - private Object closeLock = new Object(); + private final Object closeLock = new Object(); // Maps file descriptors to their indices in pollArray private static final class FdMap extends HashMap { @@ -135,6 +135,7 @@ pollWrapper.addWakeupSocket(wakeupSourceFd, 0); } + @Override protected int doSelect(long timeout) throws IOException { if (channelArray == null) throw new ClosedSelectorException(); @@ -500,6 +501,7 @@ return numKeysUpdated; } + @Override protected void implClose() throws IOException { synchronized (closeLock) { if (channelArray != null) { @@ -520,7 +522,6 @@ } pollWrapper.free(); pollWrapper = null; - selectedKeys = null; channelArray = null; // Make all remaining helper threads exit for (SelectThread t: threads)