From 704986021edb8c00f98c2f2d89b00deea8392852 Mon Sep 17 00:00:00 2001 From: Jasper Siepkes Date: Mon, 11 Mar 2024 17:33:45 +0100 Subject: [PATCH] Implemented missing native methods for Loom support --- .../sun/nio/ch/DefaultPollerProvider.java | 4 +- .../classes/sun/nio/ch/SolarisEventPort.java | 7 +- .../sun/nio/ch/SolarisEventPortPoller.java | 103 ++++++++++++++++++ 3 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 src/java.base/solaris/classes/sun/nio/ch/SolarisEventPortPoller.java diff --git a/src/java.base/solaris/classes/sun/nio/ch/DefaultPollerProvider.java b/src/java.base/solaris/classes/sun/nio/ch/DefaultPollerProvider.java index 1a7d19180046e..f534c2545038f 100644 --- a/src/java.base/solaris/classes/sun/nio/ch/DefaultPollerProvider.java +++ b/src/java.base/solaris/classes/sun/nio/ch/DefaultPollerProvider.java @@ -34,11 +34,11 @@ class DefaultPollerProvider extends PollerProvider { @Override Poller readPoller() throws IOException { - return new DevPollPoller(true); + return new SolarisEventPortPoller(true); } @Override Poller writePoller() throws IOException { - return new DevPollPoller(false); + return new SolarisEventPortPoller(false); } } diff --git a/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java b/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java index af52693be907c..80153eae2a328 100644 --- a/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java +++ b/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java @@ -63,6 +63,10 @@ private static int dependsArch(int value32, int value64) { static final short PORT_SOURCE_USER = 3; static final short PORT_SOURCE_FD = 4; + // events (sys/poll.h) + static final int POLLIN = 0x0001; + static final int POLLOUT = 0x0004; + // file descriptor to event port. private final int port; @@ -246,7 +250,8 @@ static native boolean port_dissociate(int port, int source, long object) static native int port_get(int port, long address) throws IOException; /** - * Retrieves at most {@code max} events from a port. + * Retrieves at most {@code max} events from a port. A time-out of {@code < 0} means + * never time-out. */ static native int port_getn(int port, long address, int max, long timeout) throws IOException; diff --git a/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPortPoller.java b/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPortPoller.java new file mode 100644 index 0000000000000..f7e1440132008 --- /dev/null +++ b/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPortPoller.java @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2008, 2020, 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; + +import static sun.nio.ch.SolarisEventPort.OFFSETOF_OBJECT; +import static sun.nio.ch.SolarisEventPort.POLLIN; +import static sun.nio.ch.SolarisEventPort.POLLOUT; +import static sun.nio.ch.SolarisEventPort.PORT_SOURCE_FD; +import static sun.nio.ch.SolarisEventPort.SIZEOF_PORT_EVENT; + +class SolarisEventPortPoller extends Poller { + + private static final Unsafe unsafe = Unsafe.getUnsafe(); + + private static final int MAX_EVENTS = 512; + + // File descriptor to event port. + private final int epid; + private final int event; + + // the poll array (populated by port_getn) + private final long pollArrayAddress; + private final AllocatedNativeObject pollArray; + + SolarisEventPortPoller(boolean read) throws IOException { + super(read); + this.epid = SolarisEventPort.port_create(); + this.event = (read) ? POLLIN : POLLOUT; + + int allocationSize = MAX_EVENTS * SIZEOF_PORT_EVENT; + this.pollArray = new AllocatedNativeObject(allocationSize, false); + this.pollArrayAddress = pollArray.address(); + } + + @Override + int fdVal() { + return epid; + } + + @Override + void implRegister(int fdVal) throws IOException { + boolean result = SolarisEventPort.port_associate(epid, PORT_SOURCE_FD, fdVal, event); + // 'SolarisEventPort.c' will already throw an IOException if the native 'port_associate' method returns + // an error code which is not 'EBADFD'. + if (!result) { + throw new IOException("Event ports 'port_associate' call failed. Error code: " + result); + } + } + + @Override + void implDeregister(int fdVal) { + try{ + SolarisEventPort.port_dissociate(epid, PORT_SOURCE_FD, fdVal); + } catch (IOException e) { + // Ignore. + } + } + + @Override + int poll(int timeout) throws IOException { + int numEvents = SolarisEventPort.port_getn(epid, pollArrayAddress, MAX_EVENTS, timeout); + if (numEvents < 0) { + throw new IOException("Event ports 'port_getn' call failed. Error code: " + numEvents); + } + + int i = 0; + while (i < numEvents) { + long eventAddress = pollArrayAddress + (SIZEOF_PORT_EVENT * i); + // pe->portev_object is file descriptor + int fdVal = (int)unsafe.getAddress(eventAddress + OFFSETOF_OBJECT); + polled(fdVal); + i++; + } + + return numEvents; + } +}