* Shutdown:

- Kill the global app context
    - Recognize multi-router case
    - Fix RandomIterator, YKGenerator, DHBuilder, NTCPConnection
      hanging on to old context -
      probably other offenders not yet found
    - Fix DHBuilder thread not stopping
This commit is contained in:
zzz
2011-06-17 18:37:02 +00:00
parent df793193aa
commit 9ad8f35bca
10 changed files with 101 additions and 39 deletions

View File

@ -115,6 +115,10 @@ public class I2PAppContext {
* Pull the default context, creating a new one if necessary, else using
* the first one created.
*
* Warning - do not save the returned value, or the value of any methods below,
* in a static field, or you will get the old context if a new router is
* started in the same JVM after the first is shut down,
* e.g. on Android.
*/
public static I2PAppContext getGlobalContext() {
// skip the global lock - _gAC must be volatile
@ -165,8 +169,12 @@ public class I2PAppContext {
private I2PAppContext(boolean doInit, Properties envProps) {
if (doInit) {
synchronized (I2PAppContext.class) {
if (_globalAppContext == null)
if (_globalAppContext == null) {
_globalAppContext = this;
} else {
System.out.println("Warning - New context not replacing old one, you now have a second one");
(new Exception("I did it")).printStackTrace();
}
}
}
_overrideProps = new I2PProperties();
@ -186,7 +194,7 @@ public class I2PAppContext {
_elGamalAESEngineInitialized = false;
_logManagerInitialized = false;
_keyRingInitialized = false;
_shutdownTasks = new ConcurrentHashSet(16);
_shutdownTasks = new ConcurrentHashSet(32);
initializeDirs();
}

View File

@ -47,8 +47,8 @@ import net.i2p.util.RandomSource;
* @author jrandom
*/
public class DHSessionKeyBuilder {
private static final I2PAppContext _context = I2PAppContext.getGlobalContext();
private static final Log _log;
private static I2PAppContext _context = I2PAppContext.getGlobalContext();
private static Log _log;
private static final int MIN_NUM_BUILDERS;
private static final int MAX_NUM_BUILDERS;
private static final int CALC_DELAY;
@ -100,15 +100,18 @@ public class DHSessionKeyBuilder {
startPrecalc();
}
/** @since 0.8.8 */
/**
* Caller must synch on class
* @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();
}
_context = I2PAppContext.getGlobalContext();
_log = _context.logManager().getLog(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();
}
/**
@ -505,7 +508,7 @@ public class DHSessionKeyBuilder {
}
public void run() {
while (true) {
while (_isRunning) {
int curSize = 0;
long start = System.currentTimeMillis();

View File

@ -43,7 +43,7 @@ class YKGenerator {
private static final int CALC_DELAY;
private static final LinkedBlockingQueue<BigInteger[]> _values;
private static Thread _precalcThread;
private static final I2PAppContext ctx;
private static I2PAppContext ctx;
private static volatile boolean _isRunning;
public final static String PROP_YK_PRECALC_MIN = "crypto.yk.precalc.min";
@ -76,20 +76,22 @@ class YKGenerator {
// _log.debug("ElGamal YK Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: "
// + CALC_DELAY + ")");
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();
}
/** @since 0.8.8 */
/**
* Caller must synch on class
* @since 0.8.8
*/
private static void startPrecalc() {
synchronized(YKGenerator.class) {
_precalcThread = new I2PThread(new YKPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS),
ctx = I2PAppContext.getGlobalContext();
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 });
_precalcThread = new I2PThread(new YKPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS),
"YK Precalc", true);
_precalcThread.setPriority(Thread.MIN_PRIORITY);
_isRunning = true;
_precalcThread.start();
}
_precalcThread.setPriority(Thread.MIN_PRIORITY);
_isRunning = true;
_precalcThread.start();
}
/**