forked from I2P_Developers/i2p.i2p
more cleanup at shutdown
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
package net.i2p;
|
package net.i2p;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@ -100,7 +101,7 @@ public class I2PAppContext {
|
|||||||
private volatile boolean _randomInitialized;
|
private volatile boolean _randomInitialized;
|
||||||
private volatile boolean _keyGeneratorInitialized;
|
private volatile boolean _keyGeneratorInitialized;
|
||||||
protected volatile boolean _keyRingInitialized; // used in RouterContext
|
protected volatile boolean _keyRingInitialized; // used in RouterContext
|
||||||
private Set<Runnable> _shutdownTasks;
|
protected final Set<Runnable> _shutdownTasks;
|
||||||
private File _baseDir;
|
private File _baseDir;
|
||||||
private File _configDir;
|
private File _configDir;
|
||||||
private File _routerDir;
|
private File _routerDir;
|
||||||
@ -185,7 +186,7 @@ public class I2PAppContext {
|
|||||||
_elGamalAESEngineInitialized = false;
|
_elGamalAESEngineInitialized = false;
|
||||||
_logManagerInitialized = false;
|
_logManagerInitialized = false;
|
||||||
_keyRingInitialized = false;
|
_keyRingInitialized = false;
|
||||||
_shutdownTasks = new ConcurrentHashSet(0);
|
_shutdownTasks = new ConcurrentHashSet(16);
|
||||||
initializeDirs();
|
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) {
|
public void addShutdownTask(Runnable task) {
|
||||||
_shutdownTasks.add(task);
|
_shutdownTasks.add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return an unmodifiable Set
|
||||||
|
* @since 0.7.1
|
||||||
|
*/
|
||||||
public Set<Runnable> getShutdownTasks() {
|
public Set<Runnable> getShutdownTasks() {
|
||||||
return new HashSet(_shutdownTasks);
|
return Collections.unmodifiableSet(_shutdownTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,6 +49,7 @@ import net.i2p.util.I2PAppThread;
|
|||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.SecureFileOutputStream;
|
import net.i2p.util.SecureFileOutputStream;
|
||||||
|
import net.i2p.util.SimpleByteCache;
|
||||||
import net.i2p.util.SimpleScheduler;
|
import net.i2p.util.SimpleScheduler;
|
||||||
import net.i2p.util.SimpleTimer;
|
import net.i2p.util.SimpleTimer;
|
||||||
|
|
||||||
@ -257,7 +258,7 @@ public class Router {
|
|||||||
_killVMOnEnd = true;
|
_killVMOnEnd = true;
|
||||||
_oomListener = new I2PThread.OOMEventListener() {
|
_oomListener = new I2PThread.OOMEventListener() {
|
||||||
public void outOfMemory(OutOfMemoryError oom) {
|
public void outOfMemory(OutOfMemoryError oom) {
|
||||||
ByteCache.clearAll();
|
clearCaches();
|
||||||
_log.log(Log.CRIT, "Thread ran out of memory", oom);
|
_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
|
for (int i = 0; i < 5; i++) { // try this 5 times, in case it OOMs
|
||||||
try {
|
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
|
* 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.
|
* 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);
|
_log.log(Log.CRIT, "Error running shutdown task", t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_context.removeShutdownTasks();
|
||||||
// hard and ugly
|
// hard and ugly
|
||||||
if (System.getProperty("wrapper.version") != null)
|
if (System.getProperty("wrapper.version") != null)
|
||||||
_log.log(Log.CRIT, "Restarting with new router identity");
|
_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
|
// Run the shutdown hooks first in case they want to send some goodbye messages
|
||||||
// Maybe we need a delay after this too?
|
// Maybe we need a delay after this too?
|
||||||
for (Runnable task : _context.getShutdownTasks()) {
|
for (Runnable task : _context.getShutdownTasks()) {
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Running shutdown task " + task.getClass());
|
||||||
try {
|
try {
|
||||||
task.run();
|
task.run();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
_log.log(Log.CRIT, "Error running shutdown task", 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.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.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); }
|
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 static final boolean ALLOW_DYNAMIC_KEYS = false;
|
||||||
|
|
||||||
private void finalShutdown(int exitCode) {
|
private void finalShutdown(int exitCode) {
|
||||||
|
clearCaches();
|
||||||
_log.log(Log.CRIT, "Shutdown(" + exitCode + ") complete" /* , new Exception("Shutdown") */ );
|
_log.log(Log.CRIT, "Shutdown(" + exitCode + ") complete" /* , new Exception("Shutdown") */ );
|
||||||
try { _context.logManager().shutdown(); } catch (Throwable t) { }
|
try { _context.logManager().shutdown(); } catch (Throwable t) { }
|
||||||
if (ALLOW_DYNAMIC_KEYS) {
|
if (ALLOW_DYNAMIC_KEYS) {
|
||||||
@ -1486,7 +1498,7 @@ private static class CoalesceStatsEvent implements SimpleTimer.TimedEvent {
|
|||||||
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
||||||
getContext().statManager().addRateData("router.memoryUsed", used, 0);
|
getContext().statManager().addRateData("router.memoryUsed", used, 0);
|
||||||
if (_maxMemory - used < LOW_MEMORY_THRESHOLD)
|
if (_maxMemory - used < LOW_MEMORY_THRESHOLD)
|
||||||
ByteCache.clearAll();
|
clearCaches();
|
||||||
|
|
||||||
getContext().tunnelDispatcher().updateParticipatingStats(COALESCE_TIME);
|
getContext().tunnelDispatcher().updateParticipatingStats(COALESCE_TIME);
|
||||||
|
|
||||||
|
@ -402,6 +402,13 @@ public class RouterContext extends I2PAppContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.8.8
|
||||||
|
*/
|
||||||
|
void removeShutdownTasks() {
|
||||||
|
_shutdownTasks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this instead of context instanceof RouterContext
|
* Use this instead of context instanceof RouterContext
|
||||||
* @return true
|
* @return true
|
||||||
|
Reference in New Issue
Block a user