77
88package net .codecrete .usb .linux ;
99
10- import net .codecrete .usb .linux .gen .epoll .epoll_event ;
1110import net .codecrete .usb .linux .gen .errno .errno ;
1211
1312import java .lang .foreign .Arena ;
1413import java .lang .foreign .FunctionDescriptor ;
14+ import java .lang .foreign .GroupLayout ;
1515import java .lang .foreign .Linker ;
1616import java .lang .foreign .MemoryLayout ;
1717import java .lang .foreign .MemorySegment ;
1818import java .lang .foreign .SequenceLayout ;
19+ import java .lang .foreign .MemoryLayout .PathElement ;
20+ import java .lang .foreign .ValueLayout .OfInt ;
1921import java .lang .invoke .MethodHandle ;
2022import java .lang .invoke .VarHandle ;
2123
2224import static java .lang .foreign .ValueLayout .ADDRESS ;
25+ import static java .lang .foreign .ValueLayout .ADDRESS_UNALIGNED ;
2326import static java .lang .foreign .ValueLayout .JAVA_INT ;
27+ import static java .lang .foreign .ValueLayout .JAVA_INT_UNALIGNED ;
28+ import static java .lang .foreign .ValueLayout .JAVA_LONG_UNALIGNED ;
2429import static net .codecrete .usb .linux .Linux .allocateErrorState ;
2530import static net .codecrete .usb .linux .LinuxUsbException .throwLastError ;
2631import static net .codecrete .usb .linux .gen .epoll .epoll .EPOLL_CTL_ADD ;
2732import static net .codecrete .usb .linux .gen .epoll .epoll .EPOLL_CTL_DEL ;
2833
2934@ SuppressWarnings ({"OptionalGetWithoutIsPresent" , "SameParameterValue" , "java:S100" })
3035public class EPoll {
36+ private EPoll () {}
37+
38+ private static final boolean IS_AARCH64 = System .getProperty ("os.arch" ).equals ("aarch64" );
39+
40+ private static final GroupLayout DATA$LAYOUT = MemoryLayout .unionLayout (
41+ ADDRESS_UNALIGNED .withName ("ptr" ),
42+ JAVA_INT_UNALIGNED .withName ("fd" ),
43+ JAVA_INT_UNALIGNED .withName ("u32" ),
44+ JAVA_LONG_UNALIGNED .withName ("u64" )
45+ ).withName ("epoll_data" );
46+
47+ static final GroupLayout EVENT$LAYOUT = IS_AARCH64
48+ ? MemoryLayout .structLayout (
49+ JAVA_INT .withName ("events" ),
50+ MemoryLayout .paddingLayout (4 ),
51+ DATA$LAYOUT .withName ("data" )).withName ("epoll_event" )
52+ : MemoryLayout .structLayout (
53+ JAVA_INT_UNALIGNED .withName ("events" ),
54+ DATA$LAYOUT .withName ("data" )).withName ("epoll_event" );
55+
3156 // Memory layout for an array of epoll_event structs
32- private static final SequenceLayout EVENT_ARRAY$LAYOUT = MemoryLayout .sequenceLayout (1 , epoll_event . layout () );
57+ private static final SequenceLayout EVENT_ARRAY$LAYOUT = MemoryLayout .sequenceLayout (1 , EVENT$LAYOUT );
3358
3459 // varhandle to access the "fd" field in an array of epoll_event structs
3560 static final VarHandle EVENT_ARRAY_DATA_FD$VH = EVENT_ARRAY$LAYOUT .varHandle (
@@ -39,13 +64,16 @@ public class EPoll {
3964 );
4065
4166 // varhandle to access the "fd" field in an epoll_event struct
42- static final VarHandle EVENT_DATA_FD$VH = epoll_event . layout () .varHandle (
67+ static final VarHandle EVENT_DATA_FD$VH = EVENT$LAYOUT .varHandle (
4368 MemoryLayout .PathElement .groupElement ("data" ),
4469 MemoryLayout .PathElement .groupElement ("fd" )
4570 );
4671
72+ private static final OfInt EVENT_EVENTS$LAYOUT = (OfInt )EVENT$LAYOUT .select (PathElement .groupElement ("events" ));
4773
48- private EPoll () {}
74+ private static void event_events (MemorySegment struct , int fieldValue ) {
75+ struct .set (EVENT_EVENTS$LAYOUT , 0 , fieldValue );
76+ }
4977
5078 private static final Linker linker = Linker .nativeLinker ();
5179
@@ -89,8 +117,8 @@ static void addFileDescriptor(int epfd, int op, int fd) {
89117 try (var arena = Arena .ofConfined ()) {
90118 var errorState = allocateErrorState (arena );
91119
92- var event = arena .allocate (epoll_event . layout () );
93- epoll_event . events (event , op );
120+ var event = arena .allocate (EVENT$LAYOUT );
121+ event_events (event , op );
94122 EVENT_DATA_FD$VH .set (event , 0 , fd );
95123 var ret = epoll_ctl (epfd , EPOLL_CTL_ADD (), fd , event , errorState );
96124 if (ret < 0 )
@@ -102,8 +130,8 @@ static void removeFileDescriptor(int epfd, int fd) {
102130 try (var arena = Arena .ofConfined ()) {
103131 var errorState = allocateErrorState (arena );
104132
105- var event = arena .allocate (epoll_event . layout () );
106- epoll_event . events (event , 0 );
133+ var event = arena .allocate (EVENT$LAYOUT );
134+ event_events (event , 0 );
107135 EVENT_DATA_FD$VH .set (event , 0 , fd );
108136 var ret = epoll_ctl (epfd , EPOLL_CTL_DEL (), fd , event , errorState );
109137 if (ret < 0 ) {
0 commit comments