* Router shutdown:

- Fix failsafe shutdown hook broken in 0.8.8;
      HUP, INT, and TERM signals should now shut down cleanly.
    - Shutdown hook no longer prevents other hooks from running
    - Trap HUP, if router.gracefulHUP=true, and do graceful shutdown.
      Only under wrapper, non-Windows.
    - i2prouter stop now uses SIGTERM
    - Implement i2prouter graceful using SIGHUP (ticket #580)
    - Configure wrapper to ignore SIGUSR1 and SIGUSR2 as they will shut down
      or crash the JVM
This commit is contained in:
zzz
2012-01-08 13:15:47 +00:00
parent 56a67729e3
commit f6ca6a5e0d
6 changed files with 144 additions and 3 deletions

View File

@@ -233,6 +233,8 @@ public class Router implements RouterClock.ClockShiftListener {
String now = Long.toString(System.currentTimeMillis());
_config.put("router.firstInstalled", now);
_config.put("router.updateLastInstalled", now);
// only compatible with new i2prouter script
_config.put("router.gracefulHUP", "true");
saveConfig();
}
@@ -376,7 +378,7 @@ public class Router implements RouterClock.ClockShiftListener {
_isAlive = true;
_started = _context.clock().now();
try {
Runtime.getRuntime().removeShutdownHook(_shutdownHook);
Runtime.getRuntime().addShutdownHook(_shutdownHook);
} catch (IllegalStateException ise) {}
I2PThread.addOOMEventListener(_oomListener);
@@ -987,9 +989,12 @@ public class Router implements RouterClock.ClockShiftListener {
/**
* Cancel the JVM runtime hook before calling this.
* Called by the ShutdownHook.
* NOT to be called by others, use shutdown().
*/
public void shutdown2(int exitCode) {
_shutdownInProgress = true;
_log.log(Log.CRIT, "Starting final shutdown(" + exitCode + ')');
// So we can get all the way to the end
// No, you can't do Thread.currentThread.setDaemon(false)
if (_killVMOnEnd) {
@@ -1004,6 +1009,7 @@ public class Router implements RouterClock.ClockShiftListener {
// Run the shutdown hooks first in case they want to send some goodbye messages
// Maybe we need a delay after this too?
for (Runnable task : _context.getShutdownTasks()) {
//System.err.println("Running shutdown task " + task.getClass());
if (_log.shouldLog(Log.WARN))
_log.warn("Running shutdown task " + task.getClass());
try {
@@ -1098,7 +1104,7 @@ public class Router implements RouterClock.ClockShiftListener {
//Runtime.getRuntime().halt(exitCode);
// allow the Runtime shutdown hooks to execute
Runtime.getRuntime().exit(exitCode);
} else {
} else if (System.getProperty("java.vendor").contains("Android")) {
Runtime.getRuntime().gc();
}
}

View File

@@ -32,6 +32,10 @@ public class ShutdownHook extends Thread {
setName("Router " + _id + " shutdown");
Log l = _context.logManager().getLog(Router.class);
l.log(Log.CRIT, "Shutting down the router...");
// Needed to make the wrapper happy, otherwise it gets confused
// and thinks we haven't shut down, possibly because it
// prevents other shutdown hooks from running
_context.router().setKillVMOnEnd(false);
_context.router().shutdown2(Router.EXIT_HARD);
}
}