* SimpleScheduler, SimpleTimer, SimpleTimer2: Replace static instances

with I2PAppContext-rooted references
This commit is contained in:
zzz
2012-03-22 19:53:05 +00:00
parent db42a46c71
commit bafef846d9
7 changed files with 160 additions and 31 deletions

View File

@ -37,6 +37,9 @@ import net.i2p.util.LogManager;
import net.i2p.util.PortMapper; import net.i2p.util.PortMapper;
import net.i2p.util.RandomSource; import net.i2p.util.RandomSource;
import net.i2p.util.SecureDirectory; 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; import net.i2p.util.I2PProperties.I2PPropertyCallback;
/** /**
@ -86,6 +89,9 @@ public class I2PAppContext {
private RandomSource _random; private RandomSource _random;
private KeyGenerator _keyGenerator; private KeyGenerator _keyGenerator;
protected KeyRing _keyRing; // overridden in RouterContext protected KeyRing _keyRing; // overridden in RouterContext
private SimpleScheduler _simpleScheduler;
private SimpleTimer _simpleTimer;
private SimpleTimer2 _simpleTimer2;
private final PortMapper _portMapper; private final PortMapper _portMapper;
private volatile boolean _statManagerInitialized; private volatile boolean _statManagerInitialized;
private volatile boolean _sessionKeyManagerInitialized; private volatile boolean _sessionKeyManagerInitialized;
@ -103,6 +109,9 @@ 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 volatile boolean _simpleSchedulerInitialized;
private volatile boolean _simpleTimerInitialized;
private volatile boolean _simpleTimer2Initialized;
protected final Set<Runnable> _shutdownTasks; protected final Set<Runnable> _shutdownTasks;
private File _baseDir; private File _baseDir;
private File _configDir; private File _configDir;
@ -116,7 +125,7 @@ public class I2PAppContext {
_lock5 = new Object(), _lock6 = new Object(), _lock7 = new Object(), _lock8 = new Object(), _lock5 = new Object(), _lock6 = new Object(), _lock7 = new Object(), _lock8 = new Object(),
_lock9 = new Object(), _lock10 = new Object(), _lock11 = new Object(), _lock12 = 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(), _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 * Pull the default context, creating a new one if necessary, else using
@ -921,4 +930,58 @@ public class I2PAppContext {
public PortMapper portMapper() { public PortMapper portMapper() {
return _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;
}
}
} }

View File

@ -4,6 +4,9 @@ import java.util.List;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
/**
* Deprecated - used only by SimpleTimer
*/
class Executor implements Runnable { class Executor implements Runnable {
private final I2PAppContext _context; private final I2PAppContext _context;
private Log _log; private Log _log;

View File

@ -27,21 +27,36 @@ import net.i2p.I2PAppContext;
* @author zzz * @author zzz
*/ */
public class SimpleScheduler { 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 MIN_THREADS = 2;
private static final int MAX_THREADS = 4; private static final int MAX_THREADS = 4;
private final I2PAppContext _context;
private final Log _log; private final Log _log;
private final ScheduledThreadPoolExecutor _executor; private final ScheduledThreadPoolExecutor _executor;
private final String _name; private final String _name;
private int _count; private int _count;
private final int _threads; private final int _threads;
protected SimpleScheduler() { this("SimpleScheduler"); } /**
protected SimpleScheduler(String name) { * To be instantiated by the context.
_context = I2PAppContext.getGlobalContext(); * Others should use context.simpleTimer() instead
_log = _context.logManager().getLog(SimpleScheduler.class); */
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; _name = name;
long maxMemory = Runtime.getRuntime().maxMemory(); long maxMemory = Runtime.getRuntime().maxMemory();
if (maxMemory == Long.MAX_VALUE) if (maxMemory == Long.MAX_VALUE)
@ -50,7 +65,7 @@ public class SimpleScheduler {
_executor = new ScheduledThreadPoolExecutor(_threads, new CustomThreadFactory()); _executor = new ScheduledThreadPoolExecutor(_threads, new CustomThreadFactory());
_executor.prestartAllCoreThreads(); _executor.prestartAllCoreThreads();
// don't bother saving ref to remove hook if somebody else calls stop // don't bother saving ref to remove hook if somebody else calls stop
_context.addShutdownTask(new Shutdown()); context.addShutdownTask(new Shutdown());
} }
/** /**

View File

@ -18,24 +18,39 @@ import net.i2p.I2PAppContext;
* This is an inefficient mess. Use SimpleScheduler or SimpleTimer2 if possible. * This is an inefficient mess. Use SimpleScheduler or SimpleTimer2 if possible.
*/ */
public class SimpleTimer { 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; private final Log _log;
/** event time (Long) to event (TimedEvent) mapping */ /** event time (Long) to event (TimedEvent) mapping */
private final TreeMap _events; private final TreeMap<Long, TimedEvent> _events;
/** event (TimedEvent) to event time (Long) mapping */ /** event (TimedEvent) to event time (Long) mapping */
private Map _eventTimes; private final Map<TimedEvent, Long> _eventTimes;
private final List _readyEvents; private final List<TimedEvent> _readyEvents;
private SimpleStore runn; private SimpleStore runn;
private static final int MIN_THREADS = 2; private static final int MIN_THREADS = 2;
private static final int MAX_THREADS = 4; 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); runn = new SimpleStore(true);
_context = I2PAppContext.getGlobalContext(); _log = context.logManager().getLog(SimpleTimer.class);
_log = _context.logManager().getLog(SimpleTimer.class);
_events = new TreeMap(); _events = new TreeMap();
_eventTimes = new HashMap(256); _eventTimes = new HashMap(256);
_readyEvents = new ArrayList(4); _readyEvents = new ArrayList(4);
@ -48,12 +63,12 @@ public class SimpleTimer {
maxMemory = 128*1024*1024l; maxMemory = 128*1024*1024l;
int threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024)))); int threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
for (int i = 1; i <= threads ; i++) { 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.setName(name + "Executor " + i + '/' + threads);
executor.setDaemon(true); executor.setDaemon(true);
executor.start(); executor.start();
} }
_context.addShutdownTask(new Shutdown()); context.addShutdownTask(new Shutdown());
} }
/** /**
@ -192,7 +207,7 @@ public class SimpleTimer {
// private TimedEvent _recentEvents[] = new TimedEvent[5]; // private TimedEvent _recentEvents[] = new TimedEvent[5];
private class SimpleTimerRunner implements Runnable { private class SimpleTimerRunner implements Runnable {
public void run() { public void run() {
List eventsToFire = new ArrayList(1); List<TimedEvent> eventsToFire = new ArrayList(1);
while(runn.getAnswer()) { while(runn.getAnswer()) {
try { try {
synchronized (_events) { synchronized (_events) {

View File

@ -26,19 +26,43 @@ import net.i2p.I2PAppContext;
* @author zzz * @author zzz
*/ */
public class SimpleTimer2 { 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 MIN_THREADS = 2;
private static final int MAX_THREADS = 4; private static final int MAX_THREADS = 4;
private final I2PAppContext _context;
private final ScheduledThreadPoolExecutor _executor; private final ScheduledThreadPoolExecutor _executor;
private final String _name; private final String _name;
private int _count; private int _count;
private final int _threads; private final int _threads;
protected SimpleTimer2() { this("SimpleTimer2"); } /**
protected SimpleTimer2(String name) { * To be instantiated by the context.
_context = I2PAppContext.getGlobalContext(); * 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; _name = name;
_count = 0; _count = 0;
long maxMemory = Runtime.getRuntime().maxMemory(); long maxMemory = Runtime.getRuntime().maxMemory();
@ -46,9 +70,10 @@ public class SimpleTimer2 {
maxMemory = 96*1024*1024l; maxMemory = 96*1024*1024l;
_threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024)))); _threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
_executor = new CustomScheduledThreadPoolExecutor(_threads, new CustomThreadFactory()); _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 // don't bother saving ref to remove hook if somebody else calls stop
_context.addShutdownTask(new Shutdown()); context.addShutdownTask(new Shutdown());
} }
/** /**

View File

@ -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 2012-03-20 zzz
* i2psnark: Message area tweaks and clear link * i2psnark: Message area tweaks and clear link
* NetDB: * NetDB:

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 19; public final static long BUILD = 20;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";