use of net.i2p.util.FortunaRandomSource in project i2p.i2p by i2p.
the class Router method shutdown2.
/**
* Cancel the JVM runtime hook before calling this.
* Called by the ShutdownHook.
* NOT to be called by others, use shutdown().
*
* @param exitCode one of the EXIT_* values, non-negative
* @throws IllegalArgumentException if exitCode negative
*/
public synchronized void shutdown2(int exitCode) {
if (exitCode < 0)
throw new IllegalArgumentException();
changeState(State.FINAL_SHUTDOWN_2);
// help us shut down esp. after OOM
int priority = (exitCode == EXIT_OOM) ? Thread.MAX_PRIORITY - 1 : Thread.NORM_PRIORITY + 2;
Thread.currentThread().setPriority(priority);
_log.log(Log.CRIT, "Starting final shutdown(" + exitCode + ')');
// No, you can't do Thread.currentThread.setDaemon(false)
if (_killVMOnEnd) {
try {
(new Spinner()).start();
} catch (Throwable t) {
}
}
((RouterClock) _context.clock()).removeShiftListener(this);
_context.random().saveSeed();
I2PThread.removeOOMEventListener(_oomListener);
// Run the shutdown hooks first in case they want to send some goodbye messages
// Maybe we need a delay after this too?
LinkedList<Thread> tasks = new LinkedList<Thread>();
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 {
// task.run();
Thread t = new I2PAppThread(task, "Shutdown task " + task.getClass().getName());
t.setDaemon(true);
t.start();
tasks.add(t);
} catch (Throwable t) {
_log.log(Log.CRIT, "Error running shutdown task", t);
}
}
long waitSecs = SHUTDOWN_WAIT_SECS;
if (SystemVersion.isARM())
waitSecs *= 2;
final long maxWait = System.currentTimeMillis() + (waitSecs * 1000);
Thread th;
while ((th = tasks.poll()) != null) {
long toWait = maxWait - System.currentTimeMillis();
if (toWait <= 0) {
_log.logAlways(Log.WARN, "Shutdown tasks took more than " + waitSecs + " seconds to run");
tasks.clear();
break;
}
try {
th.join(toWait);
} catch (InterruptedException ie) {
}
if (th.isAlive()) {
_log.logAlways(Log.WARN, "Shutdown task took more than " + waitSecs + " seconds to run: " + th.getName());
tasks.clear();
break;
} else if (_log.shouldInfo()) {
_log.info("Shutdown task complete: " + th.getName());
}
}
// Set the last version to the current version, since 0.8.13
if (!RouterVersion.VERSION.equals(_config.get("router.previousVersion"))) {
saveConfig("router.previousVersion", RouterVersion.VERSION);
}
_context.removeShutdownTasks();
try {
_context.clientManager().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the client manager", t);
}
try {
_context.namingService().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the naming service", t);
}
try {
_context.jobQueue().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the job queue", t);
}
try {
_context.tunnelManager().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the tunnel manager", t);
}
try {
_context.tunnelDispatcher().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the tunnel dispatcher", t);
}
try {
_context.netDb().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the networkDb", t);
}
try {
_context.commSystem().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the comm system", t);
}
try {
_context.bandwidthLimiter().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the comm system", t);
}
try {
_context.peerManager().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the peer manager", t);
}
try {
_context.messageRegistry().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the message registry", t);
}
try {
_context.messageValidator().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the message validator", t);
}
try {
_context.inNetMessagePool().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the inbound net pool", t);
}
try {
_context.clientMessagePool().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the client msg pool", t);
}
try {
_context.sessionKeyManager().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the session key manager", t);
}
try {
_context.messageHistory().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the message history logger", t);
}
// do stat manager last to reduce chance of NPEs in other threads
try {
_context.statManager().shutdown();
} catch (Throwable t) {
_log.error("Error shutting down the stats manager", t);
}
_context.deleteTempDir();
List<RouterContext> contexts = RouterContext.getContexts();
contexts.remove(_context);
try {
_context.elGamalEngine().shutdown();
} catch (Throwable t) {
_log.log(Log.CRIT, "Error shutting elGamal", t);
}
if (contexts.isEmpty()) {
// any thing else to shut down?
} else {
_log.logAlways(Log.WARN, "Warning - " + contexts.size() + " routers remaining in this JVM, not releasing all resources");
}
try {
((FortunaRandomSource) _context.random()).shutdown();
} catch (Throwable t) {
_log.log(Log.CRIT, "Error shutting random()", t);
}
// logManager shut down in finalShutdown()
_watchdog.shutdown();
_watchdogThread.interrupt();
_eventLog.addEvent(EventLog.STOPPED, Integer.toString(exitCode));
finalShutdown(exitCode);
}
Aggregations