brettwooldridge / NuProcess

Low-overhead, non-blocking I/O, external Process implementation for Java
Apache License 2.0
712 stars 84 forks source link

Add constructor with com.sun.jna.Pointer to LibKevent.Kevent #82

Closed fr0l closed 6 years ago

fr0l commented 6 years ago

What this PR does?

What this PR solves?

Problem description:

When in com.zaxxer.nuprocess.osx.ProcessKqueue#registerProcess an array of Kevent is created by using method com.sun.jna.Structure#toArray(int),

Kevent[] events = (Kevent[]) new Kevent().toArray(4);

then eventually method com.sun.jna.Structure#newInstance(java.lang.Class<?>, com.sun.jna.Pointer) searches for constructor which accepts Pointer. And there is a try..catch with some additional logic which calls com.sun.jna.Structure#useMemory.

Currently when creating thousands of processes, it ads extra unnecessary calls which seems not really optimal. Since the LibKevent.Kevent is a subclass of com.sun.jna.Structure, then it looks reasonable to implement it's constructor com.sun.jna.Structure#Structure(com.sun.jna.Pointer)

Without this patch I see thousands of exceptions with following stack trace in jmc

void jdk.jfr.internal.instrument.ThrowableTracer.traceThrowable(Throwable, String)
void java.lang.Throwable.<init>(String)
void java.lang.Exception.<init>(String)
void java.lang.ReflectiveOperationException.<init>(String)
void java.lang.NoSuchMethodException.<init>(String)
Constructor java.lang.Class.getConstructor0(Class[], int)
Constructor java.lang.Class.getConstructor(Class[])
Structure com.sun.jna.Structure.newInstance(Class, Pointer)
Structure[] com.sun.jna.Structure.toArray(Structure[])
Structure[] com.sun.jna.Structure.toArray(int)
void com.zaxxer.nuprocess.osx.ProcessKqueue.registerProcess(OsxProcess)
void com.zaxxer.nuprocess.osx.ProcessKqueue.registerProcess(BasePosixProcess)
void com.zaxxer.nuprocess.internal.BasePosixProcess.registerProcess()
NuProcess com.zaxxer.nuprocess.internal.BasePosixProcess.start(List, String[], Path)
NuProcess com.zaxxer.nuprocess.osx.OsxProcessFactory.createProcess(List, String[], NuProcessHandler, Path)
NuProcess com.zaxxer.nuprocess.NuProcessBuilder.start()
NuProcess com.badoo.automation.deviceserver.command.ShellCommand.startProcessInternal(List, Map, IShellCommandListener)
brettwooldridge commented 6 years ago

@dr0pt4ble Thanks for the PR. I will try to evaluate it over the next day or two. It seems a reasonable and simple change.