forked from I2P_Developers/i2p.i2p
* Shutdown:
- Implement and call shutdown for RouterWatchdog - Fix i2psnark DirMonitor not stopping - Fix UPnP-Disposer not stopping quickly - Implement and call YKGenerator and DHSessionKeyBuilder shutdown
This commit is contained in:
@ -48,14 +48,14 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
private final Object _addSnarkLock;
|
||||
private /* FIXME final FIXME */ File _configFile;
|
||||
private Properties _config;
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private final I2PAppContext _context;
|
||||
private final Log _log;
|
||||
private final List _messages;
|
||||
private I2PSnarkUtil _util;
|
||||
private final I2PSnarkUtil _util;
|
||||
private PeerCoordinatorSet _peerCoordinatorSet;
|
||||
private ConnectionAcceptor _connectionAcceptor;
|
||||
private Thread _monitor;
|
||||
private boolean _running;
|
||||
private volatile boolean _running;
|
||||
|
||||
public static final String PROP_I2CP_HOST = "i2psnark.i2cpHost";
|
||||
public static final String PROP_I2CP_PORT = "i2psnark.i2cpPort";
|
||||
@ -1089,7 +1089,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
// although the user will see the default until then
|
||||
getBWLimit();
|
||||
boolean doMagnets = true;
|
||||
while (true) {
|
||||
while (_running) {
|
||||
File dir = getDataDir();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Directory Monitor loop over " + dir.getAbsolutePath());
|
||||
|
@ -53,7 +53,8 @@ public class DHSessionKeyBuilder {
|
||||
private static final int MAX_NUM_BUILDERS;
|
||||
private static final int CALC_DELAY;
|
||||
private static final LinkedBlockingQueue<DHSessionKeyBuilder> _builders;
|
||||
private static final Thread _precalcThread;
|
||||
private static Thread _precalcThread;
|
||||
private static volatile boolean _isRunning;
|
||||
|
||||
// the data of importance
|
||||
private BigInteger _myPrivateValue;
|
||||
@ -96,13 +97,42 @@ public class DHSessionKeyBuilder {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("DH Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: "
|
||||
+ CALC_DELAY + ")");
|
||||
startPrecalc();
|
||||
}
|
||||
|
||||
_precalcThread = new I2PThread(new DHSessionKeyBuilderPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS));
|
||||
_precalcThread.setName("DH Precalc");
|
||||
_precalcThread.setDaemon(true);
|
||||
/** @since 0.8.8 */
|
||||
private static void startPrecalc() {
|
||||
synchronized(DHSessionKeyBuilder.class) {
|
||||
_precalcThread = new I2PThread(new DHSessionKeyBuilderPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS),
|
||||
"DH Precalc", true);
|
||||
_precalcThread.setPriority(Thread.MIN_PRIORITY);
|
||||
_isRunning = true;
|
||||
_precalcThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that this stops the singleton precalc thread.
|
||||
* You don't want to do this if there are multiple routers in the JVM.
|
||||
* Fix this if you care. See Router.shutdown().
|
||||
* @since 0.8.8
|
||||
*/
|
||||
public static void shutdown() {
|
||||
_isRunning = false;
|
||||
_precalcThread.interrupt();
|
||||
_builders.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Only required if shutdown() previously called.
|
||||
* @since 0.8.8
|
||||
*/
|
||||
public static void restart() {
|
||||
synchronized(DHSessionKeyBuilder.class) {
|
||||
if (!_isRunning)
|
||||
startPrecalc();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new DH key builder
|
||||
|
@ -78,6 +78,24 @@ public class ElGamalEngine {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Note that this stops the singleton precalc thread.
|
||||
* You don't want to do this if there are multiple routers in the JVM.
|
||||
* Fix this if you care. See Router.shutdown().
|
||||
* @since 0.8.8
|
||||
*/
|
||||
public void shutdown() {
|
||||
YKGenerator.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Only required if shutdown() previously called.
|
||||
* @since 0.8.8
|
||||
*/
|
||||
public static void restart() {
|
||||
YKGenerator.restart();
|
||||
}
|
||||
|
||||
private final static BigInteger _two = new NativeBigInteger(1, new byte[] { 0x02});
|
||||
|
||||
private BigInteger[] getNextYK() {
|
||||
|
@ -42,8 +42,9 @@ class YKGenerator {
|
||||
private static final int MAX_NUM_BUILDERS;
|
||||
private static final int CALC_DELAY;
|
||||
private static final LinkedBlockingQueue<BigInteger[]> _values;
|
||||
private static final Thread _precalcThread;
|
||||
private static Thread _precalcThread;
|
||||
private static final I2PAppContext ctx;
|
||||
private static volatile boolean _isRunning;
|
||||
|
||||
public final static String PROP_YK_PRECALC_MIN = "crypto.yk.precalc.min";
|
||||
public final static String PROP_YK_PRECALC_MAX = "crypto.yk.precalc.max";
|
||||
@ -77,13 +78,42 @@ class YKGenerator {
|
||||
|
||||
ctx.statManager().createRateStat("crypto.YKUsed", "Need a YK from the queue", "Encryption", new long[] { 60*60*1000 });
|
||||
ctx.statManager().createRateStat("crypto.YKEmpty", "YK queue empty", "Encryption", new long[] { 60*60*1000 });
|
||||
startPrecalc();
|
||||
}
|
||||
|
||||
_precalcThread = new I2PThread(new YKPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS));
|
||||
_precalcThread.setName("YK Precalc");
|
||||
_precalcThread.setDaemon(true);
|
||||
/** @since 0.8.8 */
|
||||
private static void startPrecalc() {
|
||||
synchronized(YKGenerator.class) {
|
||||
_precalcThread = new I2PThread(new YKPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS),
|
||||
"YK Precalc", true);
|
||||
_precalcThread.setPriority(Thread.MIN_PRIORITY);
|
||||
_isRunning = true;
|
||||
_precalcThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that this stops the singleton precalc thread.
|
||||
* You don't want to do this if there are multiple routers in the JVM.
|
||||
* Fix this if you care. See Router.shutdown().
|
||||
* @since 0.8.8
|
||||
*/
|
||||
public static void shutdown() {
|
||||
_isRunning = false;
|
||||
_precalcThread.interrupt();
|
||||
_values.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Only required if shutdown() previously called.
|
||||
* @since 0.8.8
|
||||
*/
|
||||
public static void restart() {
|
||||
synchronized(YKGenerator.class) {
|
||||
if (!_isRunning)
|
||||
startPrecalc();
|
||||
}
|
||||
}
|
||||
|
||||
private static final int getSize() {
|
||||
return _values.size();
|
||||
@ -161,7 +191,7 @@ class YKGenerator {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
while (_isRunning) {
|
||||
int curSize = 0;
|
||||
//long start = Clock.getInstance().now();
|
||||
int startSize = getSize();
|
||||
@ -172,7 +202,7 @@ class YKGenerator {
|
||||
_checkDelay += 1000;
|
||||
curSize = startSize;
|
||||
if (curSize < _minSize) {
|
||||
for (int i = curSize; i < _maxSize; i++) {
|
||||
for (int i = curSize; i < _maxSize && _isRunning; i++) {
|
||||
//long begin = Clock.getInstance().now();
|
||||
if (!addValues(generateYK()))
|
||||
break;
|
||||
|
@ -75,6 +75,8 @@ public class Router {
|
||||
private I2PThread.OOMEventListener _oomListener;
|
||||
private ShutdownHook _shutdownHook;
|
||||
private final I2PThread _gracefulShutdownDetector;
|
||||
private final RouterWatchdog _watchdog;
|
||||
private final Thread _watchdogThread;
|
||||
|
||||
public final static String PROP_CONFIG_FILE = "router.configLocation";
|
||||
|
||||
@ -277,8 +279,9 @@ public class Router {
|
||||
_gracefulShutdownDetector = new I2PAppThread(new GracefulShutdown(), "Graceful shutdown hook", true);
|
||||
_gracefulShutdownDetector.start();
|
||||
|
||||
Thread watchdog = new I2PAppThread(new RouterWatchdog(_context), "RouterWatchdog", true);
|
||||
watchdog.start();
|
||||
_watchdog = new RouterWatchdog(_context);
|
||||
_watchdogThread = new I2PAppThread(_watchdog, "RouterWatchdog", true);
|
||||
_watchdogThread.start();
|
||||
|
||||
}
|
||||
|
||||
@ -643,7 +646,10 @@ public class Router {
|
||||
|
||||
private void warmupCrypto() {
|
||||
_context.random().nextBoolean();
|
||||
new DHSessionKeyBuilder(); // load the class so it starts the precalc process
|
||||
// Use restart() to refire the static refiller threads, in case
|
||||
// we are restarting the router in the same JVM (Android)
|
||||
DHSessionKeyBuilder.restart();
|
||||
_context.elGamalEngine().restart();
|
||||
}
|
||||
|
||||
private void startupQueue() {
|
||||
@ -977,11 +983,23 @@ public class Router {
|
||||
RouterContext.listContexts().remove(_context);
|
||||
|
||||
// shut down I2PAppContext tasks here
|
||||
|
||||
// TODO if there are multiple routers in the JVM, we don't want to do this
|
||||
// to the DH or YK tasks, as they are singletons.
|
||||
// Have MultiRouter set a property or something.
|
||||
try {
|
||||
DHSessionKeyBuilder.shutdown();
|
||||
} catch (Throwable t) { _log.log(Log.CRIT, "Error shutting DH", t); }
|
||||
try {
|
||||
_context.elGamalEngine().shutdown();
|
||||
} catch (Throwable t) { _log.log(Log.CRIT, "Error shutting elGamal", t); }
|
||||
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();
|
||||
finalShutdown(exitCode);
|
||||
}
|
||||
|
||||
|
@ -15,12 +15,19 @@ class RouterWatchdog implements Runnable {
|
||||
private final Log _log;
|
||||
private final RouterContext _context;
|
||||
private int _consecutiveErrors;
|
||||
private volatile boolean _isRunning;
|
||||
|
||||
private static final long MAX_JOB_RUN_LAG = 60*1000;
|
||||
|
||||
public RouterWatchdog(RouterContext ctx) {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(RouterWatchdog.class);
|
||||
_isRunning = true;
|
||||
}
|
||||
|
||||
/** @since 0.8.8 */
|
||||
public void shutdown() {
|
||||
_isRunning = false;
|
||||
}
|
||||
|
||||
public boolean verifyJobQueueLiveliness() {
|
||||
@ -109,7 +116,7 @@ class RouterWatchdog implements Runnable {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
while (_isRunning) {
|
||||
try { Thread.sleep(60*1000); } catch (InterruptedException ie) {}
|
||||
monitorRouter();
|
||||
}
|
||||
|
@ -65,6 +65,8 @@ public class ThreadCore implements Runnable
|
||||
//threadObject.destroy();
|
||||
//threadObject.stop();
|
||||
setThreadObject(null);
|
||||
// I2P break Disposer out of sleep()
|
||||
threadObject.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user