From 5ba5887565be0c209acacba94aeb68fb5290ad6b Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Fri, 9 Dec 2011 22:20:32 +0000 Subject: [PATCH] Debugging Bluetooth threading issues. --- .../briar/api/plugins/BatchPluginFactory.java | 4 +- .../api/plugins/StreamPluginFactory.java | 4 +- .../sf/briar/plugins/PluginManagerImpl.java | 6 +-- .../net/sf/briar/plugins/PluginsModule.java | 6 +-- .../plugins/bluetooth/BluetoothPlugin.java | 40 +++++++++++-------- .../bluetooth/BluetoothPluginFactory.java | 5 +-- .../file/RemovableDrivePluginFactory.java | 5 +-- .../briar/plugins/socket/LanSocketPlugin.java | 4 +- .../plugins/socket/SimpleSocketPlugin.java | 4 +- .../socket/SimpleSocketPluginFactory.java | 5 +-- .../sf/briar/plugins/socket/SocketPlugin.java | 7 ++-- .../briar/plugins/PluginManagerImplTest.java | 4 +- .../bluetooth/BluetoothClientTest.java | 4 +- .../bluetooth/BluetoothServerTest.java | 4 +- .../plugins/socket/LanSocketClientTest.java | 4 +- .../plugins/socket/LanSocketServerTest.java | 4 +- .../socket/SimpleSocketPluginTest.java | 6 +-- 17 files changed, 59 insertions(+), 57 deletions(-) diff --git a/api/net/sf/briar/api/plugins/BatchPluginFactory.java b/api/net/sf/briar/api/plugins/BatchPluginFactory.java index 314497fd40..d0d1be9fbd 100644 --- a/api/net/sf/briar/api/plugins/BatchPluginFactory.java +++ b/api/net/sf/briar/api/plugins/BatchPluginFactory.java @@ -1,9 +1,9 @@ package net.sf.briar.api.plugins; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; public interface BatchPluginFactory { - BatchPlugin createPlugin(ScheduledExecutorService pluginExecutor, + BatchPlugin createPlugin(Executor pluginExecutor, BatchPluginCallback callback); } diff --git a/api/net/sf/briar/api/plugins/StreamPluginFactory.java b/api/net/sf/briar/api/plugins/StreamPluginFactory.java index 6dae0df700..7102305704 100644 --- a/api/net/sf/briar/api/plugins/StreamPluginFactory.java +++ b/api/net/sf/briar/api/plugins/StreamPluginFactory.java @@ -1,9 +1,9 @@ package net.sf.briar.api.plugins; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; public interface StreamPluginFactory { - StreamPlugin createPlugin(ScheduledExecutorService pluginExecutor, + StreamPlugin createPlugin(Executor pluginExecutor, StreamPluginCallback callback); } diff --git a/components/net/sf/briar/plugins/PluginManagerImpl.java b/components/net/sf/briar/plugins/PluginManagerImpl.java index 5d16299efb..bd4e198fe9 100644 --- a/components/net/sf/briar/plugins/PluginManagerImpl.java +++ b/components/net/sf/briar/plugins/PluginManagerImpl.java @@ -7,7 +7,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ExecutorService; import java.util.logging.Level; import java.util.logging.Logger; @@ -51,7 +51,7 @@ class PluginManagerImpl implements PluginManager { "net.sf.briar.plugins.socket.SimpleSocketPluginFactory" }; - private final ScheduledExecutorService pluginExecutor; + private final ExecutorService pluginExecutor; private final DatabaseComponent db; private final Poller poller; private final ConnectionDispatcher dispatcher; @@ -60,7 +60,7 @@ class PluginManagerImpl implements PluginManager { private final List<StreamPlugin> streamPlugins; // Locking: this @Inject - PluginManagerImpl(@PluginExecutor ScheduledExecutorService pluginExecutor, + PluginManagerImpl(@PluginExecutor ExecutorService pluginExecutor, DatabaseComponent db, Poller poller, ConnectionDispatcher dispatcher, UiCallback uiCallback) { this.pluginExecutor = pluginExecutor; diff --git a/components/net/sf/briar/plugins/PluginsModule.java b/components/net/sf/briar/plugins/PluginsModule.java index 1fcf8d3a9d..9ade114d13 100644 --- a/components/net/sf/briar/plugins/PluginsModule.java +++ b/components/net/sf/briar/plugins/PluginsModule.java @@ -1,7 +1,7 @@ package net.sf.briar.plugins; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginManager; @@ -13,9 +13,9 @@ public class PluginsModule extends AbstractModule { @Override protected void configure() { - bind(ScheduledExecutorService.class).annotatedWith( + bind(ExecutorService.class).annotatedWith( PluginExecutor.class).toInstance( - Executors.newScheduledThreadPool(1)); + Executors.newCachedThreadPool()); bind(PluginManager.class).to( PluginManagerImpl.class).in(Singleton.class); bind(Poller.class).to(PollerImpl.class); diff --git a/components/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java b/components/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java index 653119a80c..510035c964 100644 --- a/components/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java +++ b/components/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java @@ -4,10 +4,11 @@ import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Random; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -41,23 +42,25 @@ class BluetoothPlugin implements StreamPlugin { private static final Logger LOG = Logger.getLogger(BluetoothPlugin.class.getName()); - private final ScheduledExecutorService pluginExecutor; + private final Executor pluginExecutor; private final StreamPluginCallback callback; private final long pollingInterval; private final Object discoveryLock = new Object(); + private final ScheduledExecutorService scheduler; // Locking: this - private final Collection<StreamConnectionNotifier> invitationSockets; + private final Map<StreamConnectionNotifier, ScheduledFuture<?>> sockets; private boolean running = false; // Locking: this private LocalDevice localDevice = null; // Locking: this private StreamConnectionNotifier socket = null; // Locking: this - BluetoothPlugin(@PluginExecutor ScheduledExecutorService pluginExecutor, + BluetoothPlugin(@PluginExecutor Executor pluginExecutor, StreamPluginCallback callback, long pollingInterval) { this.pluginExecutor = pluginExecutor; this.callback = callback; this.pollingInterval = pollingInterval; - invitationSockets = new HashSet<StreamConnectionNotifier>(); + scheduler = Executors.newScheduledThreadPool(0); + sockets = new HashMap<StreamConnectionNotifier, ScheduledFuture<?>>(); } public TransportId getId() { @@ -173,8 +176,11 @@ class BluetoothPlugin implements StreamPlugin { public synchronized void stop() { running = false; localDevice = null; - for(StreamConnectionNotifier scn : invitationSockets) tryToClose(scn); - invitationSockets.clear(); + for(Entry<StreamConnectionNotifier, ScheduledFuture<?>> e + : sockets.entrySet()) { + if(e.getValue().cancel(false)) tryToClose(e.getKey()); + } + sockets.clear(); if(socket != null) { tryToClose(socket); socket = null; @@ -383,31 +389,31 @@ class BluetoothPlugin implements StreamPlugin { if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString()); return; } - synchronized(this) { - if(!running) { - tryToClose(scn); - return; - } - invitationSockets.add(scn); - } // Close the socket when the invitation times out Runnable close = new Runnable() { public void run() { synchronized(this) { - invitationSockets.remove(scn); + sockets.remove(scn); } tryToClose(scn); } }; - ScheduledFuture<?> future = pluginExecutor.schedule(close, + ScheduledFuture<?> future = scheduler.schedule(close, c.getTimeout(), TimeUnit.MILLISECONDS); + synchronized(this) { + if(!running) { + if(future.cancel(false)) tryToClose(scn); + return; + } + sockets.put(scn, future); + } // Try to accept a connection try { StreamConnection s = scn.acceptAndOpen(); // Close the socket and return the connection if(future.cancel(false)) { synchronized(this) { - invitationSockets.remove(scn); + sockets.remove(scn); } tryToClose(scn); } diff --git a/components/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java b/components/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java index 4c4a3a730e..a7a55fa1c3 100644 --- a/components/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java +++ b/components/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java @@ -1,6 +1,6 @@ package net.sf.briar.plugins.bluetooth; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.StreamPlugin; @@ -11,8 +11,7 @@ public class BluetoothPluginFactory implements StreamPluginFactory { private static final long POLLING_INTERVAL = 3L * 60L * 1000L; // 3 mins - public StreamPlugin createPlugin( - @PluginExecutor ScheduledExecutorService pluginExecutor, + public StreamPlugin createPlugin(@PluginExecutor Executor pluginExecutor, StreamPluginCallback callback) { return new BluetoothPlugin(pluginExecutor, callback, POLLING_INTERVAL); } diff --git a/components/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java b/components/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java index 1a0353a1e2..81f719c8dc 100644 --- a/components/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java +++ b/components/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java @@ -1,6 +1,6 @@ package net.sf.briar.plugins.file; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import net.sf.briar.api.plugins.BatchPlugin; import net.sf.briar.api.plugins.BatchPluginCallback; @@ -12,8 +12,7 @@ public class RemovableDrivePluginFactory implements BatchPluginFactory { private static final long POLLING_INTERVAL = 10L * 1000L; // 10 seconds - public BatchPlugin createPlugin( - @PluginExecutor ScheduledExecutorService pluginExecutor, + public BatchPlugin createPlugin(@PluginExecutor Executor pluginExecutor, BatchPluginCallback callback) { RemovableDriveFinder finder; RemovableDriveMonitor monitor; diff --git a/components/net/sf/briar/plugins/socket/LanSocketPlugin.java b/components/net/sf/briar/plugins/socket/LanSocketPlugin.java index 0de1417a9b..9e5c3742c1 100644 --- a/components/net/sf/briar/plugins/socket/LanSocketPlugin.java +++ b/components/net/sf/briar/plugins/socket/LanSocketPlugin.java @@ -10,7 +10,7 @@ import java.net.Socket; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.Random; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import java.util.logging.Level; import java.util.logging.Logger; @@ -25,7 +25,7 @@ class LanSocketPlugin extends SimpleSocketPlugin { private static final Logger LOG = Logger.getLogger(LanSocketPlugin.class.getName()); - LanSocketPlugin(@PluginExecutor ScheduledExecutorService pluginExecutor, + LanSocketPlugin(@PluginExecutor Executor pluginExecutor, StreamPluginCallback callback, long pollingInterval) { super(pluginExecutor, callback, pollingInterval); } diff --git a/components/net/sf/briar/plugins/socket/SimpleSocketPlugin.java b/components/net/sf/briar/plugins/socket/SimpleSocketPlugin.java index 332f7e82ab..1a6bb99eb1 100644 --- a/components/net/sf/briar/plugins/socket/SimpleSocketPlugin.java +++ b/components/net/sf/briar/plugins/socket/SimpleSocketPlugin.java @@ -9,7 +9,7 @@ import java.net.Socket; import java.net.SocketAddress; import java.util.Collections; import java.util.List; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import java.util.logging.Level; import java.util.logging.Logger; @@ -31,7 +31,7 @@ class SimpleSocketPlugin extends SocketPlugin { private static final Logger LOG = Logger.getLogger(SimpleSocketPlugin.class.getName()); - SimpleSocketPlugin(@PluginExecutor ScheduledExecutorService pluginExecutor, + SimpleSocketPlugin(@PluginExecutor Executor pluginExecutor, StreamPluginCallback callback, long pollingInterval) { super(pluginExecutor, callback, pollingInterval); } diff --git a/components/net/sf/briar/plugins/socket/SimpleSocketPluginFactory.java b/components/net/sf/briar/plugins/socket/SimpleSocketPluginFactory.java index 6e7fc5e5f4..a34e21ead8 100644 --- a/components/net/sf/briar/plugins/socket/SimpleSocketPluginFactory.java +++ b/components/net/sf/briar/plugins/socket/SimpleSocketPluginFactory.java @@ -1,6 +1,6 @@ package net.sf.briar.plugins.socket; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.StreamPlugin; @@ -11,8 +11,7 @@ public class SimpleSocketPluginFactory implements StreamPluginFactory { private static final long POLLING_INTERVAL = 5L * 60L * 1000L; // 5 mins - public StreamPlugin createPlugin( - @PluginExecutor ScheduledExecutorService pluginExecutor, + public StreamPlugin createPlugin(@PluginExecutor Executor pluginExecutor, StreamPluginCallback callback) { return new SimpleSocketPlugin(pluginExecutor, callback, POLLING_INTERVAL); diff --git a/components/net/sf/briar/plugins/socket/SocketPlugin.java b/components/net/sf/briar/plugins/socket/SocketPlugin.java index 7f2a5557d2..c5001ef85f 100644 --- a/components/net/sf/briar/plugins/socket/SocketPlugin.java +++ b/components/net/sf/briar/plugins/socket/SocketPlugin.java @@ -6,7 +6,7 @@ import java.net.Socket; import java.net.SocketAddress; import java.util.Collection; import java.util.Map; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import java.util.logging.Level; import java.util.logging.Logger; @@ -22,7 +22,7 @@ abstract class SocketPlugin implements StreamPlugin { private static final Logger LOG = Logger.getLogger(SocketPlugin.class.getName()); - protected final ScheduledExecutorService pluginExecutor; + protected final Executor pluginExecutor; protected final StreamPluginCallback callback; private final long pollingInterval; @@ -37,8 +37,7 @@ abstract class SocketPlugin implements StreamPlugin { protected abstract SocketAddress getLocalSocketAddress(); protected abstract SocketAddress getRemoteSocketAddress(ContactId c); - protected SocketPlugin( - @PluginExecutor ScheduledExecutorService pluginExecutor, + protected SocketPlugin(@PluginExecutor Executor pluginExecutor, StreamPluginCallback callback, long pollingInterval) { this.pluginExecutor = pluginExecutor; this.callback = callback; diff --git a/test/net/sf/briar/plugins/PluginManagerImplTest.java b/test/net/sf/briar/plugins/PluginManagerImplTest.java index 37c50e3966..861eb6593b 100644 --- a/test/net/sf/briar/plugins/PluginManagerImplTest.java +++ b/test/net/sf/briar/plugins/PluginManagerImplTest.java @@ -1,8 +1,8 @@ package net.sf.briar.plugins; import java.util.Collection; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicInteger; import net.sf.briar.BriarTestCase; @@ -43,7 +43,7 @@ public class PluginManagerImplTest extends BriarTestCase { with(any(TransportProperties.class))); oneOf(poller).stop(); }}); - ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + ExecutorService executor = Executors.newCachedThreadPool(); PluginManagerImpl p = new PluginManagerImpl(executor, db, poller, dispatcher, uiCallback); // We expect either 2 or 3 plugins to be started, depending on whether diff --git a/test/net/sf/briar/plugins/bluetooth/BluetoothClientTest.java b/test/net/sf/briar/plugins/bluetooth/BluetoothClientTest.java index 234c6f850e..e1acd2dae5 100644 --- a/test/net/sf/briar/plugins/bluetooth/BluetoothClientTest.java +++ b/test/net/sf/briar/plugins/bluetooth/BluetoothClientTest.java @@ -3,7 +3,7 @@ package net.sf.briar.plugins.bluetooth; import java.util.Collections; import java.util.Map; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import net.sf.briar.api.ContactId; import net.sf.briar.api.TransportConfig; @@ -24,7 +24,7 @@ public class BluetoothClientTest extends StreamClientTest { // Create the plugin callback = new ClientCallback(new TransportConfig(), new TransportProperties(), remote); - ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + Executor executor = Executors.newCachedThreadPool(); plugin = new BluetoothPlugin(executor, callback, 0L); } diff --git a/test/net/sf/briar/plugins/bluetooth/BluetoothServerTest.java b/test/net/sf/briar/plugins/bluetooth/BluetoothServerTest.java index 6b73adf3be..81d28cad27 100644 --- a/test/net/sf/briar/plugins/bluetooth/BluetoothServerTest.java +++ b/test/net/sf/briar/plugins/bluetooth/BluetoothServerTest.java @@ -2,7 +2,7 @@ package net.sf.briar.plugins.bluetooth; import java.util.Collections; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import net.sf.briar.api.TransportConfig; import net.sf.briar.api.TransportProperties; @@ -19,7 +19,7 @@ public class BluetoothServerTest extends StreamServerTest { // Create the plugin callback = new ServerCallback(new TransportConfig(), local, Collections.singletonMap(contactId, new TransportProperties())); - ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + Executor executor = Executors.newCachedThreadPool(); plugin = new BluetoothPlugin(executor, callback, 0L); } diff --git a/test/net/sf/briar/plugins/socket/LanSocketClientTest.java b/test/net/sf/briar/plugins/socket/LanSocketClientTest.java index a093f30e30..bc99d5ae6b 100644 --- a/test/net/sf/briar/plugins/socket/LanSocketClientTest.java +++ b/test/net/sf/briar/plugins/socket/LanSocketClientTest.java @@ -3,7 +3,7 @@ package net.sf.briar.plugins.socket; import java.util.Collections; import java.util.Map; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import net.sf.briar.api.ContactId; import net.sf.briar.api.TransportConfig; @@ -24,7 +24,7 @@ public class LanSocketClientTest extends StreamClientTest { // Create the plugin callback = new ClientCallback(new TransportConfig(), new TransportProperties(), remote); - ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + Executor executor = Executors.newCachedThreadPool(); plugin = new LanSocketPlugin(executor, callback, 0L); } diff --git a/test/net/sf/briar/plugins/socket/LanSocketServerTest.java b/test/net/sf/briar/plugins/socket/LanSocketServerTest.java index d46544cc4b..b969600b10 100644 --- a/test/net/sf/briar/plugins/socket/LanSocketServerTest.java +++ b/test/net/sf/briar/plugins/socket/LanSocketServerTest.java @@ -2,7 +2,7 @@ package net.sf.briar.plugins.socket; import java.util.Collections; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import net.sf.briar.api.TransportConfig; import net.sf.briar.api.TransportProperties; @@ -16,7 +16,7 @@ public class LanSocketServerTest extends StreamServerTest { callback = new ServerCallback(new TransportConfig(), new TransportProperties(), Collections.singletonMap(contactId, new TransportProperties())); - ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + Executor executor = Executors.newCachedThreadPool(); plugin = new LanSocketPlugin(executor, callback, 0L); } diff --git a/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java b/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java index 4387b93556..c1b9ded937 100644 --- a/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java +++ b/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java @@ -8,7 +8,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -30,7 +30,7 @@ public class SimpleSocketPluginTest extends BriarTestCase { StreamCallback callback = new StreamCallback(); callback.local.put("internal", "127.0.0.1"); callback.local.put("port", "0"); - ScheduledExecutorService e = Executors.newScheduledThreadPool(1); + Executor e = Executors.newCachedThreadPool(); SimpleSocketPlugin plugin = new SimpleSocketPlugin(e, callback, 0L); plugin.start(); // The plugin should have bound a socket and stored the port number @@ -64,7 +64,7 @@ public class SimpleSocketPluginTest extends BriarTestCase { @Test public void testOutgoingConnection() throws Exception { StreamCallback callback = new StreamCallback(); - ScheduledExecutorService e = Executors.newScheduledThreadPool(1); + Executor e = Executors.newCachedThreadPool(); SimpleSocketPlugin plugin = new SimpleSocketPlugin(e, callback, 0L); plugin.start(); // Listen on a local port -- GitLab