No, the finally block is not being run for me when I Ctrl-C (in Linux).
I recommend moving your finally logic to a method "shutdown". Then calling it from both the finally block as well as from a Ctrl-C handler. Like this:
private void registerSigIntHandler() {
final SignalHandler defaultSigIntHandler = Signal.handle(new Signal("INT"), SignalHandler.SIG_DFL);
Signal.handle(new Signal("INT"), new SignalHandler() {
public void handle(Signal signal) {
log.info("SIGINT received");
Signal.handle(new Signal("INT"), SignalHandler.SIG_DFL);
shutdown();
defaultSigIntHandler.handle(signal); }
});
}
The benefit of doing it this way is that after shutdown completes, the SIG_DFL handler executes, terminating the program via the default OS SIGINT handler. This terminates the main thread and the entire process. Otherwise, if you do not use SIG_DFL, you have to somehow signal the main thread to exit. My main thread does not listen/poll for shutdown signals/messages. It is a long-running data-migration job. I want to shut down certain things but terminate the main thread and subthreads.
Also if shutdown hangs (hopefully should not happen), a second ctrl-c will terminate the program via the SIG_DFL handler.
In shutdown, I also set an AtomicBoolean to ensure shutdown is only run once.
boolean isShuttingDown = this.isShuttingDown.getAndSet(true);
if (isShuttingDown) {
return;
}
I also tried addShutdownHook
(an alternative to Signal.handle
) but ran into trouble with it not running my shutdown routine fully. I was messaging and joining with subthreads.
Note: Do not call SignalHandler.SIG_DFL.handle(new Signal("INT"));
. It gives me SIGSEGV every time (which does exit the program). - How do I trigger the default signal handling behavior?