X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/cbbfc4ea6ead16711f1360105414c211456d7138..f252597002c3c95e8ed68338c53a41d519b24dcd:/src/main/java/org/asamk/signal/Shutdown.java diff --git a/src/main/java/org/asamk/signal/Shutdown.java b/src/main/java/org/asamk/signal/Shutdown.java new file mode 100644 index 00000000..a59497c9 --- /dev/null +++ b/src/main/java/org/asamk/signal/Shutdown.java @@ -0,0 +1,66 @@ +package org.asamk.signal; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import sun.misc.Signal; + +public class Shutdown { + + private static final Logger logger = LoggerFactory.getLogger(Shutdown.class); + private static final CompletableFuture shutdown = new CompletableFuture<>(); + private static final CompletableFuture shutdownComplete = new CompletableFuture<>(); + private static boolean initialized = false; + + public static void installHandler() { + if (initialized) { + return; + } + initialized = true; + Signal.handle(new Signal("INT"), Shutdown::handleSignal); + Signal.handle(new Signal("TERM"), Shutdown::handleSignal); + Runtime.getRuntime().addShutdownHook(Thread.ofPlatform().unstarted(() -> { + logger.debug("JVM is shutting down"); + if (!shutdown.isDone()) { + triggerShutdown(); + } + + try { + logger.debug("Waiting for app to shut down"); + shutdownComplete.get(); + logger.debug("Exiting"); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + })); + } + + public static void triggerShutdown() { + logger.debug("Triggering shutdown."); + shutdown.complete(null); + } + + public static void waitForShutdown() throws InterruptedException { + try { + shutdown.get(); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } + + public static void registerShutdownListener(Runnable action) { + shutdown.thenRun(action); + } + + static void shutdownComplete() { + shutdownComplete.complete(null); + } + + private static void handleSignal(Signal signal) { + logger.info("Received {} signal, shutting down ...", signal); + triggerShutdown(); + } +}