mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8200257: (se) More Selector cleanup
Reviewed-by: bpb
This commit is contained in:
parent
8a1bee438c
commit
34c94079ed
20 changed files with 457 additions and 548 deletions
|
@ -27,15 +27,11 @@ package sun.nio.ch;
|
|||
|
||||
import java.io.IOException;
|
||||
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.ArrayDeque;
|
||||
import java.util.BitSet;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -66,15 +62,11 @@ class KQueueSelectorImpl extends SelectorImpl {
|
|||
// maps file descriptor to selection key, synchronize on selector
|
||||
private final Map<Integer, SelectionKeyImpl> fdToKey = new HashMap<>();
|
||||
|
||||
// file descriptors registered with kqueue, synchronize on selector
|
||||
private final BitSet registeredReadFilter = new BitSet();
|
||||
private final BitSet registeredWriteFilter = new BitSet();
|
||||
|
||||
// pending new registrations/updates, queued by implRegister and putEventOps
|
||||
private final Object updateLock = new Object();
|
||||
private final Deque<SelectionKeyImpl> newKeys = new ArrayDeque<>();
|
||||
private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
|
||||
private final Deque<Integer> updateOps = new ArrayDeque<>();
|
||||
private final Deque<Integer> updateEvents = new ArrayDeque<>();
|
||||
|
||||
// interrupt triggering and clearing
|
||||
private final Object interruptLock = new Object();
|
||||
|
@ -113,14 +105,16 @@ class KQueueSelectorImpl extends SelectorImpl {
|
|||
protected int doSelect(long timeout) throws IOException {
|
||||
assert Thread.holdsLock(this);
|
||||
|
||||
long to = Math.min(timeout, Integer.MAX_VALUE); // max kqueue timeout
|
||||
boolean blocking = (to != 0);
|
||||
boolean timedPoll = (to > 0);
|
||||
|
||||
int numEntries;
|
||||
processUpdateQueue();
|
||||
processDeregisterQueue();
|
||||
try {
|
||||
begin();
|
||||
begin(blocking);
|
||||
|
||||
long to = Math.min(timeout, Integer.MAX_VALUE); // max kqueue timeout
|
||||
boolean timedPoll = (to > 0);
|
||||
do {
|
||||
long startTime = timedPoll ? System.nanoTime() : 0;
|
||||
numEntries = KQueue.poll(kqfd, pollArrayAddress, MAX_KEVENTS, to);
|
||||
|
@ -137,7 +131,7 @@ class KQueueSelectorImpl extends SelectorImpl {
|
|||
assert IOStatus.check(numEntries);
|
||||
|
||||
} finally {
|
||||
end();
|
||||
end(blocking);
|
||||
}
|
||||
processDeregisterQueue();
|
||||
return updateSelectedKeys(numEntries);
|
||||
|
@ -155,41 +149,41 @@ class KQueueSelectorImpl extends SelectorImpl {
|
|||
// new registrations
|
||||
while ((ski = newKeys.pollFirst()) != null) {
|
||||
if (ski.isValid()) {
|
||||
SelChImpl ch = ski.channel;
|
||||
int fd = ch.getFDVal();
|
||||
int fd = ski.channel.getFDVal();
|
||||
SelectionKeyImpl previous = fdToKey.put(fd, ski);
|
||||
assert previous == null;
|
||||
assert registeredReadFilter.get(fd) == false;
|
||||
assert registeredWriteFilter.get(fd) == false;
|
||||
assert ski.registeredEvents() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
// changes to interest ops
|
||||
assert updateKeys.size() == updateOps.size();
|
||||
assert updateKeys.size() == updateKeys.size();
|
||||
while ((ski = updateKeys.pollFirst()) != null) {
|
||||
int ops = updateOps.pollFirst();
|
||||
int newEvents = updateEvents.pollFirst();
|
||||
int fd = ski.channel.getFDVal();
|
||||
if (ski.isValid() && fdToKey.containsKey(fd)) {
|
||||
// add or delete interest in read events
|
||||
if (registeredReadFilter.get(fd)) {
|
||||
if ((ops & Net.POLLIN) == 0) {
|
||||
KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
|
||||
registeredReadFilter.clear(fd);
|
||||
}
|
||||
} else if ((ops & Net.POLLIN) != 0) {
|
||||
KQueue.register(kqfd, fd, EVFILT_READ, EV_ADD);
|
||||
registeredReadFilter.set(fd);
|
||||
}
|
||||
int registeredEvents = ski.registeredEvents();
|
||||
if (newEvents != registeredEvents) {
|
||||
|
||||
// add or delete interest in write events
|
||||
if (registeredWriteFilter.get(fd)) {
|
||||
if ((ops & Net.POLLOUT) == 0) {
|
||||
KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
|
||||
registeredWriteFilter.clear(fd);
|
||||
// add or delete interest in read events
|
||||
if ((registeredEvents & Net.POLLIN) != 0) {
|
||||
if ((newEvents & Net.POLLIN) == 0) {
|
||||
KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
|
||||
}
|
||||
} else if ((newEvents & Net.POLLIN) != 0) {
|
||||
KQueue.register(kqfd, fd, EVFILT_READ, EV_ADD);
|
||||
}
|
||||
} else if ((ops & Net.POLLOUT) != 0) {
|
||||
KQueue.register(kqfd, fd, EVFILT_WRITE, EV_ADD);
|
||||
registeredWriteFilter.set(fd);
|
||||
|
||||
// add or delete interest in write events
|
||||
if ((registeredEvents & Net.POLLOUT) != 0) {
|
||||
if ((newEvents & Net.POLLOUT) == 0) {
|
||||
KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
|
||||
}
|
||||
} else if ((newEvents & Net.POLLOUT) != 0) {
|
||||
KQueue.register(kqfd, fd, EVFILT_WRITE, EV_ADD);
|
||||
}
|
||||
|
||||
ski.registeredEvents(newEvents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -197,8 +191,8 @@ class KQueueSelectorImpl extends SelectorImpl {
|
|||
}
|
||||
|
||||
/**
|
||||
* Update the keys whose fd's have been selected by kqueue.
|
||||
* Add the ready keys to the selected key set.
|
||||
* Update the keys of file descriptors that were polled and add them to
|
||||
* the selected-key set.
|
||||
* If the interrupt fd has been selected, drain it and clear the interrupt.
|
||||
*/
|
||||
private int updateSelectedKeys(int numEntries) throws IOException {
|
||||
|
@ -265,7 +259,6 @@ class KQueueSelectorImpl extends SelectorImpl {
|
|||
protected void implClose() throws IOException {
|
||||
assert !isOpen();
|
||||
assert Thread.holdsLock(this);
|
||||
assert Thread.holdsLock(nioKeys());
|
||||
|
||||
// prevent further wakeup
|
||||
synchronized (interruptLock) {
|
||||
|
@ -277,63 +270,41 @@ class KQueueSelectorImpl extends SelectorImpl {
|
|||
|
||||
FileDispatcherImpl.closeIntFD(fd0);
|
||||
FileDispatcherImpl.closeIntFD(fd1);
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void implRegister(SelectionKeyImpl ski) {
|
||||
assert Thread.holdsLock(nioKeys());
|
||||
ensureOpen();
|
||||
synchronized (updateLock) {
|
||||
newKeys.addLast(ski);
|
||||
}
|
||||
keys.add(ski);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void implDereg(SelectionKeyImpl ski) throws IOException {
|
||||
assert !ski.isValid();
|
||||
assert Thread.holdsLock(this);
|
||||
assert Thread.holdsLock(nioKeys());
|
||||
assert Thread.holdsLock(nioSelectedKeys());
|
||||
|
||||
int fd = ski.channel.getFDVal();
|
||||
fdToKey.remove(fd);
|
||||
if (registeredReadFilter.get(fd)) {
|
||||
KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
|
||||
registeredReadFilter.clear(fd);
|
||||
int registeredEvents = ski.registeredEvents();
|
||||
if (fdToKey.remove(fd) != null) {
|
||||
if (registeredEvents != 0) {
|
||||
if ((registeredEvents & Net.POLLIN) != 0)
|
||||
KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
|
||||
if ((registeredEvents & Net.POLLOUT) != 0)
|
||||
KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
|
||||
ski.registeredEvents(0);
|
||||
}
|
||||
} else {
|
||||
assert registeredEvents == 0;
|
||||
}
|
||||
if (registeredWriteFilter.get(fd)) {
|
||||
KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
|
||||
registeredWriteFilter.clear(fd);
|
||||
}
|
||||
|
||||
selectedKeys.remove(ski);
|
||||
keys.remove(ski);
|
||||
|
||||
// remove from channel's key set
|
||||
deregister(ski);
|
||||
|
||||
SelectableChannel selch = ski.channel();
|
||||
if (!selch.isOpen() && !selch.isRegistered())
|
||||
((SelChImpl) selch).kill();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putEventOps(SelectionKeyImpl ski, int ops) {
|
||||
public void putEventOps(SelectionKeyImpl ski, int events) {
|
||||
ensureOpen();
|
||||
synchronized (updateLock) {
|
||||
updateOps.addLast(ops); // ops first in case adding the key fails
|
||||
updateEvents.addLast(events); // events first in case adding key fails
|
||||
updateKeys.addLast(ski);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue