Skip to content

Commit

Permalink
Implemented missing native methods for Loom support
Browse files Browse the repository at this point in the history
  • Loading branch information
siepkes authored and jperkin committed Jun 5, 2024
1 parent 722de78 commit 7049860
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
103 changes: 103 additions & 0 deletions src/java.base/solaris/classes/sun/nio/ch/SolarisEventPortPoller.java
Original file line number Diff line number Diff line change
@@ -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;
}
}

0 comments on commit 7049860

Please sign in to comment.