8266369: (se) Add wepoll based Selector
Reviewed-by: chegar, michaelm, vtewari, dfuchs, bpb
This commit is contained in:
parent
ff77ca8bd4
commit
be4f25b0c8
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -679,6 +679,10 @@ public class Net {
|
|||||||
*/
|
*/
|
||||||
static native int sendOOB(FileDescriptor fd, byte data) throws IOException;
|
static native int sendOOB(FileDescriptor fd, byte data) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read and discard urgent data (MSG_OOB) on the socket.
|
||||||
|
*/
|
||||||
|
static native boolean discardOOB(FileDescriptor fd) throws IOException;
|
||||||
|
|
||||||
// -- Multicast support --
|
// -- Multicast support --
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package sun.nio.ch;
|
package sun.nio.ch;
|
||||||
|
|
||||||
|
import java.io.FileDescriptor;
|
||||||
import java.lang.invoke.ConstantBootstraps;
|
import java.lang.invoke.ConstantBootstraps;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.VarHandle;
|
import java.lang.invoke.VarHandle;
|
||||||
@ -74,6 +75,10 @@ public final class SelectionKeyImpl
|
|||||||
throw new CancelledKeyException();
|
throw new CancelledKeyException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileDescriptor getFD() {
|
||||||
|
return channel.getFD();
|
||||||
|
}
|
||||||
|
|
||||||
int getFDVal() {
|
int getFDVal() {
|
||||||
return channel.getFDVal();
|
return channel.getFDVal();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -35,7 +35,7 @@ import java.security.PrivilegedAction;
|
|||||||
public class DefaultSelectorProvider {
|
public class DefaultSelectorProvider {
|
||||||
private static final SelectorProviderImpl INSTANCE;
|
private static final SelectorProviderImpl INSTANCE;
|
||||||
static {
|
static {
|
||||||
PrivilegedAction<SelectorProviderImpl> pa = WindowsSelectorProvider::new;
|
PrivilegedAction<SelectorProviderImpl> pa = WEPollSelectorProvider::new;
|
||||||
INSTANCE = AccessController.doPrivileged(pa);
|
INSTANCE = AccessController.doPrivileged(pa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -61,10 +61,10 @@ class PipeImpl
|
|||||||
private static final Random RANDOM_NUMBER_GENERATOR = new SecureRandom();
|
private static final Random RANDOM_NUMBER_GENERATOR = new SecureRandom();
|
||||||
|
|
||||||
// Source and sink channels
|
// Source and sink channels
|
||||||
private final SourceChannel source;
|
private final SourceChannelImpl source;
|
||||||
private final SinkChannel sink;
|
private final SinkChannelImpl sink;
|
||||||
|
|
||||||
private class Initializer
|
private static class Initializer
|
||||||
implements PrivilegedExceptionAction<Void>
|
implements PrivilegedExceptionAction<Void>
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -203,11 +203,11 @@ class PipeImpl
|
|||||||
this.sink = initializer.sink;
|
this.sink = initializer.sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceChannel source() {
|
public SourceChannelImpl source() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SinkChannel sink() {
|
public SinkChannelImpl sink() {
|
||||||
return sink;
|
return sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
146
src/java.base/windows/classes/sun/nio/ch/WEPoll.java
Normal file
146
src/java.base/windows/classes/sun/nio/ch/WEPoll.java
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.nio.ch;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import jdk.internal.misc.Unsafe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to wepoll.
|
||||||
|
*/
|
||||||
|
class WEPoll {
|
||||||
|
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||||
|
private static final int ADDRESS_SIZE = UNSAFE.addressSize();
|
||||||
|
|
||||||
|
private WEPoll() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* typedef union epoll_data {
|
||||||
|
* void *ptr;
|
||||||
|
* int fd;
|
||||||
|
* uint32_t u32;
|
||||||
|
* uint64_t u64;
|
||||||
|
* SOCKET sock; // Windows specific
|
||||||
|
* HANDLE hnd; // Windows specific
|
||||||
|
* } epoll_data_t;
|
||||||
|
*
|
||||||
|
* struct epoll_event {
|
||||||
|
* uint32_t events;
|
||||||
|
* epoll_data_t data;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
private static final int SIZEOF_EPOLLEVENT = eventSize();
|
||||||
|
private static final int OFFSETOF_EVENTS = eventsOffset();
|
||||||
|
private static final int OFFSETOF_SOCK = dataOffset();
|
||||||
|
|
||||||
|
// opcodes
|
||||||
|
static final int EPOLL_CTL_ADD = 1;
|
||||||
|
static final int EPOLL_CTL_MOD = 2;
|
||||||
|
static final int EPOLL_CTL_DEL = 3;
|
||||||
|
|
||||||
|
// events
|
||||||
|
static final int EPOLLIN = (1 << 0);
|
||||||
|
static final int EPOLLPRI = (1 << 1);
|
||||||
|
static final int EPOLLOUT = (1 << 2);
|
||||||
|
static final int EPOLLERR = (1 << 3);
|
||||||
|
static final int EPOLLHUP = (1 << 4);
|
||||||
|
|
||||||
|
// flags
|
||||||
|
static final int EPOLLONESHOT = (1 << 31);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates a poll array to handle up to {@code count} events.
|
||||||
|
*/
|
||||||
|
static long allocatePollArray(int count) {
|
||||||
|
long size = (long) count * SIZEOF_EPOLLEVENT;
|
||||||
|
long base = UNSAFE.allocateMemory(size);
|
||||||
|
UNSAFE.setMemory(base, size, (byte) 0);
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a poll array
|
||||||
|
*/
|
||||||
|
static void freePollArray(long address) {
|
||||||
|
UNSAFE.freeMemory(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns event[i];
|
||||||
|
*/
|
||||||
|
static long getEvent(long address, int i) {
|
||||||
|
return address + (SIZEOF_EPOLLEVENT*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns event->data.socket
|
||||||
|
*/
|
||||||
|
static long getSocket(long eventAddress) {
|
||||||
|
if (ADDRESS_SIZE == 8) {
|
||||||
|
return UNSAFE.getLong(eventAddress + OFFSETOF_SOCK);
|
||||||
|
} else {
|
||||||
|
return UNSAFE.getInt(eventAddress + OFFSETOF_SOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return event->data.socket as an int file descriptor
|
||||||
|
*/
|
||||||
|
static int getDescriptor(long eventAddress) {
|
||||||
|
long s = getSocket(eventAddress);
|
||||||
|
int fd = (int) s;
|
||||||
|
assert ((long) fd) == s;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns event->events
|
||||||
|
*/
|
||||||
|
static int getEvents(long eventAddress) {
|
||||||
|
return UNSAFE.getInt(eventAddress + OFFSETOF_EVENTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Native methods --
|
||||||
|
|
||||||
|
private static native int eventSize();
|
||||||
|
|
||||||
|
private static native int eventsOffset();
|
||||||
|
|
||||||
|
private static native int dataOffset();
|
||||||
|
|
||||||
|
static native long create() throws IOException;
|
||||||
|
|
||||||
|
static native int ctl(long h, int opcode, long s, int events);
|
||||||
|
|
||||||
|
static native int wait(long h, long pollAddress, int numfds, int timeout)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
static native void close(long h);
|
||||||
|
|
||||||
|
static {
|
||||||
|
IOUtil.load();
|
||||||
|
}
|
||||||
|
}
|
276
src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java
Normal file
276
src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.nio.ch;
|
||||||
|
|
||||||
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.ClosedSelectorException;
|
||||||
|
import java.nio.channels.Pipe;
|
||||||
|
import java.nio.channels.SelectionKey;
|
||||||
|
import java.nio.channels.Selector;
|
||||||
|
import java.nio.channels.spi.SelectorProvider;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import static sun.nio.ch.WEPoll.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows wepoll based Selector implementation
|
||||||
|
*/
|
||||||
|
class WEPollSelectorImpl extends SelectorImpl {
|
||||||
|
// maximum number of events to poll in one call to epoll_wait
|
||||||
|
private static final int NUM_EPOLLEVENTS = 256;
|
||||||
|
|
||||||
|
// wepoll handle
|
||||||
|
private final long eph;
|
||||||
|
|
||||||
|
// address of epoll_event array when polling with epoll_wait
|
||||||
|
private final long pollArrayAddress;
|
||||||
|
|
||||||
|
// maps SOCKET to selection key, synchronize on selector
|
||||||
|
private final Map<Integer, SelectionKeyImpl> fdToKey = new HashMap<>();
|
||||||
|
|
||||||
|
// pending new registrations/updates, queued by setEventOps
|
||||||
|
private final Object updateLock = new Object();
|
||||||
|
private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
|
||||||
|
|
||||||
|
// interrupt/wakeup
|
||||||
|
private final Object interruptLock = new Object();
|
||||||
|
private boolean interruptTriggered;
|
||||||
|
private final PipeImpl pipe;
|
||||||
|
private final int fd0Val, fd1Val;
|
||||||
|
|
||||||
|
WEPollSelectorImpl(SelectorProvider sp) throws IOException {
|
||||||
|
super(sp);
|
||||||
|
|
||||||
|
this.eph = WEPoll.create();
|
||||||
|
this.pollArrayAddress = WEPoll.allocatePollArray(NUM_EPOLLEVENTS);
|
||||||
|
|
||||||
|
// wakeup support
|
||||||
|
try {
|
||||||
|
this.pipe = new PipeImpl(sp, /*buffering*/ false);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
WEPoll.freePollArray(pollArrayAddress);
|
||||||
|
WEPoll.close(eph);
|
||||||
|
throw ioe;
|
||||||
|
}
|
||||||
|
this.fd0Val = pipe.source().getFDVal();
|
||||||
|
this.fd1Val = pipe.sink().getFDVal();
|
||||||
|
|
||||||
|
// register one end of the pipe for wakeups
|
||||||
|
WEPoll.ctl(eph, EPOLL_CTL_ADD, fd0Val, WEPoll.EPOLLIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureOpen() {
|
||||||
|
if (!isOpen())
|
||||||
|
throw new ClosedSelectorException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int doSelect(Consumer<SelectionKey> action, long timeout)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
assert Thread.holdsLock(this);
|
||||||
|
|
||||||
|
// epoll_wait timeout is int
|
||||||
|
int to = (int) Math.min(timeout, Integer.MAX_VALUE);
|
||||||
|
boolean blocking = (to != 0);
|
||||||
|
|
||||||
|
int numEntries;
|
||||||
|
processUpdateQueue();
|
||||||
|
processDeregisterQueue();
|
||||||
|
try {
|
||||||
|
begin(blocking);
|
||||||
|
numEntries = WEPoll.wait(eph, pollArrayAddress, NUM_EPOLLEVENTS, to);
|
||||||
|
} finally {
|
||||||
|
end(blocking);
|
||||||
|
}
|
||||||
|
processDeregisterQueue();
|
||||||
|
return processEvents(numEntries, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process changes to the interest ops.
|
||||||
|
*/
|
||||||
|
private void processUpdateQueue() {
|
||||||
|
assert Thread.holdsLock(this);
|
||||||
|
|
||||||
|
synchronized (updateLock) {
|
||||||
|
SelectionKeyImpl ski;
|
||||||
|
while ((ski = updateKeys.pollFirst()) != null) {
|
||||||
|
if (ski.isValid()) {
|
||||||
|
int fd = ski.getFDVal();
|
||||||
|
// add to fdToKey if needed
|
||||||
|
SelectionKeyImpl previous = fdToKey.putIfAbsent(fd, ski);
|
||||||
|
assert (previous == null) || (previous == ski);
|
||||||
|
int newOps = ski.translateInterestOps();
|
||||||
|
int registeredOps = ski.registeredEvents();
|
||||||
|
if (newOps != registeredOps) {
|
||||||
|
if (newOps == 0) {
|
||||||
|
// remove from epoll
|
||||||
|
WEPoll.ctl(eph, EPOLL_CTL_DEL, fd, 0);
|
||||||
|
} else {
|
||||||
|
int events = toEPollEvents(newOps);
|
||||||
|
if (registeredOps == 0) {
|
||||||
|
// add to epoll
|
||||||
|
WEPoll.ctl(eph, EPOLL_CTL_ADD, fd, events);
|
||||||
|
} else {
|
||||||
|
// modify events
|
||||||
|
WEPoll.ctl(eph, EPOLL_CTL_MOD, fd, events);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ski.registeredEvents(newOps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the polled events.
|
||||||
|
* If the interrupt fd has been selected, drain it and clear the interrupt.
|
||||||
|
*/
|
||||||
|
private int processEvents(int numEntries, Consumer<SelectionKey> action)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
assert Thread.holdsLock(this);
|
||||||
|
|
||||||
|
boolean interrupted = false;
|
||||||
|
int numKeysUpdated = 0;
|
||||||
|
for (int i = 0; i < numEntries; i++) {
|
||||||
|
long event = WEPoll.getEvent(pollArrayAddress, i);
|
||||||
|
int fd = WEPoll.getDescriptor(event);
|
||||||
|
if (fd == fd0Val) {
|
||||||
|
interrupted = true;
|
||||||
|
} else {
|
||||||
|
SelectionKeyImpl ski = fdToKey.get(fd);
|
||||||
|
if (ski != null) {
|
||||||
|
int events = WEPoll.getEvents(event);
|
||||||
|
if ((events & WEPoll.EPOLLPRI) != 0) {
|
||||||
|
Net.discardOOB(ski.getFD());
|
||||||
|
}
|
||||||
|
int rOps = toReadyOps(events);
|
||||||
|
numKeysUpdated += processReadyEvents(rOps, ski, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interrupted) {
|
||||||
|
clearInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return numKeysUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void implClose() throws IOException {
|
||||||
|
assert !isOpen() && Thread.holdsLock(this);
|
||||||
|
|
||||||
|
// prevent further wakeup
|
||||||
|
synchronized (interruptLock) {
|
||||||
|
interruptTriggered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// close the epoll port and free resources
|
||||||
|
WEPoll.close(eph);
|
||||||
|
WEPoll.freePollArray(pollArrayAddress);
|
||||||
|
pipe.sink().close();
|
||||||
|
pipe.source().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void implDereg(SelectionKeyImpl ski) throws IOException {
|
||||||
|
assert !ski.isValid() && Thread.holdsLock(this);
|
||||||
|
|
||||||
|
int fd = ski.getFDVal();
|
||||||
|
if (fdToKey.remove(fd) != null) {
|
||||||
|
if (ski.registeredEvents() != 0) {
|
||||||
|
WEPoll.ctl(eph, EPOLL_CTL_DEL, fd, 0);
|
||||||
|
ski.registeredEvents(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert ski.registeredEvents() == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEventOps(SelectionKeyImpl ski) {
|
||||||
|
ensureOpen();
|
||||||
|
synchronized (updateLock) {
|
||||||
|
updateKeys.addLast(ski);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Selector wakeup() {
|
||||||
|
synchronized (interruptLock) {
|
||||||
|
if (!interruptTriggered) {
|
||||||
|
try {
|
||||||
|
IOUtil.write1(fd1Val, (byte) 0);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new InternalError(ioe);
|
||||||
|
}
|
||||||
|
interruptTriggered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearInterrupt() throws IOException {
|
||||||
|
synchronized (interruptLock) {
|
||||||
|
IOUtil.drain(fd0Val);
|
||||||
|
interruptTriggered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps interest ops to epoll events
|
||||||
|
*/
|
||||||
|
private static int toEPollEvents(int ops) {
|
||||||
|
int events = EPOLLPRI;
|
||||||
|
if ((ops & Net.POLLIN) != 0)
|
||||||
|
events |= EPOLLIN;
|
||||||
|
if ((ops & (Net.POLLOUT | Net.POLLCONN)) != 0)
|
||||||
|
events |= EPOLLOUT;
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map epoll events to ready ops
|
||||||
|
*/
|
||||||
|
private static int toReadyOps(int events) {
|
||||||
|
int ops = 0;
|
||||||
|
if ((events & WEPoll.EPOLLIN) != 0) ops |= Net.POLLIN;
|
||||||
|
if ((events & WEPoll.EPOLLOUT) != 0) ops |= (Net.POLLOUT | Net.POLLCONN);
|
||||||
|
if ((events & WEPoll.EPOLLHUP) != 0) ops |= Net.POLLHUP;
|
||||||
|
if ((events & WEPoll.EPOLLERR) != 0) ops |= Net.POLLERR;
|
||||||
|
return ops;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.nio.ch;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.channels.spi.AbstractSelector;
|
||||||
|
|
||||||
|
public class WEPollSelectorProvider extends SelectorProviderImpl {
|
||||||
|
public AbstractSelector openSelector() throws IOException {
|
||||||
|
return new WEPollSelectorImpl(this);
|
||||||
|
}
|
||||||
|
}
|
@ -365,7 +365,9 @@ class WindowsSelectorImpl extends SelectorImpl {
|
|||||||
private native int poll0(long pollAddress, int numfds,
|
private native int poll0(long pollAddress, int numfds,
|
||||||
int[] readFds, int[] writeFds, int[] exceptFds, long timeout, long fdsBuffer);
|
int[] readFds, int[] writeFds, int[] exceptFds, long timeout, long fdsBuffer);
|
||||||
|
|
||||||
private int processSelectedKeys(long updateCount, Consumer<SelectionKey> action) {
|
private int processSelectedKeys(long updateCount, Consumer<SelectionKey> action)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
int numKeysUpdated = 0;
|
int numKeysUpdated = 0;
|
||||||
numKeysUpdated += processFDSet(updateCount, action, readFds,
|
numKeysUpdated += processFDSet(updateCount, action, readFds,
|
||||||
Net.POLLIN,
|
Net.POLLIN,
|
||||||
@ -392,6 +394,7 @@ class WindowsSelectorImpl extends SelectorImpl {
|
|||||||
Consumer<SelectionKey> action,
|
Consumer<SelectionKey> action,
|
||||||
int[] fds, int rOps,
|
int[] fds, int rOps,
|
||||||
boolean isExceptFds)
|
boolean isExceptFds)
|
||||||
|
throws IOException
|
||||||
{
|
{
|
||||||
int numKeysUpdated = 0;
|
int numKeysUpdated = 0;
|
||||||
for (int i = 1; i <= fds[0]; i++) {
|
for (int i = 1; i <= fds[0]; i++) {
|
||||||
@ -415,7 +418,7 @@ class WindowsSelectorImpl extends SelectorImpl {
|
|||||||
SelectableChannel sc = ski.channel();
|
SelectableChannel sc = ski.channel();
|
||||||
if (isExceptFds && (sc instanceof SocketChannelImpl)
|
if (isExceptFds && (sc instanceof SocketChannelImpl)
|
||||||
&& ((SocketChannelImpl) sc).isNetSocket()
|
&& ((SocketChannelImpl) sc).isNetSocket()
|
||||||
&& discardUrgentData(desc)) {
|
&& Net.discardOOB(ski.getFD())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,8 +514,6 @@ class WindowsSelectorImpl extends SelectorImpl {
|
|||||||
|
|
||||||
private native void resetWakeupSocket0(int wakeupSourceFd);
|
private native void resetWakeupSocket0(int wakeupSourceFd);
|
||||||
|
|
||||||
private native boolean discardUrgentData(int fd);
|
|
||||||
|
|
||||||
// We increment this counter on each call to updateSelectedKeys()
|
// We increment this counter on each call to updateSelectedKeys()
|
||||||
// each entry in SubSelector.fdsMap has a memorized value of
|
// each entry in SubSelector.fdsMap has a memorized value of
|
||||||
// updateCount. When we increment numKeysUpdated we set updateCount
|
// updateCount. When we increment numKeysUpdated we set updateCount
|
||||||
@ -523,7 +524,7 @@ class WindowsSelectorImpl extends SelectorImpl {
|
|||||||
|
|
||||||
// Update ops of the corresponding Channels. Add the ready keys to the
|
// Update ops of the corresponding Channels. Add the ready keys to the
|
||||||
// ready queue.
|
// ready queue.
|
||||||
private int updateSelectedKeys(Consumer<SelectionKey> action) {
|
private int updateSelectedKeys(Consumer<SelectionKey> action) throws IOException {
|
||||||
updateCount++;
|
updateCount++;
|
||||||
int numKeysUpdated = 0;
|
int numKeysUpdated = 0;
|
||||||
numKeysUpdated += subSelector.processSelectedKeys(updateCount, action);
|
numKeysUpdated += subSelector.processSelectedKeys(updateCount, action);
|
||||||
|
34
src/java.base/windows/legal/wepoll.md
Normal file
34
src/java.base/windows/legal/wepoll.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
## Bert Belder: wepoll v 1.5.8
|
||||||
|
|
||||||
|
### wepoll License
|
||||||
|
```
|
||||||
|
wepoll - epoll for Windows
|
||||||
|
https://github.com/piscisaureus/wepoll
|
||||||
|
|
||||||
|
Copyright 2012-2020, Bert Belder <bertbelder@gmail.com>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
```
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -148,45 +148,36 @@ Java_sun_nio_ch_IOUtil_configureBlocking(JNIEnv *env, jclass clazz,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: Drain uses the int fd value. It is currently not called
|
|
||||||
on windows.
|
|
||||||
*/
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_sun_nio_ch_IOUtil_drain(JNIEnv *env, jclass cl, jint fd)
|
Java_sun_nio_ch_IOUtil_drain(JNIEnv *env, jclass cl, jint fd)
|
||||||
{
|
{
|
||||||
DWORD read = 0;
|
char buf[16];
|
||||||
int totalRead = 0;
|
jboolean readBytes = JNI_FALSE;
|
||||||
BOOL result = 0;
|
|
||||||
HANDLE h = (HANDLE)_get_osfhandle(fd);
|
|
||||||
char buf[128];
|
|
||||||
|
|
||||||
if (h == INVALID_HANDLE_VALUE) {
|
|
||||||
JNU_ThrowIOExceptionWithLastError(env, "Read failed");
|
|
||||||
return JNI_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
result = ReadFile(h, /* File handle to read */
|
int n = recv((SOCKET) fd, buf, sizeof(buf), 0);
|
||||||
(LPVOID)&buf, /* address to put data */
|
if (n == SOCKET_ERROR) {
|
||||||
128, /* number of bytes to read */
|
if (WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||||
&read, /* number of bytes read */
|
JNU_ThrowIOExceptionWithLastError(env, "recv failed");
|
||||||
NULL); /* no overlapped struct */
|
|
||||||
|
|
||||||
if (result == 0) {
|
|
||||||
int error = GetLastError();
|
|
||||||
if (error == ERROR_NO_DATA) {
|
|
||||||
return (totalRead > 0) ? JNI_TRUE : JNI_FALSE;
|
|
||||||
}
|
}
|
||||||
JNU_ThrowIOExceptionWithLastError(env, "Drain");
|
return readBytes;
|
||||||
return JNI_FALSE;
|
|
||||||
}
|
|
||||||
if (read > 0) {
|
|
||||||
totalRead += read;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (n <= 0)
|
||||||
|
return readBytes;
|
||||||
|
if (n < (int)sizeof(buf))
|
||||||
|
return JNI_TRUE;
|
||||||
|
readBytes = JNI_TRUE;
|
||||||
}
|
}
|
||||||
return (totalRead > 0) ? JNI_TRUE : JNI_FALSE;
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_sun_nio_ch_IOUtil_write1(JNIEnv *env, jclass cl, jint fd, jbyte b)
|
||||||
|
{
|
||||||
|
int n = send((SOCKET) fd, &b, 1, 0);
|
||||||
|
if (n == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||||
|
JNU_ThrowIOExceptionWithLastError(env, "send failed");
|
||||||
|
return IOS_THROWN;
|
||||||
|
}
|
||||||
|
return (n == 1) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: This function returns the int fd value from file descriptor.
|
/* Note: This function returns the int fd value from file descriptor.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -654,8 +654,7 @@ Java_sun_nio_ch_Net_poll(JNIEnv* env, jclass this, jobject fdo, jint events, jlo
|
|||||||
if (events & POLLIN) {
|
if (events & POLLIN) {
|
||||||
FD_SET(fd, &rd);
|
FD_SET(fd, &rd);
|
||||||
}
|
}
|
||||||
if (events & POLLOUT ||
|
if (events & POLLOUT) {
|
||||||
events & POLLCONN) {
|
|
||||||
FD_SET(fd, &wr);
|
FD_SET(fd, &wr);
|
||||||
}
|
}
|
||||||
FD_SET(fd, &ex);
|
FD_SET(fd, &ex);
|
||||||
@ -768,7 +767,7 @@ Java_sun_nio_ch_Net_pollnvalValue(JNIEnv *env, jclass this)
|
|||||||
JNIEXPORT jshort JNICALL
|
JNIEXPORT jshort JNICALL
|
||||||
Java_sun_nio_ch_Net_pollconnValue(JNIEnv *env, jclass this)
|
Java_sun_nio_ch_Net_pollconnValue(JNIEnv *env, jclass this)
|
||||||
{
|
{
|
||||||
return (jshort)POLLCONN;
|
return (jshort)POLLOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
@ -786,3 +785,24 @@ Java_sun_nio_ch_Net_sendOOB(JNIEnv* env, jclass this, jobject fdo, jbyte b)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_sun_nio_ch_Net_discardOOB(JNIEnv* env, jclass clazz, jobject fdo)
|
||||||
|
{
|
||||||
|
char buf[8];
|
||||||
|
jboolean discarded = JNI_FALSE;
|
||||||
|
for (;;) {
|
||||||
|
int n = recv(fdval(env, fdo), (char*)&buf, sizeof(buf), MSG_OOB);
|
||||||
|
if (n == SOCKET_ERROR) {
|
||||||
|
if (WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||||
|
JNU_ThrowIOExceptionWithLastError(env, "recv failed");
|
||||||
|
}
|
||||||
|
return discarded;
|
||||||
|
}
|
||||||
|
if (n <= 0)
|
||||||
|
return discarded;
|
||||||
|
if (n < (int)sizeof(buf))
|
||||||
|
return JNI_TRUE;
|
||||||
|
discarded = JNI_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
93
src/java.base/windows/native/libnio/ch/WEPollNatives.c
Normal file
93
src/java.base/windows/native/libnio/ch/WEPollNatives.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "jni.h"
|
||||||
|
#include "jni_util.h"
|
||||||
|
#include "jvm.h"
|
||||||
|
#include "jlong.h"
|
||||||
|
#include "nio.h"
|
||||||
|
#include "nio_util.h"
|
||||||
|
#include "wepoll.h"
|
||||||
|
#include "sun_nio_ch_WEPoll.h"
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_sun_nio_ch_WEPoll_eventSize(JNIEnv* env, jclass clazz)
|
||||||
|
{
|
||||||
|
return sizeof(struct epoll_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_sun_nio_ch_WEPoll_eventsOffset(JNIEnv* env, jclass clazz)
|
||||||
|
{
|
||||||
|
return offsetof(struct epoll_event, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_sun_nio_ch_WEPoll_dataOffset(JNIEnv* env, jclass clazz)
|
||||||
|
{
|
||||||
|
return offsetof(struct epoll_event, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL
|
||||||
|
Java_sun_nio_ch_WEPoll_create(JNIEnv *env, jclass clazz) {
|
||||||
|
HANDLE h = epoll_create1(0);
|
||||||
|
if (h == NULL) {
|
||||||
|
JNU_ThrowIOExceptionWithLastError(env, "epoll_create1 failed");
|
||||||
|
}
|
||||||
|
return ptr_to_jlong(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_sun_nio_ch_WEPoll_ctl(JNIEnv *env, jclass clazz, jlong h,
|
||||||
|
jint opcode, jlong s, jint events)
|
||||||
|
{
|
||||||
|
struct epoll_event event;
|
||||||
|
int res;
|
||||||
|
SOCKET socket = (SOCKET) jlong_to_ptr(s);
|
||||||
|
|
||||||
|
event.events = (uint32_t) events;
|
||||||
|
event.data.sock = socket;
|
||||||
|
|
||||||
|
res = epoll_ctl(jlong_to_ptr(h), opcode, socket, &event);
|
||||||
|
return (res == 0) ? 0 : errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_sun_nio_ch_WEPoll_wait(JNIEnv *env, jclass clazz, jlong h,
|
||||||
|
jlong address, jint numfds, jint timeout)
|
||||||
|
{
|
||||||
|
struct epoll_event *events = jlong_to_ptr(address);
|
||||||
|
int res = epoll_wait(jlong_to_ptr(h), events, numfds, timeout);
|
||||||
|
if (res < 0) {
|
||||||
|
JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed");
|
||||||
|
return IOS_THROWN;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_sun_nio_ch_WEPoll_close(JNIEnv *env, jclass clazz, jlong h) {
|
||||||
|
epoll_close(jlong_to_ptr(h));
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -99,8 +99,7 @@ Java_sun_nio_ch_WindowsSelectorImpl_00024SubSelector_poll0(JNIEnv *env, jobject
|
|||||||
readfds->fd_array[read_count] = fds[i].fd;
|
readfds->fd_array[read_count] = fds[i].fd;
|
||||||
read_count++;
|
read_count++;
|
||||||
}
|
}
|
||||||
if (fds[i].events & (POLLOUT | POLLCONN))
|
if (fds[i].events & POLLOUT) {
|
||||||
{
|
|
||||||
writefds->fd_array[write_count] = fds[i].fd;
|
writefds->fd_array[write_count] = fds[i].fd;
|
||||||
write_count++;
|
write_count++;
|
||||||
}
|
}
|
||||||
@ -190,19 +189,3 @@ Java_sun_nio_ch_WindowsSelectorImpl_resetWakeupSocket0(JNIEnv *env, jclass this,
|
|||||||
recv(scinFd, bytes, WAKEUP_SOCKET_BUF_SIZE, 0);
|
recv(scinFd, bytes, WAKEUP_SOCKET_BUF_SIZE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
|
||||||
Java_sun_nio_ch_WindowsSelectorImpl_discardUrgentData(JNIEnv* env, jobject this,
|
|
||||||
jint s)
|
|
||||||
{
|
|
||||||
char data[8];
|
|
||||||
jboolean discarded = JNI_FALSE;
|
|
||||||
int n;
|
|
||||||
do {
|
|
||||||
n = recv(s, (char*)&data, sizeof(data), MSG_OOB);
|
|
||||||
if (n > 0) {
|
|
||||||
discarded = JNI_TRUE;
|
|
||||||
}
|
|
||||||
} while (n > 0);
|
|
||||||
return discarded;
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -64,22 +64,6 @@ struct iovec {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef POLLIN
|
|
||||||
/* WSAPoll()/WSAPOLLFD and the corresponding constants are only defined */
|
|
||||||
/* in Windows Vista / Windows Server 2008 and later. If we are on an */
|
|
||||||
/* older release we just use the Solaris constants as this was previously */
|
|
||||||
/* done in PollArrayWrapper.java. */
|
|
||||||
#define POLLIN 0x0001
|
|
||||||
#define POLLOUT 0x0004
|
|
||||||
#define POLLERR 0x0008
|
|
||||||
#define POLLHUP 0x0010
|
|
||||||
#define POLLNVAL 0x0020
|
|
||||||
#define POLLCONN 0x0002
|
|
||||||
#else
|
|
||||||
/* POLLCONN must not equal any of the other constants (see winsock2.h). */
|
|
||||||
#define POLLCONN 0x2000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Defined in UnixDomainSockets.c */
|
/* Defined in UnixDomainSockets.c */
|
||||||
|
|
||||||
jbyteArray sockaddrToUnixAddressBytes(JNIEnv *env, struct sockaddr_un *sa, socklen_t len);
|
jbyteArray sockaddrToUnixAddressBytes(JNIEnv *env, struct sockaddr_un *sa, socklen_t len);
|
||||||
|
2283
src/java.base/windows/native/libnio/ch/wepoll.c
Normal file
2283
src/java.base/windows/native/libnio/ch/wepoll.c
Normal file
File diff suppressed because it is too large
Load Diff
143
src/java.base/windows/native/libnio/ch/wepoll.h
Normal file
143
src/java.base/windows/native/libnio/ch/wepoll.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is available under and governed by the GNU General Public
|
||||||
|
* License version 2 only, as published by the Free Software Foundation.
|
||||||
|
* However, the following notice accompanied the original version of this
|
||||||
|
* file and, per its terms, should not be removed:
|
||||||
|
*
|
||||||
|
* wepoll - epoll for Windows
|
||||||
|
* https://github.com/piscisaureus/wepoll
|
||||||
|
*
|
||||||
|
* Copyright 2012-2020, Bert Belder <bertbelder@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEPOLL_H_
|
||||||
|
#define WEPOLL_H_
|
||||||
|
|
||||||
|
#ifndef WEPOLL_EXPORT
|
||||||
|
#define WEPOLL_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum EPOLL_EVENTS {
|
||||||
|
EPOLLIN = (int) (1U << 0),
|
||||||
|
EPOLLPRI = (int) (1U << 1),
|
||||||
|
EPOLLOUT = (int) (1U << 2),
|
||||||
|
EPOLLERR = (int) (1U << 3),
|
||||||
|
EPOLLHUP = (int) (1U << 4),
|
||||||
|
EPOLLRDNORM = (int) (1U << 6),
|
||||||
|
EPOLLRDBAND = (int) (1U << 7),
|
||||||
|
EPOLLWRNORM = (int) (1U << 8),
|
||||||
|
EPOLLWRBAND = (int) (1U << 9),
|
||||||
|
EPOLLMSG = (int) (1U << 10), /* Never reported. */
|
||||||
|
EPOLLRDHUP = (int) (1U << 13),
|
||||||
|
EPOLLONESHOT = (int) (1U << 31)
|
||||||
|
};
|
||||||
|
|
||||||
|
#define EPOLLIN (1U << 0)
|
||||||
|
#define EPOLLPRI (1U << 1)
|
||||||
|
#define EPOLLOUT (1U << 2)
|
||||||
|
#define EPOLLERR (1U << 3)
|
||||||
|
#define EPOLLHUP (1U << 4)
|
||||||
|
#define EPOLLRDNORM (1U << 6)
|
||||||
|
#define EPOLLRDBAND (1U << 7)
|
||||||
|
#define EPOLLWRNORM (1U << 8)
|
||||||
|
#define EPOLLWRBAND (1U << 9)
|
||||||
|
#define EPOLLMSG (1U << 10)
|
||||||
|
#define EPOLLRDHUP (1U << 13)
|
||||||
|
#define EPOLLONESHOT (1U << 31)
|
||||||
|
|
||||||
|
#define EPOLL_CTL_ADD 1
|
||||||
|
#define EPOLL_CTL_MOD 2
|
||||||
|
#define EPOLL_CTL_DEL 3
|
||||||
|
|
||||||
|
typedef void* HANDLE;
|
||||||
|
typedef uintptr_t SOCKET;
|
||||||
|
|
||||||
|
typedef union epoll_data {
|
||||||
|
void* ptr;
|
||||||
|
int fd;
|
||||||
|
uint32_t u32;
|
||||||
|
uint64_t u64;
|
||||||
|
SOCKET sock; /* Windows specific */
|
||||||
|
HANDLE hnd; /* Windows specific */
|
||||||
|
} epoll_data_t;
|
||||||
|
|
||||||
|
struct epoll_event {
|
||||||
|
uint32_t events; /* Epoll events and flags */
|
||||||
|
epoll_data_t data; /* User data variable */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WEPOLL_EXPORT HANDLE epoll_create(int size);
|
||||||
|
WEPOLL_EXPORT HANDLE epoll_create1(int flags);
|
||||||
|
|
||||||
|
WEPOLL_EXPORT int epoll_close(HANDLE ephnd);
|
||||||
|
|
||||||
|
WEPOLL_EXPORT int epoll_ctl(HANDLE ephnd,
|
||||||
|
int op,
|
||||||
|
SOCKET sock,
|
||||||
|
struct epoll_event* event);
|
||||||
|
|
||||||
|
WEPOLL_EXPORT int epoll_wait(HANDLE ephnd,
|
||||||
|
struct epoll_event* events,
|
||||||
|
int maxevents,
|
||||||
|
int timeout);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* WEPOLL_H_ */
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,6 +27,11 @@
|
|||||||
* @summary Test that Selector doesn't spin when changing interest ops
|
* @summary Test that Selector doesn't spin when changing interest ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* @test
|
||||||
|
* @requires (os.family == "windows")
|
||||||
|
* @run main/othervm -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider ChangingInterests
|
||||||
|
*/
|
||||||
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.*;
|
import java.nio.channels.*;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -29,6 +29,11 @@
|
|||||||
* @author kladko
|
* @author kladko
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* @test
|
||||||
|
* @requires (os.family == "windows")
|
||||||
|
* @run main/othervm -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider LotsOfChannels
|
||||||
|
*/
|
||||||
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.*;
|
import java.nio.*;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,11 +23,12 @@
|
|||||||
|
|
||||||
/* @test
|
/* @test
|
||||||
* @bug 6213702
|
* @bug 6213702
|
||||||
* @requires (os.family != "mac") | (os.version == "10.10.5")
|
* @summary OOB data causes a SocketChannel, with OOBINLINE disabled, to be selected
|
||||||
* | (os.simpleVersion != "10.8" & os.simpleVersion != "10.9"
|
*/
|
||||||
* & os.simpleVersion != "10.10")
|
|
||||||
* @summary OOB data causes a SocketChannel, with OOBINLINE disabled, to be
|
/* @test
|
||||||
* selected
|
* @requires (os.family == "windows")
|
||||||
|
* @run main/othervm -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider OutOfBand
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -39,6 +39,12 @@ import java.nio.channels.SocketChannel;
|
|||||||
* @author Frank Ding
|
* @author Frank Ding
|
||||||
* @run main/timeout=1200 RacyDeregister
|
* @run main/timeout=1200 RacyDeregister
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* @test
|
||||||
|
* @requires (os.family == "windows")
|
||||||
|
* @run main/othervm/timeout=1200 -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider RacyDeregister
|
||||||
|
*/
|
||||||
|
|
||||||
public class RacyDeregister {
|
public class RacyDeregister {
|
||||||
|
|
||||||
// 90% of 1200 second timeout as milliseconds
|
// 90% of 1200 second timeout as milliseconds
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,10 +22,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* @test
|
/* @test
|
||||||
|
* @summary Unit test for Selector.select/selectNow(Consumer)
|
||||||
* @bug 8199433 8208780
|
* @bug 8199433 8208780
|
||||||
* @run testng SelectWithConsumer
|
* @run testng SelectWithConsumer
|
||||||
* @summary Unit test for Selector select(Consumer), select(Consumer,long) and
|
*/
|
||||||
* selectNow(Consumer)
|
|
||||||
|
/* @test
|
||||||
|
* @requires (os.family == "windows")
|
||||||
|
* @run testng/othervm -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider SelectWithConsumer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
|
113
test/micro/org/openjdk/bench/java/nio/channels/SelectOne.java
Normal file
113
test/micro/org/openjdk/bench/java/nio/channels/SelectOne.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.openjdk.bench.java.nio.channels;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
import org.openjdk.jmh.annotations.Param;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.TearDown;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.Selector;
|
||||||
|
import java.nio.channels.SelectionKey;
|
||||||
|
import java.nio.channels.ServerSocketChannel;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark for Selector.select(Consumer) when there is one channel ready.
|
||||||
|
*/
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
public class SelectOne {
|
||||||
|
private Selector sel;
|
||||||
|
private List<SocketChannel> clients;
|
||||||
|
private List<SocketChannel> peers;
|
||||||
|
|
||||||
|
private final int nready = 1; // one channel ready for reading
|
||||||
|
|
||||||
|
@Param({"1", "10", "100", "1000", "10000"})
|
||||||
|
private int nchannels; // number of registered channels
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() throws IOException {
|
||||||
|
sel = Selector.open();
|
||||||
|
clients = new ArrayList<SocketChannel>();
|
||||||
|
peers = new ArrayList<SocketChannel>();
|
||||||
|
|
||||||
|
try (ServerSocketChannel listener = ServerSocketChannel.open()) {
|
||||||
|
InetAddress loopback = InetAddress.getLoopbackAddress();
|
||||||
|
listener.bind(new InetSocketAddress(loopback, 0));
|
||||||
|
|
||||||
|
SocketAddress remote = listener.getLocalAddress();
|
||||||
|
for (int i = 0; i < nchannels; i++) {
|
||||||
|
SocketChannel sc = SocketChannel.open(remote);
|
||||||
|
sc.configureBlocking(false);
|
||||||
|
sc.register(sel, SelectionKey.OP_READ);
|
||||||
|
clients.add(sc);
|
||||||
|
|
||||||
|
SocketChannel peer = listener.accept();
|
||||||
|
peers.add(peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = nready - 1; i >= 0; i--) {
|
||||||
|
SocketChannel peer = peers.get(i);
|
||||||
|
peer.write(ByteBuffer.allocate(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TearDown
|
||||||
|
public void teardown() throws IOException {
|
||||||
|
for (SocketChannel sc: clients) {
|
||||||
|
sc.close();
|
||||||
|
}
|
||||||
|
for (SocketChannel sc: peers) {
|
||||||
|
sc.close();
|
||||||
|
}
|
||||||
|
if (sel != null) {
|
||||||
|
sel.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testSelectOne() throws IOException {
|
||||||
|
int nselected = sel.select(k -> { });
|
||||||
|
if (nselected != 1) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Oracle America, Inc.
|
* Copyright (c) 2021, Oracle America, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -29,7 +29,7 @@
|
|||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.openjdk.bench.java.nio;
|
package org.openjdk.bench.java.nio.channels;
|
||||||
|
|
||||||
import org.openjdk.jmh.annotations.Benchmark;
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
import org.openjdk.jmh.annotations.Level;
|
import org.openjdk.jmh.annotations.Level;
|
Loading…
x
Reference in New Issue
Block a user