package net.i2p.router.tasks;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
/**
* Simple thread that sits and waits forever, managing the
* graceful shutdown "process" (describing it would take more text
* than just reading the code...)
*
* @since 0.8.12 moved from Router
*/
public class GracefulShutdown implements Runnable {
private final RouterContext _context;
public GracefulShutdown(RouterContext ctx) {
_context = ctx;
}
public void run() {
Log log = _context.logManager().getLog(Router.class);
while (true) {
boolean shutdown = _context.router().gracefulShutdownInProgress();
if (shutdown) {
int gracefulExitCode = _context.router().scheduledGracefulExitCode();
if (gracefulExitCode == Router.EXIT_HARD || gracefulExitCode == Router.EXIT_HARD_RESTART ||
_context.tunnelManager().getParticipatingCount() <= 0) {
if (gracefulExitCode == Router.EXIT_HARD)
log.log(Log.CRIT, "Shutting down after a brief delay");
else if (gracefulExitCode == Router.EXIT_HARD_RESTART)
log.log(Log.CRIT, "Restarting after a brief delay");
else
log.log(Log.CRIT, "Graceful shutdown progress: No more tunnels, starting final shutdown");
// Allow time for a UI reponse
try {
synchronized (Thread.currentThread()) {
Thread.currentThread().wait(2*1000);
}
} catch (InterruptedException ie) {}
_context.router().shutdown(gracefulExitCode);
return;
} else {
try {
synchronized (Thread.currentThread()) {
Thread.currentThread().wait(10*1000);
}
} catch (InterruptedException ie) {}
}
} else {
try {
synchronized (Thread.currentThread()) {
Thread.currentThread().wait();
}
} catch (InterruptedException ie) {}
}
}
}
}