mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8199433: (se) select(Consumer<SelectionKey> action) as alternative to selected-key set
Reviewed-by: bpb
This commit is contained in:
parent
4a24d95917
commit
db61a602f6
10 changed files with 1188 additions and 157 deletions
|
@ -27,6 +27,7 @@ package sun.nio.ch;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.ClosedSelectorException;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.util.ArrayDeque;
|
||||
|
@ -34,6 +35,7 @@ import java.util.Deque;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static sun.nio.ch.DevPollArrayWrapper.NUM_POLLFDS;
|
||||
import static sun.nio.ch.DevPollArrayWrapper.POLLREMOVE;
|
||||
|
@ -85,7 +87,9 @@ class DevPollSelectorImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
protected int doSelect(long timeout) throws IOException {
|
||||
protected int doSelect(Consumer<SelectionKey> action, long timeout)
|
||||
throws IOException
|
||||
{
|
||||
assert Thread.holdsLock(this);
|
||||
|
||||
long to = timeout;
|
||||
|
@ -117,7 +121,7 @@ class DevPollSelectorImpl
|
|||
end(blocking);
|
||||
}
|
||||
processDeregisterQueue();
|
||||
return updateSelectedKeys(numEntries);
|
||||
return processEvents(numEntries, action);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,13 +169,13 @@ class DevPollSelectorImpl
|
|||
}
|
||||
|
||||
/**
|
||||
* Update the keys of file descriptors that were polled and add them to
|
||||
* the selected-key set.
|
||||
* Process the polled events.
|
||||
* If the interrupt fd has been selected, drain it and clear the interrupt.
|
||||
*/
|
||||
private int updateSelectedKeys(int numEntries) throws IOException {
|
||||
private int processEvents(int numEntries, Consumer<SelectionKey> action)
|
||||
throws IOException
|
||||
{
|
||||
assert Thread.holdsLock(this);
|
||||
assert Thread.holdsLock(nioSelectedKeys());
|
||||
|
||||
boolean interrupted = false;
|
||||
int numKeysUpdated = 0;
|
||||
|
@ -183,17 +187,7 @@ class DevPollSelectorImpl
|
|||
SelectionKeyImpl ski = fdToKey.get(fd);
|
||||
if (ski != null) {
|
||||
int rOps = pollWrapper.getReventOps(i);
|
||||
if (selectedKeys.contains(ski)) {
|
||||
if (ski.translateAndUpdateReadyOps(rOps)) {
|
||||
numKeysUpdated++;
|
||||
}
|
||||
} else {
|
||||
ski.translateAndSetReadyOps(rOps);
|
||||
if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
|
||||
selectedKeys.add(ski);
|
||||
numKeysUpdated++;
|
||||
}
|
||||
}
|
||||
numKeysUpdated += processReadyEvents(rOps, ski, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Deque;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static sun.nio.ch.SolarisEventPort.PORT_SOURCE_FD;
|
||||
import static sun.nio.ch.SolarisEventPort.PORT_SOURCE_USER;
|
||||
|
@ -97,7 +98,9 @@ class EventPortSelectorImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
protected int doSelect(long timeout) throws IOException {
|
||||
protected int doSelect(Consumer<SelectionKey> action, long timeout)
|
||||
throws IOException
|
||||
{
|
||||
assert Thread.holdsLock(this);
|
||||
|
||||
long to = timeout;
|
||||
|
@ -129,7 +132,7 @@ class EventPortSelectorImpl
|
|||
end(blocking);
|
||||
}
|
||||
processDeregisterQueue();
|
||||
return processPortEvents(numEvents);
|
||||
return processPortEvents(numEvents, action);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,19 +169,21 @@ class EventPortSelectorImpl
|
|||
}
|
||||
|
||||
/**
|
||||
* Process the port events. This method updates the keys of file descriptors
|
||||
* that were polled. It also re-queues the key so that the file descriptor
|
||||
* is re-associated at the next select operation.
|
||||
*
|
||||
* @return the number of selection keys updated.
|
||||
* Process the polled events and re-queue the selected keys so the file
|
||||
* descriptors are re-associated at the next select operation.
|
||||
*/
|
||||
private int processPortEvents(int numEvents) throws IOException {
|
||||
private int processPortEvents(int numEvents, Consumer<SelectionKey> action)
|
||||
throws IOException
|
||||
{
|
||||
assert Thread.holdsLock(this);
|
||||
assert Thread.holdsLock(nioSelectedKeys());
|
||||
|
||||
int numKeysUpdated = 0;
|
||||
boolean interrupted = false;
|
||||
|
||||
// Process the polled events while holding the update lock. This allows
|
||||
// keys to be queued for ready file descriptors so they can be
|
||||
// re-associated at the next select. The selected-key can be updated
|
||||
// in this pass.
|
||||
synchronized (updateLock) {
|
||||
for (int i = 0; i < numEvents; i++) {
|
||||
short source = getSource(i);
|
||||
|
@ -186,22 +191,15 @@ class EventPortSelectorImpl
|
|||
int fd = getDescriptor(i);
|
||||
SelectionKeyImpl ski = fdToKey.get(fd);
|
||||
if (ski != null) {
|
||||
int rOps = getEventOps(i);
|
||||
if (selectedKeys.contains(ski)) {
|
||||
if (ski.translateAndUpdateReadyOps(rOps)) {
|
||||
numKeysUpdated++;
|
||||
}
|
||||
} else {
|
||||
ski.translateAndSetReadyOps(rOps);
|
||||
if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
|
||||
selectedKeys.add(ski);
|
||||
numKeysUpdated++;
|
||||
}
|
||||
}
|
||||
|
||||
// re-queue key so it re-associated at next select
|
||||
ski.registeredEvents(0);
|
||||
updateKeys.addLast(ski);
|
||||
|
||||
// update selected-key set if no action specified
|
||||
if (action == null) {
|
||||
int rOps = getEventOps(i);
|
||||
numKeysUpdated += processReadyEvents(rOps, ski, null);
|
||||
}
|
||||
|
||||
}
|
||||
} else if (source == PORT_SOURCE_USER) {
|
||||
interrupted = true;
|
||||
|
@ -211,6 +209,22 @@ class EventPortSelectorImpl
|
|||
}
|
||||
}
|
||||
|
||||
// if an action specified then iterate over the polled events again so
|
||||
// that the action is performed without holding the update lock.
|
||||
if (action != null) {
|
||||
for (int i = 0; i < numEvents; i++) {
|
||||
short source = getSource(i);
|
||||
if (source == PORT_SOURCE_FD) {
|
||||
int fd = getDescriptor(i);
|
||||
SelectionKeyImpl ski = fdToKey.get(fd);
|
||||
if (ski != null) {
|
||||
int rOps = getEventOps(i);
|
||||
numKeysUpdated += processReadyEvents(rOps, ski, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (interrupted) {
|
||||
clearInterrupt();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue