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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Read and discard urgent data (MSG_OOB) on the socket.
|
||||
*/
|
||||
static native boolean discardOOB(FileDescriptor fd) throws IOException;
|
||||
|
||||
// -- 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
package sun.nio.ch;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.lang.invoke.ConstantBootstraps;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
@ -74,6 +75,10 @@ public final class SelectionKeyImpl
|
||||
throw new CancelledKeyException();
|
||||
}
|
||||
|
||||
FileDescriptor getFD() {
|
||||
return channel.getFD();
|
||||
}
|
||||
|
||||
int 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,7 +35,7 @@ import java.security.PrivilegedAction;
|
||||
public class DefaultSelectorProvider {
|
||||
private static final SelectorProviderImpl INSTANCE;
|
||||
static {
|
||||
PrivilegedAction<SelectorProviderImpl> pa = WindowsSelectorProvider::new;
|
||||
PrivilegedAction<SelectorProviderImpl> pa = WEPollSelectorProvider::new;
|
||||
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.
|
||||
*
|
||||
* 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();
|
||||
|
||||
// Source and sink channels
|
||||
private final SourceChannel source;
|
||||
private final SinkChannel sink;
|
||||
private final SourceChannelImpl source;
|
||||
private final SinkChannelImpl sink;
|
||||
|
||||
private class Initializer
|
||||
private static class Initializer
|
||||
implements PrivilegedExceptionAction<Void>
|
||||
{
|
||||
|
||||
@ -203,11 +203,11 @@ class PipeImpl
|
||||
this.sink = initializer.sink;
|
||||
}
|
||||
|
||||
public SourceChannel source() {
|
||||
public SourceChannelImpl source() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public SinkChannel sink() {
|
||||
public SinkChannelImpl 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,
|
||||
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;
|
||||
numKeysUpdated += processFDSet(updateCount, action, readFds,
|
||||
Net.POLLIN,
|
||||
@ -392,6 +394,7 @@ class WindowsSelectorImpl extends SelectorImpl {
|
||||
Consumer<SelectionKey> action,
|
||||
int[] fds, int rOps,
|
||||
boolean isExceptFds)
|
||||
throws IOException
|
||||
{
|
||||
int numKeysUpdated = 0;
|
||||
for (int i = 1; i <= fds[0]; i++) {
|
||||
@ -415,7 +418,7 @@ class WindowsSelectorImpl extends SelectorImpl {
|
||||
SelectableChannel sc = ski.channel();
|
||||
if (isExceptFds && (sc instanceof SocketChannelImpl)
|
||||
&& ((SocketChannelImpl) sc).isNetSocket()
|
||||
&& discardUrgentData(desc)) {
|
||||
&& Net.discardOOB(ski.getFD())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -511,8 +514,6 @@ class WindowsSelectorImpl extends SelectorImpl {
|
||||
|
||||
private native void resetWakeupSocket0(int wakeupSourceFd);
|
||||
|
||||
private native boolean discardUrgentData(int fd);
|
||||
|
||||
// We increment this counter on each call to updateSelectedKeys()
|
||||
// each entry in SubSelector.fdsMap has a memorized value of
|
||||
// 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
|
||||
// ready queue.
|
||||
private int updateSelectedKeys(Consumer<SelectionKey> action) {
|
||||
private int updateSelectedKeys(Consumer<SelectionKey> action) throws IOException {
|
||||
updateCount++;
|
||||
int numKeysUpdated = 0;
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
Java_sun_nio_ch_IOUtil_drain(JNIEnv *env, jclass cl, jint fd)
|
||||
{
|
||||
DWORD read = 0;
|
||||
int totalRead = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
char buf[16];
|
||||
jboolean readBytes = JNI_FALSE;
|
||||
for (;;) {
|
||||
result = ReadFile(h, /* File handle to read */
|
||||
(LPVOID)&buf, /* address to put data */
|
||||
128, /* number of bytes to read */
|
||||
&read, /* number of bytes read */
|
||||
NULL); /* no overlapped struct */
|
||||
|
||||
if (result == 0) {
|
||||
int error = GetLastError();
|
||||
if (error == ERROR_NO_DATA) {
|
||||
return (totalRead > 0) ? JNI_TRUE : JNI_FALSE;
|
||||
int n = recv((SOCKET) fd, buf, sizeof(buf), 0);
|
||||
if (n == SOCKET_ERROR) {
|
||||
if (WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "recv failed");
|
||||
}
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Drain");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
if (read > 0) {
|
||||
totalRead += read;
|
||||
} else {
|
||||
break;
|
||||
return readBytes;
|
||||
}
|
||||
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.
|
||||
|
@ -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.
|
||||
*
|
||||
* 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) {
|
||||
FD_SET(fd, &rd);
|
||||
}
|
||||
if (events & POLLOUT ||
|
||||
events & POLLCONN) {
|
||||
if (events & POLLOUT) {
|
||||
FD_SET(fd, &wr);
|
||||
}
|
||||
FD_SET(fd, &ex);
|
||||
@ -768,7 +767,7 @@ Java_sun_nio_ch_Net_pollnvalValue(JNIEnv *env, jclass this)
|
||||
JNIEXPORT jshort JNICALL
|
||||
Java_sun_nio_ch_Net_pollconnValue(JNIEnv *env, jclass this)
|
||||
{
|
||||
return (jshort)POLLCONN;
|
||||
return (jshort)POLLOUT;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
@ -786,3 +785,24 @@ Java_sun_nio_ch_Net_sendOOB(JNIEnv* env, jclass this, jobject fdo, jbyte b)
|
||||
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.
|
||||
*
|
||||
* 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;
|
||||
read_count++;
|
||||
}
|
||||
if (fds[i].events & (POLLOUT | POLLCONN))
|
||||
{
|
||||
if (fds[i].events & POLLOUT) {
|
||||
writefds->fd_array[write_count] = fds[i].fd;
|
||||
write_count++;
|
||||
}
|
||||
@ -190,19 +189,3 @@ Java_sun_nio_ch_WindowsSelectorImpl_resetWakeupSocket0(JNIEnv *env, jclass this,
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -64,22 +64,6 @@ struct iovec {
|
||||
|
||||
#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 */
|
||||
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @requires (os.family == "windows")
|
||||
* @run main/othervm -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider ChangingInterests
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.nio.ByteBuffer;
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,6 +29,11 @@
|
||||
* @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.io.*;
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,11 +23,12 @@
|
||||
|
||||
/* @test
|
||||
* @bug 6213702
|
||||
* @requires (os.family != "mac") | (os.version == "10.10.5")
|
||||
* | (os.simpleVersion != "10.8" & os.simpleVersion != "10.9"
|
||||
* & os.simpleVersion != "10.10")
|
||||
* @summary OOB data causes a SocketChannel, with OOBINLINE disabled, to be
|
||||
* selected
|
||||
* @summary OOB data causes a SocketChannel, with OOBINLINE disabled, to be selected
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @requires (os.family == "windows")
|
||||
* @run main/othervm -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider OutOfBand
|
||||
*/
|
||||
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
* @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 {
|
||||
|
||||
// 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,10 +22,14 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary Unit test for Selector.select/selectNow(Consumer)
|
||||
* @bug 8199433 8208780
|
||||
* @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;
|
||||
|
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.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -29,7 +29,7 @@
|
||||
* 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.Level;
|
Loading…
x
Reference in New Issue
Block a user