Skip to content

Commit be72c50

Browse files
committed
Linux: use epoll instead of poll
1 parent 2978e08 commit be72c50

File tree

14 files changed

+346
-422
lines changed

14 files changed

+346
-422
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
typedef unsigned int uint32_t;
2+
typedef unsigned long int uint64_t;
3+
#include <sys/epoll.h>

java-does-usb/jextract/linux/gen_linux.sh

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ $JEXTRACT --source --output ../../src/main/java \
1010
--include-constant EAGAIN \
1111
--include-constant EINVAL \
1212
--include-constant ENODEV \
13+
--include-constant EINTR \
14+
--include-constant ENOENT \
1315
/usr/include/errno.h
1416

1517
# string.h
@@ -45,16 +47,6 @@ $JEXTRACT --source --output ../../src/main/java \
4547
--include-struct usbdevfs_urb \
4648
--include-struct usbdevfs_disconnect_claim \
4749
--include-struct usbdevfs_ioctl \
48-
--include-constant USBDEVFS_CONTROL \
49-
--include-constant USBDEVFS_BULK \
50-
--include-constant USBDEVFS_CLAIMINTERFACE \
51-
--include-constant USBDEVFS_RELEASEINTERFACE \
52-
--include-constant USBDEVFS_SETINTERFACE \
53-
--include-constant USBDEVFS_CLEAR_HALT \
54-
--include-constant USBDEVFS_SUBMITURB \
55-
--include-constant USBDEVFS_DISCARDURB \
56-
--include-constant USBDEVFS_REAPURB \
57-
--include-constant USBDEVFS_DISCONNECT_CLAIM \
5850
--include-constant USBDEVFS_URB_TYPE_INTERRUPT \
5951
--include-constant USBDEVFS_URB_TYPE_CONTROL \
6052
--include-constant USBDEVFS_URB_TYPE_BULK \
@@ -89,14 +81,14 @@ $JEXTRACT --source --output ../../src/main/java \
8981
--include-function udev_monitor_get_fd \
9082
/usr/include/libudev.h
9183

92-
# poll.h
84+
# epoll.h
9385
$JEXTRACT --source --output ../../src/main/java \
94-
--header-class-name poll \
95-
--target-package net.codecrete.usb.linux.gen.poll \
96-
--include-function poll \
97-
--include-struct pollfd \
98-
--include-constant POLLIN \
99-
--include-constant POLLOUT \
100-
--include-constant POLLERR \
101-
/usr/include/poll.h
86+
--header-class-name epoll \
87+
--target-package net.codecrete.usb.linux.gen.epoll \
88+
--include-struct epoll_event \
89+
--include-constant EPOLL_CTL_ADD \
90+
--include-constant EPOLL_CTL_DEL \
91+
--include-constant EPOLLIN \
92+
--include-constant EPOLLOUT \
93+
epoll.h
10294

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//
2+
// Java Does USB
3+
// Copyright (c) 2022 Manuel Bleichenbacher
4+
// Licensed under MIT License
5+
// https://opensource.org/licenses/MIT
6+
//
7+
8+
package net.codecrete.usb.linux;
9+
10+
import net.codecrete.usb.linux.gen.epoll.epoll_event;
11+
import net.codecrete.usb.linux.gen.errno.errno;
12+
13+
import java.lang.foreign.*;
14+
import java.lang.invoke.MethodHandle;
15+
import java.lang.invoke.VarHandle;
16+
17+
import static java.lang.foreign.ValueLayout.ADDRESS;
18+
import static java.lang.foreign.ValueLayout.JAVA_INT;
19+
import static net.codecrete.usb.linux.Linux.allocateErrorState;
20+
import static net.codecrete.usb.linux.LinuxUsbException.throwLastError;
21+
import static net.codecrete.usb.linux.gen.epoll.epoll.*;
22+
23+
@SuppressWarnings({"OptionalGetWithoutIsPresent", "SameParameterValue", "java:S100"})
24+
public class EPoll {
25+
private EPoll() {}
26+
27+
private static final Linker linker = Linker.nativeLinker();
28+
29+
private static final FunctionDescriptor epoll_create$FUNC = FunctionDescriptor.of(JAVA_INT, JAVA_INT);
30+
private static final MethodHandle epoll_create$MH = linker.downcallHandle(linker.defaultLookup().find(
31+
"epoll_create").get(), epoll_create$FUNC, Linux.ERRNO_STATE);
32+
33+
private static final FunctionDescriptor epoll_ctl$FUNC = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
34+
private static final MethodHandle epoll_ctl$MH = linker.downcallHandle(linker.defaultLookup().find(
35+
"epoll_ctl").get(), epoll_ctl$FUNC, Linux.ERRNO_STATE);
36+
37+
private static final FunctionDescriptor epoll_wait$FUNC = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT);
38+
private static final MethodHandle epoll_wait$MH = linker.downcallHandle(linker.defaultLookup().find(
39+
"epoll_wait").get(), epoll_wait$FUNC, Linux.ERRNO_STATE);
40+
41+
private static final VarHandle epoll_event_data_fd$VH = epoll_event.$LAYOUT().varHandle(
42+
MemoryLayout.PathElement.groupElement("data"),
43+
MemoryLayout.PathElement.groupElement("fd")
44+
);
45+
46+
static int epoll_create(int size, MemorySegment errno) {
47+
try {
48+
return (int) epoll_create$MH.invokeExact(errno, size);
49+
} catch (Throwable ex) {
50+
throw new AssertionError(ex);
51+
}
52+
}
53+
54+
private static int epoll_ctl(int epfd, int op, int fd, MemorySegment event, MemorySegment errno) {
55+
try {
56+
return (int) epoll_ctl$MH.invokeExact(errno, epfd, op, fd, event);
57+
} catch (Throwable ex) {
58+
throw new AssertionError(ex);
59+
}
60+
}
61+
62+
static int epoll_wait(int epfd, MemorySegment events, int maxevent, int timeout, MemorySegment errno) {
63+
try {
64+
return (int) epoll_wait$MH.invokeExact(errno, epfd, events, maxevent, timeout);
65+
} catch (Throwable ex) {
66+
throw new AssertionError(ex);
67+
}
68+
}
69+
70+
static void addFileDescriptor(int epfd, int op, int fd) {
71+
try (var arena = Arena.ofConfined()) {
72+
var errorState = allocateErrorState(arena);
73+
74+
var event = arena.allocate(epoll_event.$LAYOUT());
75+
epoll_event.events$set(event, op);
76+
epoll_event_data_fd$VH.set(event, fd);
77+
var ret = epoll_ctl(epfd, EPOLL_CTL_ADD(), fd, event, errorState);
78+
if (ret < 0)
79+
throwLastError(errorState, "internal error (epoll_ctl_add)");
80+
}
81+
}
82+
83+
static void removeFileDescriptor(int epfd, int fd) {
84+
try (var arena = Arena.ofConfined()) {
85+
var errorState = allocateErrorState(arena);
86+
87+
var event = arena.allocate(epoll_event.$LAYOUT());
88+
epoll_event.events$set(event, 0);
89+
epoll_event_data_fd$VH.set(event, fd);
90+
var ret = epoll_ctl(epfd, EPOLL_CTL_DEL(), fd, event, errorState);
91+
if (ret < 0) {
92+
var err = Linux.getErrno(errorState);
93+
if (err != errno.ENOENT())
94+
throwLastError(errorState, "internal error (epoll_ctl_del)");
95+
}
96+
}
97+
}
98+
}

java-does-usb/src/main/java/net/codecrete/usb/linux/IO.java

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,6 @@ private IO() {
2727
private static final FunctionDescriptor open$FUNC = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT);
2828
private static final MethodHandle open$MH = linker.downcallHandle(linker.defaultLookup().find("open").get(),
2929
open$FUNC, Linux.ERRNO_STATE);
30-
private static final FunctionDescriptor eventfd$FUNC = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
31-
private static final MethodHandle eventfd$MH = linker.downcallHandle(linker.defaultLookup().find("eventfd").get()
32-
, eventfd$FUNC, Linux.ERRNO_STATE);
33-
private static final FunctionDescriptor eventfd_read$FUNC = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
34-
private static final MethodHandle eventfd_read$MH = linker.downcallHandle(linker.defaultLookup().find(
35-
"eventfd_read").get(), eventfd_read$FUNC, Linux.ERRNO_STATE);
36-
private static final FunctionDescriptor eventfd_write$FUNC = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_LONG);
37-
private static final MethodHandle eventfd_write$MH = linker.downcallHandle(linker.defaultLookup().find(
38-
"eventfd_write").get(), eventfd_write$FUNC, Linux.ERRNO_STATE);
3930

4031
static int ioctl(int fd, long request, MemorySegment segment, MemorySegment errno) {
4132
try {
@@ -52,29 +43,4 @@ static int open(MemorySegment file, int oflag, MemorySegment errno) {
5243
throw new AssertionError(ex);
5344
}
5445
}
55-
56-
static int eventfd(int count, int flags, MemorySegment errno) {
57-
try {
58-
return (int) eventfd$MH.invokeExact(errno, count, flags);
59-
} catch (Throwable ex) {
60-
throw new AssertionError(ex);
61-
}
62-
}
63-
64-
static int eventfd_read(int fd, MemorySegment value, MemorySegment errno) {
65-
try {
66-
return (int) eventfd_read$MH.invokeExact(errno, fd, value);
67-
} catch (Throwable ex) {
68-
throw new AssertionError(ex);
69-
}
70-
}
71-
72-
static int eventfd_write(int fd, long value, MemorySegment errno) {
73-
try {
74-
return (int) eventfd_write$MH.invokeExact(errno, fd, value);
75-
} catch (Throwable ex) {
76-
throw new AssertionError(ex);
77-
}
78-
}
79-
8046
}

0 commit comments

Comments
 (0)