package org.atomnuke.kernel.shutdown; import java.util.Stack; import org.atomnuke.lifecycle.Reclaimable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author zinic */ public class KernelShutdownHook implements Runnable, ShutdownHook { private static final Logger LOG = LoggerFactory.getLogger(KernelShutdownHook.class); private final Stack<Reclaimable> childHooks; private boolean shutdown; public KernelShutdownHook() { childHooks = new Stack<Reclaimable>(); shutdown = false; registerWithRuntime(); } private void registerWithRuntime() { Runtime.getRuntime().addShutdownHook(new Thread(this)); } @Override public synchronized void enlist(Reclaimable destroyable) { if (!shutdown) { childHooks.push(destroyable); } } @Override public synchronized void run() { shutdown(); } @Override public void shutdown() { if (!shutdown) { shutdown = true; LOG.info("Process shutting down."); callHooks(); } } private void callHooks() { while (!childHooks.isEmpty()) { final Reclaimable shutdownHook = childHooks.pop(); try { LOG.info("Running destroy hook, " + shutdownHook + "."); shutdownHook.destroy(); } catch (Exception ex) { LOG.info("Failure occured while calling destroy hook, " + shutdownHook + ". Reason: " + ex.getMessage(), ex); } } } }