jline.internal.ShutdownHooks Maven / Gradle / Ivy
/*
* Copyright (c) 2002-2012, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package jline.internal;
import java.util.ArrayList;
import java.util.List;
import static jline.internal.Preconditions.checkNotNull;
/**
* Manages the JLine shutdown-hook thread and tasks to execute on shutdown.
*
* @author Jason Dillon
* @since 2.7
*/
public class ShutdownHooks
{
public static final String JLINE_SHUTDOWNHOOK = "jline.shutdownhook";
private static final boolean enabled = Configuration.getBoolean(JLINE_SHUTDOWNHOOK, true);
private static final List tasks = new ArrayList();
private static Thread hook;
public static synchronized T add(final T task) {
checkNotNull(task);
// If not enabled ignore
if (!enabled) {
Log.debug("Shutdown-hook is disabled; not installing: ", task);
return task;
}
// Install the hook thread if needed
if (hook == null) {
hook = addHook(new Thread("JLine Shutdown Hook")
{
@Override
public void run() {
runTasks();
}
});
}
// Track the task
Log.debug("Adding shutdown-hook task: ", task);
tasks.add(task);
return task;
}
private static synchronized void runTasks() {
Log.debug("Running all shutdown-hook tasks");
// Iterate through copy of tasks list
for (Task task : tasks.toArray(new Task[tasks.size()])) {
Log.debug("Running task: ", task);
try {
task.run();
}
catch (Throwable e) {
Log.warn("Task failed", e);
}
}
tasks.clear();
}
private static Thread addHook(final Thread thread) {
Log.debug("Registering shutdown-hook: ", thread);
try {
Runtime.getRuntime().addShutdownHook(thread);
}
catch (AbstractMethodError e) {
// JDK 1.3+ only method. Bummer.
Log.debug("Failed to register shutdown-hook", e);
}
return thread;
}
public static synchronized void remove(final Task task) {
checkNotNull(task);
// ignore if not enabled or hook never installed
if (!enabled || hook == null) {
return;
}
// Drop the task
tasks.remove(task);
// If there are no more tasks, then remove the hook thread
if (tasks.isEmpty()) {
removeHook(hook);
hook = null;
}
}
private static void removeHook(final Thread thread) {
Log.debug("Removing shutdown-hook: ", thread);
try {
Runtime.getRuntime().removeShutdownHook(thread);
}
catch (AbstractMethodError e) {
// JDK 1.3+ only method. Bummer.
Log.debug("Failed to remove shutdown-hook", e);
}
catch (IllegalStateException e) {
// The VM is shutting down, not a big deal; ignore
}
}
/**
* Essentially a {@link Runnable} which allows running to throw an exception.
*/
public static interface Task
{
void run() throws Exception;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy