8199611: (se) Minor selector implementation clean-up
Reviewed-by: clanger, redestad, bpb
This commit is contained in:
parent
8994d5ad0e
commit
3a7f72200c
src/java.base
linux/classes/sun/nio/ch
macosx/classes/sun/nio/ch
share/classes/sun/nio/ch
solaris/classes/sun/nio/ch
windows/classes/sun/nio/ch
@ -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 @@ class EPoll {
|
||||
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);
|
||||
|
||||
|
@ -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 @@ class EPollArrayWrapper {
|
||||
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 @@ class EPollArrayWrapper {
|
||||
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 @@ class EPollArrayWrapper {
|
||||
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 @@ class EPollArrayWrapper {
|
||||
/**
|
||||
* 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 @@ class EPollArrayWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
@ -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 @@ final class EPollPort
|
||||
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;
|
||||
|
@ -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 @@ import java.util.*;
|
||||
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 @@ class EPollSelectorImpl
|
||||
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 @@ class EPollSelectorImpl
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ class EPollSelectorImpl
|
||||
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 @@ class EPollSelectorImpl
|
||||
((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 @@ class EPollSelectorImpl
|
||||
keys.add(ski);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void implDereg(SelectionKeyImpl ski) throws IOException {
|
||||
assert (ski.getIndex() >= 0);
|
||||
SelChImpl ch = ski.channel;
|
||||
@ -187,19 +185,20 @@ class EPollSelectorImpl
|
||||
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 @@ class EPollSelectorImpl
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void clearInterrupt() throws IOException {
|
||||
synchronized (interruptLock) {
|
||||
IOUtil.drain(fd0);
|
||||
interruptTriggered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 @@ class KQueue {
|
||||
|
||||
// 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;
|
||||
|
||||
|
@ -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 @@ class KQueueArrayWrapper {
|
||||
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 @@ class KQueueArrayWrapper {
|
||||
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 @@ class KQueueArrayWrapper {
|
||||
|
||||
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 @@ class KQueueArrayWrapper {
|
||||
* 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 @@ class KQueueArrayWrapper {
|
||||
|
||||
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 @@ class KQueueArrayWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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() {
|
||||
|
@ -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 @@ class KQueueSelectorImpl
|
||||
* 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 @@ class KQueueSelectorImpl
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ class KQueueSelectorImpl
|
||||
* 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 @@ class KQueueSelectorImpl
|
||||
// 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 @@ class KQueueSelectorImpl
|
||||
}
|
||||
|
||||
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 @@ class KQueueSelectorImpl
|
||||
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 @@ class KQueueSelectorImpl
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void clearInterrupt() throws IOException {
|
||||
synchronized (interruptLock) {
|
||||
IOUtil.drain(fd0);
|
||||
interruptTriggered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.*;
|
||||
import java.nio.channels.spi.*;
|
||||
|
||||
public class KQueueSelectorProvider
|
||||
extends SelectorProviderImpl
|
||||
extends SelectorProviderImpl
|
||||
{
|
||||
public AbstractSelector openSelector() throws IOException {
|
||||
return new KQueueSelectorImpl(this);
|
||||
|
@ -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 @@ abstract class AbstractPollSelectorImpl
|
||||
implCloseInterrupt();
|
||||
pollWrapper.free();
|
||||
pollWrapper = null;
|
||||
selectedKeys = null;
|
||||
channelArray = null;
|
||||
totalChannels = 0;
|
||||
}
|
||||
|
@ -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 @@ public class SelectionKeyImpl
|
||||
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 @@ public class SelectionKeyImpl
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.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;
|
||||
@ -47,16 +46,15 @@ import java.util.Set;
|
||||
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 @@ public abstract class SelectorImpl
|
||||
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 abstract class SelectorImpl
|
||||
}
|
||||
}
|
||||
|
||||
public int select(long timeout)
|
||||
@Override
|
||||
public final int select(long timeout)
|
||||
throws IOException
|
||||
{
|
||||
if (timeout < 0)
|
||||
@ -100,15 +101,18 @@ public abstract class SelectorImpl
|
||||
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 @@ public abstract class SelectorImpl
|
||||
|
||||
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 @@ public abstract class SelectorImpl
|
||||
|
||||
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 @@ public abstract class SelectorImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
|
||||
|
||||
public abstract Selector wakeup();
|
||||
|
||||
}
|
||||
|
@ -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 @@ class DevPollArrayWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
void closeDevPollFD() throws IOException {
|
||||
void close() throws IOException {
|
||||
FileDispatcherImpl.closeIntFD(wfd);
|
||||
pollArray.free();
|
||||
}
|
||||
|
@ -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 @@ import java.util.*;
|
||||
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 @@ class DevPollSelectorImpl
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ class DevPollSelectorImpl
|
||||
return numKeysUpdated;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void implClose() throws IOException {
|
||||
if (closed)
|
||||
return;
|
||||
@ -151,13 +156,10 @@ class DevPollSelectorImpl
|
||||
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 @@ class DevPollSelectorImpl
|
||||
((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 @@ class DevPollSelectorImpl
|
||||
((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) {
|
||||
|
@ -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 @@ class EventPortSelectorImpl
|
||||
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 @@ class EventPortSelectorImpl
|
||||
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 @@ class EventPortSelectorImpl
|
||||
return numKeysUpdated;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void implClose() throws IOException {
|
||||
if (closed)
|
||||
return;
|
||||
@ -116,7 +122,6 @@ class EventPortSelectorImpl
|
||||
}
|
||||
|
||||
pollWrapper.close();
|
||||
selectedKeys = null;
|
||||
|
||||
// Deregister channels
|
||||
Iterator<SelectionKey> i = keys.iterator();
|
||||
@ -130,12 +135,14 @@ class EventPortSelectorImpl
|
||||
}
|
||||
}
|
||||
|
||||
@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 @@ class EventPortSelectorImpl
|
||||
((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) {
|
||||
|
@ -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 @@ import java.util.Iterator;
|
||||
* @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 @@ final class WindowsSelectorImpl extends SelectorImpl {
|
||||
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 @@ final class WindowsSelectorImpl extends SelectorImpl {
|
||||
pollWrapper.addWakeupSocket(wakeupSourceFd, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doSelect(long timeout) throws IOException {
|
||||
if (channelArray == null)
|
||||
throw new ClosedSelectorException();
|
||||
@ -500,6 +501,7 @@ final class WindowsSelectorImpl extends SelectorImpl {
|
||||
return numKeysUpdated;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void implClose() throws IOException {
|
||||
synchronized (closeLock) {
|
||||
if (channelArray != null) {
|
||||
@ -520,7 +522,6 @@ final class WindowsSelectorImpl extends SelectorImpl {
|
||||
}
|
||||
pollWrapper.free();
|
||||
pollWrapper = null;
|
||||
selectedKeys = null;
|
||||
channelArray = null;
|
||||
// Make all remaining helper threads exit
|
||||
for (SelectThread t: threads)
|
||||
|
Loading…
x
Reference in New Issue
Block a user