diff --git a/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java b/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java index b227943116e713cd5a277e7ad2699583b3149a7d..3abfa4cbc3ac732a2cff9c66bf5c2f9395580350 100644 --- a/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java +++ b/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java @@ -53,20 +53,20 @@ class LifecycleManagerImpl implements LifecycleManager { @Override public void registerService(Service s) { if (LOG.isLoggable(INFO)) - LOG.info("Registering service " + s.getClass().getName()); + LOG.info("Registering service " + s.getClass().getSimpleName()); services.add(s); } @Override public void registerClient(Client c) { if (LOG.isLoggable(INFO)) - LOG.info("Registering client " + c.getClass().getName()); + LOG.info("Registering client " + c.getClass().getSimpleName()); clients.add(c); } @Override public void registerForShutdown(ExecutorService e) { - LOG.info("Registering executor"); + LOG.info("Registering executor " + e.getClass().getSimpleName()); executors.add(e); } @@ -94,7 +94,8 @@ class LifecycleManagerImpl implements LifecycleManager { c.createLocalState(txn); duration = System.currentTimeMillis() - start; if (LOG.isLoggable(INFO)) { - LOG.info("Starting client " + c.getClass().getName() + LOG.info("Starting client " + + c.getClass().getSimpleName() + " took " + duration + " ms"); } } @@ -107,7 +108,7 @@ class LifecycleManagerImpl implements LifecycleManager { s.startService(); duration = System.currentTimeMillis() - start; if (LOG.isLoggable(INFO)) { - LOG.info("Starting service " + s.getClass().getName() + LOG.info("Starting service " + s.getClass().getSimpleName() + " took " + duration + " ms"); } } @@ -140,13 +141,17 @@ class LifecycleManagerImpl implements LifecycleManager { s.stopService(); long duration = System.currentTimeMillis() - start; if (LOG.isLoggable(INFO)) { - LOG.info("Stopping service " + s.getClass().getName() + LOG.info("Stopping service " + s.getClass().getSimpleName() + " took " + duration + " ms"); } } - for (ExecutorService e : executors) e.shutdownNow(); - if (LOG.isLoggable(INFO)) - LOG.info(executors.size() + " executors shut down"); + for (ExecutorService e : executors) { + if (LOG.isLoggable(INFO)) { + LOG.info("Stopping executor " + + e.getClass().getSimpleName()); + } + e.shutdownNow(); + } long start = System.currentTimeMillis(); db.close(); long duration = System.currentTimeMillis() - start; diff --git a/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java b/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java index 852fe3dc95221301df59daa30654a2d1b03931a2..e8b9b129d79120db7198b0dbcdad851d838d22bb 100644 --- a/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java +++ b/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java @@ -62,6 +62,7 @@ class PluginManagerImpl implements PluginManager, Service { private final Map<TransportId, Plugin> plugins; private final List<SimplexPlugin> simplexPlugins; private final List<DuplexPlugin> duplexPlugins; + private final Map<TransportId, CountDownLatch> startLatches; private final AtomicBoolean used = new AtomicBoolean(false); @Inject @@ -80,69 +81,64 @@ class PluginManagerImpl implements PluginManager, Service { plugins = new ConcurrentHashMap<TransportId, Plugin>(); simplexPlugins = new CopyOnWriteArrayList<SimplexPlugin>(); duplexPlugins = new CopyOnWriteArrayList<DuplexPlugin>(); + startLatches = new ConcurrentHashMap<TransportId, CountDownLatch>(); } @Override public void startService() throws ServiceException { if (used.getAndSet(true)) throw new IllegalStateException(); - Collection<SimplexPluginFactory> simplexFactories = - pluginConfig.getSimplexFactories(); - Collection<DuplexPluginFactory> duplexFactories = - pluginConfig.getDuplexFactories(); - int numPlugins = simplexFactories.size() + duplexFactories.size(); - CountDownLatch latch = new CountDownLatch(numPlugins); - // Instantiate and start the simplex plugins + // Instantiate the simplex plugins and start them asynchronously LOG.info("Starting simplex plugins"); - for (SimplexPluginFactory f : simplexFactories) { + for (SimplexPluginFactory f : pluginConfig.getSimplexFactories()) { TransportId t = f.getId(); SimplexPlugin s = f.createPlugin(new SimplexCallback(t)); if (s == null) { if (LOG.isLoggable(WARNING)) LOG.warning("Could not create plugin for " + t); - latch.countDown(); } else { plugins.put(t, s); simplexPlugins.add(s); - ioExecutor.execute(new PluginStarter(s, latch)); + CountDownLatch startLatch = new CountDownLatch(1); + startLatches.put(t, startLatch); + ioExecutor.execute(new PluginStarter(s, startLatch)); } } - // Instantiate and start the duplex plugins + // Instantiate the duplex plugins and start them asynchronously LOG.info("Starting duplex plugins"); - for (DuplexPluginFactory f : duplexFactories) { + for (DuplexPluginFactory f : pluginConfig.getDuplexFactories()) { TransportId t = f.getId(); DuplexPlugin d = f.createPlugin(new DuplexCallback(t)); if (d == null) { if (LOG.isLoggable(WARNING)) LOG.warning("Could not create plugin for " + t); - latch.countDown(); } else { plugins.put(t, d); duplexPlugins.add(d); - ioExecutor.execute(new PluginStarter(d, latch)); + CountDownLatch startLatch = new CountDownLatch(1); + startLatches.put(t, startLatch); + ioExecutor.execute(new PluginStarter(d, startLatch)); } } - // Wait for all the plugins to start - try { - latch.await(); - } catch (InterruptedException e) { - throw new ServiceException(e); - } } @Override public void stopService() throws ServiceException { - CountDownLatch latch = new CountDownLatch(plugins.size()); + CountDownLatch stopLatch = new CountDownLatch(plugins.size()); // Stop the simplex plugins LOG.info("Stopping simplex plugins"); - for (SimplexPlugin plugin : simplexPlugins) - ioExecutor.execute(new PluginStopper(plugin, latch)); + for (SimplexPlugin s : simplexPlugins) { + CountDownLatch startLatch = startLatches.get(s.getId()); + ioExecutor.execute(new PluginStopper(s, startLatch, stopLatch)); + } // Stop the duplex plugins LOG.info("Stopping duplex plugins"); - for (DuplexPlugin plugin : duplexPlugins) - ioExecutor.execute(new PluginStopper(plugin, latch)); + for (DuplexPlugin d : duplexPlugins) { + CountDownLatch startLatch = startLatches.get(d.getId()); + ioExecutor.execute(new PluginStopper(d, startLatch, stopLatch)); + } // Wait for all the plugins to stop try { - latch.await(); + stopLatch.await(); } catch (InterruptedException e) { throw new ServiceException(e); } @@ -182,11 +178,11 @@ class PluginManagerImpl implements PluginManager, Service { private class PluginStarter implements Runnable { private final Plugin plugin; - private final CountDownLatch latch; + private final CountDownLatch startLatch; - private PluginStarter(Plugin plugin, CountDownLatch latch) { + private PluginStarter(Plugin plugin, CountDownLatch startLatch) { this.plugin = plugin; - this.latch = latch; + this.startLatch = startLatch; } @Override @@ -212,7 +208,7 @@ class PluginManagerImpl implements PluginManager, Service { LOG.log(WARNING, e.toString(), e); } } finally { - latch.countDown(); + startLatch.countDown(); } } } @@ -220,16 +216,21 @@ class PluginManagerImpl implements PluginManager, Service { private class PluginStopper implements Runnable { private final Plugin plugin; - private final CountDownLatch latch; + private final CountDownLatch startLatch, stopLatch; - private PluginStopper(Plugin plugin, CountDownLatch latch) { + private PluginStopper(Plugin plugin, CountDownLatch startLatch, + CountDownLatch stopLatch) { this.plugin = plugin; - this.latch = latch; + this.startLatch = startLatch; + this.stopLatch = stopLatch; } @Override public void run() { try { + // Wait for the plugin to finish starting + startLatch.await(); + // Stop the plugin long start = System.currentTimeMillis(); plugin.stop(); long duration = System.currentTimeMillis() - start; @@ -237,10 +238,13 @@ class PluginManagerImpl implements PluginManager, Service { LOG.info("Stopping plugin " + plugin.getId() + " took " + duration + " ms"); } + } catch (InterruptedException e) { + LOG.warning("Interrupted while waiting for plugin to start"); + // This task runs on an executor, so don't reset the interrupt } catch (IOException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); } finally { - latch.countDown(); + stopLatch.countDown(); } } }