/*
typedef union epoll_data
{
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
*/
public static class epoll_data_t extends Union {
public Pointer ptr;
public int fd;
public int u32;
public long u64;
public epoll_data_t() {
super();
}
public epoll_data_t(int fd_or_u32) {
super();
this.u32 = this.fd = fd_or_u32;
setType(Integer.TYPE);
}
public epoll_data_t(long u64) {
super();
this.u64 = u64;
setType(Long.TYPE);
}
public epoll_data_t(Pointer ptr) {
super();
this.ptr = ptr;
setType(Pointer.class);
}
public static class ByReference extends epoll_data_t implements com.sun.jna.Structure.ByReference {
};
public static class ByValue extends epoll_data_t implements com.sun.jna.Structure.ByValue {
};
}
/*
struct epoll_event
{
uint32_t events; //Epoll events
epoll_data_t data; //User data variable
} __EPOLL_PACKED;
*/
public static class epoll_event extends Structure {
/// Epoll events
public int events;
/// User data variable
public epoll_data_t data;
public epoll_event() {
super();
}
protected List getFieldOrder() {
return Arrays.asList("events", "data");
}
public epoll_event(Pointer p) {
super(p);
}
public epoll_event(int events, epoll_data_t data) {
super();
this.events = events;
this.data = data;
}
public static class ByReference extends epoll_event implements Structure.ByReference {
};
public static class ByValue extends epoll_event implements Structure.ByValue {
};
}
//extern int epoll_create (int __size) __THROW;
public static native int epoll_create(int size);
//extern int epoll_create1 (int __flags) __THROW;
public static native int epoll_create1(int flags);
//extern int epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event) __THROW;
public static native int epoll_ctl(int epfd, int op, int fd, epoll_event.ByReference event);
public static native int epoll_ctl(int epfd, int op, int fd, Pointer event);
//extern int epoll_wait (int __epfd, struct epoll_event *__events, int __maxevents, int __timeout);
public static native int epoll_wait(int epfd, Pointer events, int maxevents, int timeout);
//extern int epoll_pwait (int __epfd, struct epoll_event *__events, int __maxevents, int __timeout, const __sigset_t *__ss);
public static native int epoll_pwait(int epfd, Pointer events, int maxevents, int timeout, Pointer ss);
public static Pointer createPointerToStructureArray(Class<? extends Structure> cls, int size) {
final int size_of_struct = Native.getNativeSize(cls);
final PinnableMemory m = PinnableMemory.pin(size * Pointer.SIZE);
for(int i = 0; i < size; ++i) {
m.setPointer(i * Pointer.SIZE, PinnableMemory.pin(size_of_struct));
}
return m;
}
public static Pointer itemInStructureArrayAtIndex(Pointer array, int index) {
return array.getPointer(index * Pointer.SIZE);
}
public static void disposeStructureArray(Pointer ptr) {
final PinnableMemory orig = PinnableMemory.unpin(ptr);
final int size = (int)(orig.size() / (long)Pointer.SIZE);
PinnableMemory entry;
for(int i = 0; i < size; ++i) {
if ((entry = PinnableMemory.unpin(orig.getPointer(i * Pointer.SIZE))) != null) {
entry.dispose();
}
}
orig.dispose();
}
final int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
final epoll_event.ByReference event = new epoll_event.ByReference();
event.data.fd = <some other file descriptor>;
event.events = EPOLLOUT | EPOLLET | EPOLLHUP | EPOLLONESHOT;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, <some other file descriptor>, event);
...
final int MAX_EVENTS = 2;
final Pointer events = createPointerToStructureArray(epoll_event.class, MAX_EVENTS);
epoll_event event;
int ready_count = 0;
int i = 0;
try {
while((ready_count = epoll_wait(epoll_fd, events, MAX_EVENTS, -1)) > 0) {
System.out.println("Got " + ready_count + " events");
for(i = 0; i < ready_count; ++i) {
event = new epoll_event(itemInStructureArrayAtIndex(events, i));
System.out.println(" FD: " + event.data.fd);
}
}
} finally {
disposeStructureArray(events);
}
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f52503269a0, pid=6021, tid=139991306516224
#
# JRE version: 6.0_45-b06
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.45-b01 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libc.so.6+0x14d9a0] __nss_hosts_lookup+0x152a0
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x00007f52481bf800): JavaThread "pool-1-thread-1" [_thread_in_vm, id=6043, stack(0x00007f524408b000,0x00007f524418c000)]
siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x000000000000000c
Registers:
RAX=0x00000000ebc158f8, RBX=0x00007f525006f300, RCX=0x0000000000000000, RDX=0x0000000000000010
RSP=0x00007f5244189a98, RBP=0x00007f5244189b20, RSI=0x000000000000001c, RDI=0x00000000ebc15908
R8 =0x0000000000000010, R9 =0x00007f52503269a0, R10=0x00007f525006b200, R11=0x00007f5250365b80
R12=0x0000000000000010, R13=0x0000000000000000, R14=0x0000000000000010, R15=0x00007f5244189ab0
RIP=0x00007f52503269a0, EFLAGS=0x0000000000010207, CSGSFS=0x0000000000000033, ERR=0x0000000000000004
TRAPNO=0x000000000000000e
Top of Stack: (sp=0x00007f5244189a98)
0x00007f5244189a98: 00007f524fae1457 00007f5248006dc0
0x00007f5244189aa8: 000000000000000c 00007f52481bf800
0x00007f5244189ab8: 0000000000000000 00007f52481bf800
0x00007f5244189ac8: 00000000bd441440 00007f52481bf800
0x00007f5244189ad8: 00007f52481bf800 00007f52481bf800
0x00007f5244189ae8: 00007f524faa61ce 00000000bd55396b
0x00007f5244189af8: 00000000bd441440 0000000000000000
0x00007f5244189b08: 00000000bd441440 00007f5244189c08
0x00007f5244189b18: 00007f52481bf800 00007f5244189b50
0x00007f5244189b28: 00007f51ff5b67df 0000000000000010
0x00007f5244189b38: 00007f5244189bf8 000000000000000c
0x00007f5244189b48: 00007f52481bf9d0 00007f5244189bc8
0x00007f5244189b58: 00007f5245016cd5 00007f5244189c50
0x00007f5244189b68: 00007f5244189be8 00007f5208004300
0x00007f5244189b78: 00007f5208004320 00007f52481bf800
0x00007f5244189b88: 00007f5244189b88 00000000bd441440
0x00007f5244189b98: 00007f5244189c08 00000000bd447b08
0x00007f5244189ba8: 0000000000000000 00000000bd441440
0x00007f5244189bb8: 0000000000000000 00007f5244189be8
0x00007f5244189bc8: 00007f5244189c50 00007f5245005b02
0x00007f5244189bd8: 00000000bd444128 00007f5245012298
0x00007f5244189be8: 0000000000000010 0000000000000000
0x00007f5244189bf8: 00000000ebc158e8 000000000000000c
0x00007f5244189c08: 00000000ebbf6670 00007f5244189c10
0x00007f5244189c18: 00000000bd55396b 00007f5244189c88
0x00007f5244189c28: 00000000bd5692c0 0000000000000000
0x00007f5244189c38: 00000000bd5539b8 00007f5244189be8
0x00007f5244189c48: 00007f5244189c60 00007f5244189cd0
0x00007f5244189c58: 00007f5245005b02 0000000000000010
0x00007f5244189c68: 0000000000000000 00000000ebc158e8
0x00007f5244189c78: 0000000000000000 00007f52481bf800
0x00007f5244189c88: 00000000ebbf6670 00007f5244189c90
Instructions: (pc=0x00007f52503269a0)
0x00007f5250326980: 4c 8b 56 e8 4c 8b 5e f0 48 8b 56 f8 4c 89 57 e8
0x00007f5250326990: 4c 89 5f f0 48 89 57 f8 c3 0f 1f 80 00 00 00 00
0x00007f52503269a0: 4c 8b 5e f0 48 8b 56 f8 4c 89 5f f0 48 89 57 f8
0x00007f52503269b0: c3 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00
Register to memory mapping:
RAX=0x00000000ebc158f8 is an unknown value
RBX=0x00007f525006f300: <offset 0xaa6300> in /opt/java/jdk1.6.0_45/jre/lib/amd64/server/libjvm.so at 0x00007f524f5c9000
RCX=0x0000000000000000 is an unknown value
RDX=0x0000000000000010 is an unknown value
RSP=0x00007f5244189a98 is pointing into the stack for thread: 0x00007f52481bf800
RBP=0x00007f5244189b20 is pointing into the stack for thread: 0x00007f52481bf800
RSI=0x000000000000001c is an unknown value
RDI=0x00000000ebc15908 is an oop
java.lang.String
- klass: 'java/lang/String'
R8 =0x0000000000000010 is an unknown value
R9 =0x00007f52503269a0: <offset 0x14d9a0> in /lib/x86_64-linux-gnu/libc.so.6 at 0x00007f52501d9000
R10=0x00007f525006b200: <offset 0xaa2200> in /opt/java/jdk1.6.0_45/jre/lib/amd64/server/libjvm.so at 0x00007f524f5c9000
R11=0x00007f5250365b80: <offset 0x18cb80> in /lib/x86_64-linux-gnu/libc.so.6 at 0x00007f52501d9000
R12=0x0000000000000010 is an unknown value
R13=0x0000000000000000 is an unknown value
R14=0x0000000000000010 is an unknown value
R15=0x00007f5244189ab0 is pointing into the stack for thread: 0x00007f52481bf800
Stack: [0x00007f524408b000,0x00007f524418c000], sp=0x00007f5244189a98, free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libc.so.6+0x14d9a0] __nss_hosts_lookup+0x152a0
C [jna117475868801589856.tmp+0x67df] Java_com_sun_jna_Native_read__J_3BII+0xbf
j com.sun.jna.Native.read(J[BII)V+0
j com.sun.jna.Pointer.read(J[BII)V+11
j com.sun.jna.Pointer.getByteArray(JI)[B+11
j com.sun.jna.Structure.toString(IZZ)Ljava/lang/String;+739
j com.sun.jna.Structure.toString(Z)Ljava/lang/String;+4
j com.sun.jna.Structure.toString()Ljava/lang/String;+7
j com.intellij.rt.debugger.BatchEvaluatorServer.evaluate([Ljava/lang/Object;)[Ljava/lang/Object;+24
v ~StubRoutines::call_stub
V [libjvm.so+0x4e14a0] JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x1e0
V [libjvm.so+0x711a39] os::os_exception_wrapper(void (*)(JavaValue*, methodHandle*, JavaCallArguments*, Thread*), JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x19
V [libjvm.so+0x4e12b5] JavaCalls::call(JavaValue*, methodHandle, JavaCallArguments*, Thread*)+0x25
V [libjvm.so+0x51d0ef] jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)+0x1af
V [libjvm.so+0x4f91f1] unsigned+0x171
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j com.sun.jna.Native.read(J[BII)V+0
j com.sun.jna.Pointer.read(J[BII)V+11
j com.sun.jna.Pointer.getByteArray(JI)[B+11
j com.sun.jna.Structure.toString(IZZ)Ljava/lang/String;+739
j com.sun.jna.Structure.toString(Z)Ljava/lang/String;+4
j com.sun.jna.Structure.toString()Ljava/lang/String;+7
j com.intellij.rt.debugger.BatchEvaluatorServer.evaluate([Ljava/lang/Object;)[Ljava/lang/Object;+24
v ~StubRoutines::call_stub
j jcommon.process.platform.unix.UnixProcessLauncherEPoll$1$1.doWork()V+90
j jcommon.core.concurrent.BoundedAutoGrowThreadPool$1.run()V+14
j java.lang.Thread.run()V+11
v ~StubRoutines::call_stub
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
0x00007f52481e5000 JavaThread "pool-1-thread-3" [_thread_in_native, id=6045, stack(0x00007f51ff3ae000,0x00007f51ff4af000)]
0x00007f52481ff000 JavaThread "pool-1-thread-2" [_thread_in_native, id=6044, stack(0x00007f51ff4af000,0x00007f51ff5b0000)]
=>0x00007f52481bf800 JavaThread "pool-1-thread-1" [_thread_in_vm, id=6043, stack(0x00007f524408b000,0x00007f524418c000)]
0x00007f52480a7000 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=6040, stack(0x00007f5244cfd000,0x00007f5244dfe000)]
0x00007f52480a4800 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=6039, stack(0x00007f5244dfe000,0x00007f5244eff000)]
0x00007f52480a2000 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=6038, stack(0x00007f5244eff000,0x00007f5245000000)]
0x00007f521c001800 JavaThread "JDWP Command Reader" daemon [_thread_in_native, id=6037, stack(0x00007f524c071000,0x00007f524c172000)]
0x00007f524809f800 JavaThread "JDWP Event Helper Thread" daemon [_thread_blocked, id=6036, stack(0x00007f524c172000,0x00007f524c273000)]
0x00007f524809c000 JavaThread "JDWP Transport Listener: dt_socket" daemon [_thread_blocked, id=6033, stack(0x00007f524c273000,0x00007f524c374000)]
0x00007f5248090000 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=6032, stack(0x00007f524c478000,0x00007f524c579000)]
0x00007f5248074800 JavaThread "Finalizer" daemon [_thread_blocked, id=6031, stack(0x00007f524c579000,0x00007f524c67a000)]
0x00007f5248072800 JavaThread "Reference Handler" daemon [_thread_blocked, id=6030, stack(0x00007f524c67a000,0x00007f524c77b000)]
0x00007f524800a800 JavaThread "main" [_thread_blocked, id=6022, stack(0x00007f524f1c3000,0x00007f524f2c4000)]
Other Threads:
0x00007f524806c000 VMThread [stack: 0x00007f524c77b000,0x00007f524c87c000] [id=6029]
0x00007f52480b1800 WatcherThread [stack: 0x00007f5244bfc000,0x00007f5244cfd000] [id=6041]
VM state:not at safepoint (normal execution)
final int MAX_EVENTS = 1;
//Create a region of memory analogous to a native array where the elements are
//contiguously placed.
final int size_of_struct = new epoll_event().size();
final PinnableMemory ptr = new PinnableMemory(MAX_EVENTS * size_of_struct);
final epoll_event event = new epoll_event();
int ready_count = 0;
int i = 0;
try {
while((ready_count = epoll_wait(epoll_fd, ptr, MAX_EVENTS, -1)) > 0) {
int err = Native.getLastError();
System.out.println("GOT " + ready_count + " events");
System.out.println("ERR " + err);
for(i = 0; i < ready_count; ++i) {
event.reuse(ptr, size_of_struct * i);
System.out.println(" FD: " + event.data.fd);
System.out.println(" Events: " + event.events);
}
}
} finally {
ptr.dispose();
}
#include <stdio.h>
#include <sys/epoll.h>
int main(int argc, char** argv) {
printf("size of epoll_event: %d\n", sizeof(struct epoll_event));
}
size of epoll_event: 12
System.out.println("A - size of epoll_event: " + new epoll_event().size());
System.out.println("B - size of epoll_event: " + Native.getNativeSize(epoll_event.class));
A - size of epoll_event: 16
B - size of epoll_event: 8
public class epoll_event extends Structure {
public int events;
public epoll_data_t data;
}
public class epoll_data_t extends Union {
public Pointer ptr;
public int fd;
public int u32;
public long u64;
}
That makes sense, but as I showed, it's not 16, it's 12 on 64-bit. I did notice that epoll_event is annotated with __EPOLL_PACKED which I believe translates to __attribute__((__packed__)). How can I compensate for that?
--