mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8199611: (se) Minor selector implementation clean-up
Reviewed-by: clanger, redestad, bpb
This commit is contained in:
parent
8994d5ad0e
commit
3a7f72200c
15 changed files with 238 additions and 249 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue