Util: Fix leak of SimpleTimer2 shutdown task

This commit is contained in:
zzz
2022-01-21 09:09:32 -05:00
parent 5e7a00ede4
commit 77e30e246d
2 changed files with 27 additions and 3 deletions

View File

@@ -906,6 +906,13 @@ public class I2PAppContext {
public void addShutdownTask(Runnable task) {
_shutdownTasks.add(task);
}
/**
* @since 0.9.53
*/
public void removeShutdownTask(Runnable task) {
_shutdownTasks.remove(task);
}
/**
* @return an unmodifiable Set

View File

@@ -41,6 +41,8 @@ public class SimpleTimer2 {
private final String _name;
private final AtomicInteger _count = new AtomicInteger();
private final int _threads;
private final I2PAppContext _context;
private final Runnable _shutdown;
/**
* To be instantiated by the context.
@@ -64,14 +66,15 @@ public class SimpleTimer2 {
* @since 0.9
*/
protected SimpleTimer2(I2PAppContext context, String name, boolean prestartAllThreads) {
_context = context;
_name = name;
long maxMemory = SystemVersion.getMaxMemory();
_threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
_executor = new CustomScheduledThreadPoolExecutor(_threads, new CustomThreadFactory());
if (prestartAllThreads)
_executor.prestartAllCoreThreads();
// don't bother saving ref to remove hook if somebody else calls stop
context.addShutdownTask(new Shutdown());
_shutdown = new Shutdown();
context.addShutdownTask(_shutdown);
}
/**
@@ -79,7 +82,7 @@ public class SimpleTimer2 {
*/
private class Shutdown implements Runnable {
public void run() {
stop();
stop(false);
}
}
@@ -89,6 +92,20 @@ public class SimpleTimer2 {
* Cannot be restarted.
*/
public void stop() {
stop(true);
}
/**
* Stops the SimpleTimer.
* Subsequent executions should not throw a RejectedExecutionException.
* Cannot be restarted.
*
* @param removeTask true to unregister the shutdown hook
* @since 0.9.53
*/
private void stop(boolean removeTask) {
if (removeTask)
_context.removeShutdownTask(_shutdown);
_executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
_executor.shutdownNow();
}