more cleanup at shutdown

This commit is contained in:
zzz
2011-06-14 19:27:46 +00:00
parent 21b76f1ca1
commit 3c88c854bf
3 changed files with 37 additions and 5 deletions

View File

@ -1,6 +1,7 @@
package net.i2p;
import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.Properties;
import java.util.Random;
@ -100,7 +101,7 @@ public class I2PAppContext {
private volatile boolean _randomInitialized;
private volatile boolean _keyGeneratorInitialized;
protected volatile boolean _keyRingInitialized; // used in RouterContext
private Set<Runnable> _shutdownTasks;
protected final Set<Runnable> _shutdownTasks;
private File _baseDir;
private File _configDir;
private File _routerDir;
@ -185,7 +186,7 @@ public class I2PAppContext {
_elGamalAESEngineInitialized = false;
_logManagerInitialized = false;
_keyRingInitialized = false;
_shutdownTasks = new ConcurrentHashSet(0);
_shutdownTasks = new ConcurrentHashSet(16);
initializeDirs();
}
@ -843,12 +844,24 @@ public class I2PAppContext {
}
}
/**
* WARNING - Shutdown tasks are not executed in an I2PAppContext.
* You must be in a RouterContext for the tasks to be executed
* at shutdown.
* This method moved from Router in 0.7.1 so that clients
* may use it without depending on router.jar.
* @since 0.7.1
*/
public void addShutdownTask(Runnable task) {
_shutdownTasks.add(task);
}
/**
* @return an unmodifiable Set
* @since 0.7.1
*/
public Set<Runnable> getShutdownTasks() {
return new HashSet(_shutdownTasks);
return Collections.unmodifiableSet(_shutdownTasks);
}
/**

View File

@ -49,6 +49,7 @@ import net.i2p.util.I2PAppThread;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.util.SecureFileOutputStream;
import net.i2p.util.SimpleByteCache;
import net.i2p.util.SimpleScheduler;
import net.i2p.util.SimpleTimer;
@ -257,7 +258,7 @@ public class Router {
_killVMOnEnd = true;
_oomListener = new I2PThread.OOMEventListener() {
public void outOfMemory(OutOfMemoryError oom) {
ByteCache.clearAll();
clearCaches();
_log.log(Log.CRIT, "Thread ran out of memory", oom);
for (int i = 0; i < 5; i++) { // try this 5 times, in case it OOMs
try {
@ -280,6 +281,12 @@ public class Router {
}
/** @since 0.8.8 */
private static final void clearCaches() {
ByteCache.clearAll();
SimpleByteCache.clearAll();
}
/**
* Configure the router to kill the JVM when the router shuts down, as well
* as whether to explicitly halt the JVM during the hard fail process.
@ -624,6 +631,7 @@ public class Router {
_log.log(Log.CRIT, "Error running shutdown task", t);
}
}
_context.removeShutdownTasks();
// hard and ugly
if (System.getProperty("wrapper.version") != null)
_log.log(Log.CRIT, "Restarting with new router identity");
@ -940,12 +948,15 @@ public class Router {
// 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()) {
if (_log.shouldLog(Log.WARN))
_log.warn("Running shutdown task " + task.getClass());
try {
task.run();
} catch (Throwable t) {
_log.log(Log.CRIT, "Error running shutdown task", t);
}
}
_context.removeShutdownTasks();
try { _context.clientManager().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the client manager", t); }
try { _context.namingService().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the naming service", t); }
try { _context.jobQueue().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the job queue", t); }
@ -972,6 +983,7 @@ public class Router {
private static final boolean ALLOW_DYNAMIC_KEYS = false;
private void finalShutdown(int exitCode) {
clearCaches();
_log.log(Log.CRIT, "Shutdown(" + exitCode + ") complete" /* , new Exception("Shutdown") */ );
try { _context.logManager().shutdown(); } catch (Throwable t) { }
if (ALLOW_DYNAMIC_KEYS) {
@ -1486,7 +1498,7 @@ private static class CoalesceStatsEvent implements SimpleTimer.TimedEvent {
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
getContext().statManager().addRateData("router.memoryUsed", used, 0);
if (_maxMemory - used < LOW_MEMORY_THRESHOLD)
ByteCache.clearAll();
clearCaches();
getContext().tunnelDispatcher().updateParticipatingStats(COALESCE_TIME);

View File

@ -402,6 +402,13 @@ public class RouterContext extends I2PAppContext {
}
}
/**
* @since 0.8.8
*/
void removeShutdownTasks() {
_shutdownTasks.clear();
}
/**
* Use this instead of context instanceof RouterContext
* @return true