diff --git a/components/net/sf/briar/lifecycle/ShutdownManagerImpl.java b/components/net/sf/briar/lifecycle/ShutdownManagerImpl.java index 001f8a3f0a4a2cbf03770e1360d99e59ff7fc7b7..fa6eb7833fdb04f31be15f71bcc75be30ad7275c 100644 --- a/components/net/sf/briar/lifecycle/ShutdownManagerImpl.java +++ b/components/net/sf/briar/lifecycle/ShutdownManagerImpl.java @@ -15,14 +15,18 @@ class ShutdownManagerImpl implements ShutdownManager { hooks = new HashMap<Integer, Thread>(); } - public synchronized int addShutdownHook(Runnable runnable) { + public synchronized int addShutdownHook(Runnable r) { int handle = nextHandle++; - Thread hook = new Thread(runnable); + Thread hook = createThread(r); hooks.put(handle, hook); Runtime.getRuntime().addShutdownHook(hook); return handle; } + protected Thread createThread(Runnable r) { + return new Thread(r); + } + public synchronized boolean removeShutdownHook(int handle) { Thread hook = hooks.remove(handle); if(hook == null) return false; diff --git a/components/net/sf/briar/lifecycle/WindowsShutdownManagerImpl.java b/components/net/sf/briar/lifecycle/WindowsShutdownManagerImpl.java index 9395206c0de4e8e2c1cad36a297e17378f5ce8d8..7fd9ec3914b1f611f7815e5fd8247cbcecd414f5 100644 --- a/components/net/sf/briar/lifecycle/WindowsShutdownManagerImpl.java +++ b/components/net/sf/briar/lifecycle/WindowsShutdownManagerImpl.java @@ -45,9 +45,14 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl { } @Override - public synchronized int addShutdownHook(Runnable runnable) { + public synchronized int addShutdownHook(Runnable r) { if(!initialised) initialise(); - return super.addShutdownHook(new RunOnce(runnable)); + return super.addShutdownHook(r); + } + + @Override + protected Thread createThread(Runnable r) { + return new StartOnce(r); } // Locking: this @@ -122,19 +127,18 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl { } } - private static class RunOnce implements Runnable { + private static class StartOnce extends Thread { - private final Runnable runnable; private final AtomicBoolean called = new AtomicBoolean(false); - private RunOnce(Runnable runnable) { - this.runnable = runnable; + private StartOnce(Runnable r) { + super(r); } - public void run() { - // Ensure the runnable only runs once - if(called.getAndSet(true)) return; - runnable.run(); + @Override + public void start() { + // Ensure the thread is only started once + if(!called.getAndSet(true)) super.start(); } }