]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/Shutdown.java
Update user agent
[signal-cli] / src / main / java / org / asamk / signal / Shutdown.java
1 package org.asamk.signal;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5
6 import java.util.concurrent.CompletableFuture;
7 import java.util.concurrent.ExecutionException;
8
9 import sun.misc.Signal;
10
11 public class Shutdown {
12
13 private static final Logger logger = LoggerFactory.getLogger(Shutdown.class);
14 private static final CompletableFuture<Void> shutdown = new CompletableFuture<>();
15 private static final CompletableFuture<Void> shutdownComplete = new CompletableFuture<>();
16 private static boolean initialized = false;
17
18 public static void installHandler() {
19 if (initialized) {
20 return;
21 }
22 initialized = true;
23 Signal.handle(new Signal("INT"), Shutdown::handleSignal);
24 Signal.handle(new Signal("TERM"), Shutdown::handleSignal);
25 Runtime.getRuntime().addShutdownHook(Thread.ofPlatform().unstarted(() -> {
26 logger.debug("JVM is shutting down");
27 if (!shutdown.isDone()) {
28 triggerShutdown();
29 }
30
31 try {
32 logger.debug("Waiting for app to shut down");
33 shutdownComplete.get();
34 logger.debug("Exiting");
35 } catch (InterruptedException | ExecutionException e) {
36 throw new RuntimeException(e);
37 }
38 }));
39 }
40
41 public static void triggerShutdown() {
42 logger.debug("Triggering shutdown.");
43 shutdown.complete(null);
44 }
45
46 public static void waitForShutdown() throws InterruptedException {
47 try {
48 shutdown.get();
49 } catch (ExecutionException e) {
50 throw new RuntimeException(e);
51 }
52 }
53
54 public static void registerShutdownListener(Runnable action) {
55 shutdown.thenRun(action);
56 }
57
58 static void shutdownComplete() {
59 shutdownComplete.complete(null);
60 }
61
62 private static void handleSignal(Signal signal) {
63 logger.info("Received {} signal, shutting down ...", signal);
64 triggerShutdown();
65 }
66 }