From bafef846d92e3b8518372d673477b6c96bd949de Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 22 Mar 2012 19:53:05 +0000 Subject: [PATCH] * SimpleScheduler, SimpleTimer, SimpleTimer2: Replace static instances with I2PAppContext-rooted references --- core/java/src/net/i2p/I2PAppContext.java | 65 ++++++++++++++++++- core/java/src/net/i2p/util/Executor.java | 3 + .../src/net/i2p/util/SimpleScheduler.java | 31 ++++++--- core/java/src/net/i2p/util/SimpleTimer.java | 41 ++++++++---- core/java/src/net/i2p/util/SimpleTimer2.java | 41 +++++++++--- history.txt | 8 +++ .../src/net/i2p/router/RouterVersion.java | 2 +- 7 files changed, 160 insertions(+), 31 deletions(-) diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java index a39da7785..313f6e445 100644 --- a/core/java/src/net/i2p/I2PAppContext.java +++ b/core/java/src/net/i2p/I2PAppContext.java @@ -37,6 +37,9 @@ import net.i2p.util.LogManager; import net.i2p.util.PortMapper; import net.i2p.util.RandomSource; import net.i2p.util.SecureDirectory; +import net.i2p.util.SimpleScheduler; +import net.i2p.util.SimpleTimer; +import net.i2p.util.SimpleTimer2; import net.i2p.util.I2PProperties.I2PPropertyCallback; /** @@ -86,6 +89,9 @@ public class I2PAppContext { private RandomSource _random; private KeyGenerator _keyGenerator; protected KeyRing _keyRing; // overridden in RouterContext + private SimpleScheduler _simpleScheduler; + private SimpleTimer _simpleTimer; + private SimpleTimer2 _simpleTimer2; private final PortMapper _portMapper; private volatile boolean _statManagerInitialized; private volatile boolean _sessionKeyManagerInitialized; @@ -103,6 +109,9 @@ public class I2PAppContext { private volatile boolean _randomInitialized; private volatile boolean _keyGeneratorInitialized; protected volatile boolean _keyRingInitialized; // used in RouterContext + private volatile boolean _simpleSchedulerInitialized; + private volatile boolean _simpleTimerInitialized; + private volatile boolean _simpleTimer2Initialized; protected final Set _shutdownTasks; private File _baseDir; private File _configDir; @@ -116,7 +125,7 @@ public class I2PAppContext { _lock5 = new Object(), _lock6 = new Object(), _lock7 = new Object(), _lock8 = new Object(), _lock9 = new Object(), _lock10 = new Object(), _lock11 = new Object(), _lock12 = new Object(), _lock13 = new Object(), _lock14 = new Object(), _lock15 = new Object(), _lock16 = new Object(), - _lock17 = new Object(); + _lock17 = new Object(), _lock18 = new Object(), _lock19 = new Object(), _lock20 = new Object(); /** * Pull the default context, creating a new one if necessary, else using @@ -921,4 +930,58 @@ public class I2PAppContext { public PortMapper portMapper() { return _portMapper; } + + /** + * Use instead of SimpleScheduler.getInstance() + * @since 0.9 to replace static instance in the class + */ + public SimpleScheduler simpleScheduler() { + if (!_simpleSchedulerInitialized) + initializeSimpleScheduler(); + return _simpleScheduler; + } + + private void initializeSimpleScheduler() { + synchronized (_lock18) { + if (_simpleScheduler == null) + _simpleScheduler = new SimpleScheduler(this); + _simpleSchedulerInitialized = true; + } + } + + /** + * Use instead of SimpleTimer.getInstance() + * @since 0.9 to replace static instance in the class + */ + public SimpleTimer simpleTimer() { + if (!_simpleTimerInitialized) + initializeSimpleTimer(); + return _simpleTimer; + } + + private void initializeSimpleTimer() { + synchronized (_lock19) { + if (_simpleTimer == null) + _simpleTimer = new SimpleTimer(this); + _simpleTimerInitialized = true; + } + } + + /** + * Use instead of SimpleTimer2.getInstance() + * @since 0.9 to replace static instance in the class + */ + public SimpleTimer2 simpleTimer2() { + if (!_simpleTimer2Initialized) + initializeSimpleTimer2(); + return _simpleTimer2; + } + + private void initializeSimpleTimer2() { + synchronized (_lock20) { + if (_simpleTimer2 == null) + _simpleTimer2 = new SimpleTimer2(this); + _simpleTimer2Initialized = true; + } + } } diff --git a/core/java/src/net/i2p/util/Executor.java b/core/java/src/net/i2p/util/Executor.java index 3c81d46f1..1bff87557 100644 --- a/core/java/src/net/i2p/util/Executor.java +++ b/core/java/src/net/i2p/util/Executor.java @@ -4,6 +4,9 @@ import java.util.List; import net.i2p.I2PAppContext; +/** + * Deprecated - used only by SimpleTimer + */ class Executor implements Runnable { private final I2PAppContext _context; private Log _log; diff --git a/core/java/src/net/i2p/util/SimpleScheduler.java b/core/java/src/net/i2p/util/SimpleScheduler.java index 728199e65..ee19a82ac 100644 --- a/core/java/src/net/i2p/util/SimpleScheduler.java +++ b/core/java/src/net/i2p/util/SimpleScheduler.java @@ -27,21 +27,36 @@ import net.i2p.I2PAppContext; * @author zzz */ public class SimpleScheduler { - private static final SimpleScheduler _instance = new SimpleScheduler(); - public static SimpleScheduler getInstance() { return _instance; } + + /** + * If you have a context, use context.simpleScheduler() instead + */ + public static SimpleScheduler getInstance() { + return I2PAppContext.getGlobalContext().simpleScheduler(); + } + private static final int MIN_THREADS = 2; private static final int MAX_THREADS = 4; - private final I2PAppContext _context; private final Log _log; private final ScheduledThreadPoolExecutor _executor; private final String _name; private int _count; private final int _threads; - protected SimpleScheduler() { this("SimpleScheduler"); } - protected SimpleScheduler(String name) { - _context = I2PAppContext.getGlobalContext(); - _log = _context.logManager().getLog(SimpleScheduler.class); + /** + * To be instantiated by the context. + * Others should use context.simpleTimer() instead + */ + public SimpleScheduler(I2PAppContext context) { + this(context, "SimpleScheduler"); + } + + /** + * To be instantiated by the context. + * Others should use context.simpleTimer() instead + */ + private SimpleScheduler(I2PAppContext context, String name) { + _log = context.logManager().getLog(SimpleScheduler.class); _name = name; long maxMemory = Runtime.getRuntime().maxMemory(); if (maxMemory == Long.MAX_VALUE) @@ -50,7 +65,7 @@ public class SimpleScheduler { _executor = new ScheduledThreadPoolExecutor(_threads, new CustomThreadFactory()); _executor.prestartAllCoreThreads(); // don't bother saving ref to remove hook if somebody else calls stop - _context.addShutdownTask(new Shutdown()); + context.addShutdownTask(new Shutdown()); } /** diff --git a/core/java/src/net/i2p/util/SimpleTimer.java b/core/java/src/net/i2p/util/SimpleTimer.java index ea6069f16..4582d4024 100644 --- a/core/java/src/net/i2p/util/SimpleTimer.java +++ b/core/java/src/net/i2p/util/SimpleTimer.java @@ -18,24 +18,39 @@ import net.i2p.I2PAppContext; * This is an inefficient mess. Use SimpleScheduler or SimpleTimer2 if possible. */ public class SimpleTimer { - private static final SimpleTimer _instance = new SimpleTimer(); - public static SimpleTimer getInstance() { return _instance; } - private final I2PAppContext _context; + + /** + * If you have a context, use context.simpleTimer() instead + */ + public static SimpleTimer getInstance() { + return I2PAppContext.getGlobalContext().simpleTimer(); + } + private final Log _log; /** event time (Long) to event (TimedEvent) mapping */ - private final TreeMap _events; + private final TreeMap _events; /** event (TimedEvent) to event time (Long) mapping */ - private Map _eventTimes; - private final List _readyEvents; + private final Map _eventTimes; + private final List _readyEvents; private SimpleStore runn; private static final int MIN_THREADS = 2; private static final int MAX_THREADS = 4; - protected SimpleTimer() { this("SimpleTimer"); } - protected SimpleTimer(String name) { + /** + * To be instantiated by the context. + * Others should use context.simpleTimer() instead + */ + public SimpleTimer(I2PAppContext context) { + this(context, "SimpleTimer"); + } + + /** + * To be instantiated by the context. + * Others should use context.simpleTimer() instead + */ + private SimpleTimer(I2PAppContext context, String name) { runn = new SimpleStore(true); - _context = I2PAppContext.getGlobalContext(); - _log = _context.logManager().getLog(SimpleTimer.class); + _log = context.logManager().getLog(SimpleTimer.class); _events = new TreeMap(); _eventTimes = new HashMap(256); _readyEvents = new ArrayList(4); @@ -48,12 +63,12 @@ public class SimpleTimer { maxMemory = 128*1024*1024l; int threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024)))); for (int i = 1; i <= threads ; i++) { - I2PThread executor = new I2PThread(new Executor(_context, _log, _readyEvents, runn)); + I2PThread executor = new I2PThread(new Executor(context, _log, _readyEvents, runn)); executor.setName(name + "Executor " + i + '/' + threads); executor.setDaemon(true); executor.start(); } - _context.addShutdownTask(new Shutdown()); + context.addShutdownTask(new Shutdown()); } /** @@ -192,7 +207,7 @@ public class SimpleTimer { // private TimedEvent _recentEvents[] = new TimedEvent[5]; private class SimpleTimerRunner implements Runnable { public void run() { - List eventsToFire = new ArrayList(1); + List eventsToFire = new ArrayList(1); while(runn.getAnswer()) { try { synchronized (_events) { diff --git a/core/java/src/net/i2p/util/SimpleTimer2.java b/core/java/src/net/i2p/util/SimpleTimer2.java index 8e2aee8a7..a49f0e9d2 100644 --- a/core/java/src/net/i2p/util/SimpleTimer2.java +++ b/core/java/src/net/i2p/util/SimpleTimer2.java @@ -26,19 +26,43 @@ import net.i2p.I2PAppContext; * @author zzz */ public class SimpleTimer2 { - private static final SimpleTimer2 _instance = new SimpleTimer2(); - public static SimpleTimer2 getInstance() { return _instance; } + + /** + * If you have a context, use context.simpleTimer2() instead + */ + public static SimpleTimer2 getInstance() { + return I2PAppContext.getGlobalContext().simpleTimer2(); + } + private static final int MIN_THREADS = 2; private static final int MAX_THREADS = 4; - private final I2PAppContext _context; private final ScheduledThreadPoolExecutor _executor; private final String _name; private int _count; private final int _threads; - protected SimpleTimer2() { this("SimpleTimer2"); } - protected SimpleTimer2(String name) { - _context = I2PAppContext.getGlobalContext(); + /** + * To be instantiated by the context. + * Others should use context.simpleTimer2() instead + */ + public SimpleTimer2(I2PAppContext context) { + this(context, "SimpleTimer2"); + } + + /** + * To be instantiated by the context. + * Others should use context.simpleTimer2() instead + */ + protected SimpleTimer2(I2PAppContext context, String name) { + this(context, name, true); + } + + /** + * To be instantiated by the context. + * Others should use context.simpleTimer2() instead + * @since 0.9 + */ + protected SimpleTimer2(I2PAppContext context, String name, boolean prestartAllThreads) { _name = name; _count = 0; long maxMemory = Runtime.getRuntime().maxMemory(); @@ -46,9 +70,10 @@ public class SimpleTimer2 { maxMemory = 96*1024*1024l; _threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024)))); _executor = new CustomScheduledThreadPoolExecutor(_threads, new CustomThreadFactory()); - _executor.prestartAllCoreThreads(); + if (prestartAllThreads) + _executor.prestartAllCoreThreads(); // don't bother saving ref to remove hook if somebody else calls stop - _context.addShutdownTask(new Shutdown()); + context.addShutdownTask(new Shutdown()); } /** diff --git a/history.txt b/history.txt index cf0023e13..8a51b9175 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,11 @@ +2012-03-22 zzz + * Home page: CSS tweaks + * Reseeder: Get rid of static instance, root in netDB, + don't use system properties for status + * Router: When removing a config setting, remove from context also + * SimpleScheduler, SimpleTimer, SimpleTimer2: Replace static instances + with I2PAppContext-rooted references + 2012-03-20 zzz * i2psnark: Message area tweaks and clear link * NetDB: diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 5b1ba79e3..f5c926454 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 19; + public final static long BUILD = 20; /** for example "-test" */ public final static String EXTRA = "";