Skip to content

Commit

Permalink
some cursed wait for exit
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Aug 20, 2024
1 parent 28cf672 commit fa9f8a5
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package xyz.wagyourtail.jvmdg.j9.intl;

import org.jetbrains.annotations.NotNull;
import sun.misc.Unsafe;
import xyz.wagyourtail.jvmdg.exc.MissingStubError;
import xyz.wagyourtail.jvmdg.j9.stub.java_base.J_L_ProcessHandle;
import xyz.wagyourtail.jvmdg.util.Utils;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -20,6 +26,29 @@
import java.util.stream.Stream;

public class UnixProcessHandle implements J_L_ProcessHandle {
private static final Unsafe unsafe = Utils.getUnsafe();
private static final MethodHandles.Lookup IMPL_LOOKUP = Utils.getImplLookup();
private static final MethodHandle waitForProcessExit;

static {
MethodHandle waitForProcessExit1;
try {
Class<?> unixProcess = Class.forName("java.lang.UNIXProcess");
waitForProcessExit1 = IMPL_LOOKUP.findVirtual(unixProcess, "waitForProcessExit", MethodType.methodType(int.class, int.class)).bindTo(unsafe.allocateInstance(unixProcess));
} catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException e) {
// we are probably on j9+, fallback on actual processHandle impl stuff
try {
waitForProcessExit1 = MethodHandles.insertArguments(IMPL_LOOKUP.findStatic(Class.forName("java.lang.ProcessHandleImpl"), "waitForProcessExit0", MethodType.methodType(int.class, long.class, boolean.class)), 1, false).asType(MethodType.methodType(int.class, int.class));
} catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException ex) {
throw new RuntimeException(ex);
}
} catch (InstantiationException e) {
throw new RuntimeException(e);
}

waitForProcessExit = waitForProcessExit1;
}

private final long pid;
private String[] pidInfo;
private final String[] cmdline;
Expand Down Expand Up @@ -56,7 +85,11 @@ private String[] readCmdLine() {
Path pth = Paths.get("/proc/" + pid + "/cmdline");
if (Files.isReadable(pth)) {
try {
return new String(Files.readAllBytes(pth)).split("\0");
String args = new String(Files.readAllBytes(pth));
if (args.isEmpty()) {
return null;
}
return args.split("\0");
} catch (IOException e) {
return null;
}
Expand Down Expand Up @@ -164,14 +197,15 @@ public Optional<String> user() {
@Override
public CompletableFuture<J_L_ProcessHandle> onExit() {
return CompletableFuture.supplyAsync(() -> {
try (WatchService ws = FileSystems.getDefault().newWatchService()) {
Path pth = Paths.get("/proc/" + pid + "/status");
pth.register(ws, StandardWatchEventKinds.ENTRY_DELETE);
ws.take();
return this;
} catch (IOException | InterruptedException e) {
if (pid > Integer.MAX_VALUE) {
throw MissingStubError.create();
}
try {
int exitCode = (int) waitForProcessExit.invokeExact((int) pid);
} catch (Throwable e) {
throw new RuntimeException(e);
}
return new UnixProcessHandle(pid);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import java.lang.management.ManagementFactory;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Semaphore;

public class TestProcessHandle {

public static void main(String[] args) throws IOException {
public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
ProcessHandle currentProcessHandle = ProcessHandle.current();
System.out.println(currentProcessHandle.pid() == ManagementFactory.getRuntimeMXBean().getPid());
List<String> lst = Arrays.asList(currentProcessHandle.info().arguments().get());
Expand All @@ -22,7 +24,6 @@ public static void main(String[] args) throws IOException {
}
Process p = pb.start();
currentProcessHandle.children().map(e -> String.join(" ", e.info().arguments().get())).forEach(System.out::println);
p.toHandle().onExit().thenAccept(e -> System.out.println(e.info().commandLine()));
// Thread.sleep(1);
System.out.println(p.toHandle().onExit().get().info().commandLine().orElse("missing"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ private static Stream<FlagsAndRunner> flags() {
return Stream.of(
new FlagsAndRunner(JavaRunner.JavaVersion.V1_8, flags.copy(e -> {
e.classVersion = JavaRunner.JavaVersion.V1_8.toOpcode();
e.multiReleaseVersions = Set.of(JavaRunner.JavaVersion.V11.toOpcode(), JavaRunner.JavaVersion.V17.toOpcode());
// e.multiReleaseVersions = Set.of(JavaRunner.JavaVersion.V11.toOpcode(), JavaRunner.JavaVersion.V17.toOpcode());
})),
new FlagsAndRunner(JavaRunner.JavaVersion.V11, flags.copy(e -> {
e.classVersion = JavaRunner.JavaVersion.V1_8.toOpcode();
e.multiReleaseVersions = Set.of(JavaRunner.JavaVersion.V11.toOpcode(), JavaRunner.JavaVersion.V17.toOpcode());
// e.multiReleaseVersions = Set.of(JavaRunner.JavaVersion.V11.toOpcode(), JavaRunner.JavaVersion.V17.toOpcode());
})),
new FlagsAndRunner(JavaRunner.JavaVersion.V17, flags.copy(e -> {
e.classVersion = JavaRunner.JavaVersion.V1_8.toOpcode();
e.multiReleaseVersions = Set.of(JavaRunner.JavaVersion.V11.toOpcode(), JavaRunner.JavaVersion.V17.toOpcode());
// e.multiReleaseVersions = Set.of(JavaRunner.JavaVersion.V11.toOpcode(), JavaRunner.JavaVersion.V17.toOpcode());
}))
// new FlagsAndRunner(flags.copy(e -> {
// e.classVersion = JavaRunner.JavaVersion.V1_7.toOpcode();
Expand Down

0 comments on commit fa9f8a5

Please sign in to comment.