8199611: (se) Minor selector implementation clean-up
Reviewed-by: clanger, redestad, bpb
--- a/src/java.base/linux/classes/sun/nio/ch/EPoll.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/linux/classes/sun/nio/ch/EPoll.java Thu Mar 15 10:47:58 2018 +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);
--- a/src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java Thu Mar 15 10:47:58 2018 +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<updated; i++) {
- if (getDescriptor(i) == incomingInterruptFD) {
- interruptedIndex = i;
- interrupted = true;
- break;
- }
- }
- return updated;
+ return epollWait(pollArrayAddress, NUM_EPOLLEVENTS, timeout, epfd);
}
/**
@@ -306,25 +289,10 @@
}
}
- // interrupt support
- private boolean interrupted = false;
-
public void interrupt() {
interrupt(outgoingInterruptFD);
}
- public int interruptedIndex() {
- return interruptedIndex;
- }
-
- boolean interrupted() {
- return interrupted;
- }
-
- void clearInterrupted() {
- interrupted = false;
- }
-
static {
IOUtil.load();
init();
--- a/src/java.base/linux/classes/sun/nio/ch/EPollPort.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/linux/classes/sun/nio/ch/EPollPort.java Thu Mar 15 10:47:58 2018 +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
@@ -93,7 +93,7 @@
try {
socketpair(sv);
// register one end with epoll
- epollCtl(epfd, EPOLL_CTL_ADD, sv[0], Net.POLLIN);
+ epollCtl(epfd, EPOLL_CTL_ADD, sv[0], EPOLLIN);
} catch (IOException x) {
close0(epfd);
throw x;
--- a/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java Thu Mar 15 10:47:58 2018 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, 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
@@ -37,16 +37,15 @@
class EPollSelectorImpl
extends SelectorImpl
{
-
// File descriptors used for interrupt
- protected int fd0;
- protected int fd1;
+ private final int fd0;
+ private final int fd1;
// The poll object
- EPollArrayWrapper pollWrapper;
+ private final EPollArrayWrapper pollWrapper;
// Maps from file descriptors to keys
- private Map<Integer,SelectionKeyImpl> fdToKey;
+ private final Map<Integer, SelectionKeyImpl> 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<entries; i++) {
+ for (int i=0; i<numEntries; i++) {
int nextFD = pollWrapper.getDescriptor(i);
- SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
- // ski is null in the case of an interrupt
- if (ski != null) {
- int rOps = pollWrapper.getEventOps(i);
- if (selectedKeys.contains(ski)) {
- if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
- numKeysUpdated++;
- }
- } else {
- ski.channel.translateAndSetReadyOps(rOps, ski);
- if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
- selectedKeys.add(ski);
- numKeysUpdated++;
+ if (nextFD == fd0) {
+ interrupted = true;
+ } else {
+ SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
+ if (ski != null) {
+ int rOps = pollWrapper.getEventOps(i);
+ if (selectedKeys.contains(ski)) {
+ if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
+ numKeysUpdated++;
+ }
+ } else {
+ ski.channel.translateAndSetReadyOps(rOps, ski);
+ if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
+ selectedKeys.add(ski);
+ numKeysUpdated++;
+ }
}
}
}
}
+
+ if (interrupted) {
+ clearInterrupt();
+ }
+
return numKeysUpdated;
}
+ @Override
protected void implClose() throws IOException {
if (closed)
return;
@@ -146,13 +149,10 @@
interruptTriggered = true;
}
+ pollWrapper.close();
FileDispatcherImpl.closeIntFD(fd0);
FileDispatcherImpl.closeIntFD(fd1);
- pollWrapper.closeEPollFD();
- // it is possible
- selectedKeys = null;
-
// Deregister channels
Iterator<SelectionKey> 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;
+ }
+ }
}
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueue.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueue.java Thu Mar 15 10:47:58 2018 +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;
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Thu Mar 15 10:47:58 2018 +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<Update> updateList = new LinkedList<Update>();
- 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() {
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Thu Mar 15 10:47:58 2018 +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<Integer,MapEntry> fdMap;
+ private final HashMap<Integer, MapEntry> 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<SelectionKey> 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<SelectionKey> 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;
+ }
+ }
}
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java Thu Mar 15 10:47:58 2018 +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);
--- a/src/java.base/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java Thu Mar 15 10:47:58 2018 +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;
}
--- a/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java Thu Mar 15 10:47:58 2018 +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();
+ }
+
}
--- a/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java Thu Mar 15 10:47:58 2018 +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<SelectionKey> keys;
// 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;
+ protected final Set<SelectionKey> selectedKeys;
// Public views of the key sets
- private Set<SelectionKey> publicKeys; // Immutable
- private Set<SelectionKey> publicSelectedKeys; // Removal allowed, but not addition
+ private final Set<SelectionKey> publicKeys; // Immutable
+ private final Set<SelectionKey> publicSelectedKeys; // Removal allowed, but not addition
protected SelectorImpl(SelectorProvider sp) {
super(sp);
@@ -66,13 +64,15 @@
publicSelectedKeys = Util.ungrowableSet(selectedKeys);
}
- public Set<SelectionKey> keys() {
+ @Override
+ public final Set<SelectionKey> keys() {
if (!isOpen())
throw new ClosedSelectorException();
return publicKeys;
}
- public Set<SelectionKey> selectedKeys() {
+ @Override
+ public final Set<SelectionKey> selectedKeys() {
if (!isOpen())
throw new ClosedSelectorException();
return publicSelectedKeys;
@@ -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<SelectionKey> cks = cancelledKeys();
synchronized (cks) {
@@ -159,9 +166,4 @@
}
}
}
-
- protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
-
- public abstract Selector wakeup();
-
}
--- a/src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java Thu Mar 15 10:47:58 2018 +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();
}
--- a/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Thu Mar 15 10:47:58 2018 +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<Integer,SelectionKeyImpl> fdToKey;
+ private final Map<Integer, SelectionKeyImpl> 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<SelectionKey> 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) {
--- a/src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java Thu Mar 15 10:47:58 2018 +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<Integer,SelectionKeyImpl> fdToKey;
+ private final Map<Integer, SelectionKeyImpl> 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<SelectionKey> 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) {
--- a/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Thu Mar 15 10:41:57 2018 +0100
+++ b/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Thu Mar 15 10:47:58 2018 +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<Integer, MapEntry> {
@@ -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)