Fixed Bluetooth shutdown issues.

This commit is contained in:
akwizgran
2011-12-09 23:01:32 +00:00
parent 5ba5887565
commit e47d4990c3
8 changed files with 58 additions and 37 deletions

View File

@@ -4,9 +4,11 @@ import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Random; import java.util.Random;
import java.util.Set;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
@@ -47,8 +49,7 @@ class BluetoothPlugin implements StreamPlugin {
private final long pollingInterval; private final long pollingInterval;
private final Object discoveryLock = new Object(); private final Object discoveryLock = new Object();
private final ScheduledExecutorService scheduler; private final ScheduledExecutorService scheduler;
// Locking: this private final Set<StreamConnectionNotifier> sockets; // Locking: this
private final Map<StreamConnectionNotifier, ScheduledFuture<?>> sockets;
private boolean running = false; // Locking: this private boolean running = false; // Locking: this
private LocalDevice localDevice = null; // Locking: this private LocalDevice localDevice = null; // Locking: this
@@ -60,7 +61,7 @@ class BluetoothPlugin implements StreamPlugin {
this.callback = callback; this.callback = callback;
this.pollingInterval = pollingInterval; this.pollingInterval = pollingInterval;
scheduler = Executors.newScheduledThreadPool(0); scheduler = Executors.newScheduledThreadPool(0);
sockets = new HashMap<StreamConnectionNotifier, ScheduledFuture<?>>(); sockets = new HashSet<StreamConnectionNotifier>();
} }
public TransportId getId() { public TransportId getId() {
@@ -176,10 +177,8 @@ class BluetoothPlugin implements StreamPlugin {
public synchronized void stop() { public synchronized void stop() {
running = false; running = false;
localDevice = null; localDevice = null;
for(Entry<StreamConnectionNotifier, ScheduledFuture<?>> e scheduler.shutdownNow();
: sockets.entrySet()) { for(StreamConnectionNotifier scn : sockets) tryToClose(scn);
if(e.getValue().cancel(false)) tryToClose(e.getKey());
}
sockets.clear(); sockets.clear();
if(socket != null) { if(socket != null) {
tryToClose(socket); tryToClose(socket);
@@ -389,6 +388,13 @@ class BluetoothPlugin implements StreamPlugin {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString()); if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
return; return;
} }
synchronized(this) {
if(!running) {
tryToClose(scn);
return;
}
sockets.add(scn);
}
// Close the socket when the invitation times out // Close the socket when the invitation times out
Runnable close = new Runnable() { Runnable close = new Runnable() {
public void run() { public void run() {
@@ -400,13 +406,6 @@ class BluetoothPlugin implements StreamPlugin {
}; };
ScheduledFuture<?> future = scheduler.schedule(close, ScheduledFuture<?> future = scheduler.schedule(close,
c.getTimeout(), TimeUnit.MILLISECONDS); 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 to accept a connection
try { try {
StreamConnection s = scn.acceptAndOpen(); StreamConnection s = scn.acceptAndOpen();

View File

@@ -11,6 +11,8 @@ import net.sf.briar.api.transport.StreamTransportConnection;
public abstract class StreamClientTest extends StreamTest { public abstract class StreamClientTest extends StreamTest {
protected ClientCallback callback = null;
protected void run() throws IOException { protected void run() throws IOException {
assert plugin != null; assert plugin != null;
// Start the plugin // Start the plugin

View File

@@ -1,6 +1,7 @@
package net.sf.briar.plugins; package net.sf.briar.plugins;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CountDownLatch;
import net.sf.briar.api.ContactId; import net.sf.briar.api.ContactId;
import net.sf.briar.api.TransportConfig; import net.sf.briar.api.TransportConfig;
@@ -10,6 +11,8 @@ import net.sf.briar.api.transport.StreamTransportConnection;
public abstract class StreamServerTest extends StreamTest { public abstract class StreamServerTest extends StreamTest {
protected ServerCallback callback = null;
protected void run() throws Exception { protected void run() throws Exception {
assert callback != null; assert callback != null;
assert plugin != null; assert plugin != null;
@@ -18,9 +21,7 @@ public abstract class StreamServerTest extends StreamTest {
plugin.start(); plugin.start();
// Wait for a connection // Wait for a connection
System.out.println("Waiting for connection"); System.out.println("Waiting for connection");
synchronized(callback) { callback.latch.await();
callback.wait();
}
// Try to accept an invitation // Try to accept an invitation
System.out.println("Accepting invitation"); System.out.println("Accepting invitation");
StreamTransportConnection s = plugin.acceptInvitation(123, StreamTransportConnection s = plugin.acceptInvitation(123,
@@ -47,6 +48,8 @@ public abstract class StreamServerTest extends StreamTest {
protected class ServerCallback implements StreamPluginCallback { protected class ServerCallback implements StreamPluginCallback {
private final CountDownLatch latch = new CountDownLatch(1);
private TransportConfig config; private TransportConfig config;
private TransportProperties local; private TransportProperties local;
private Map<ContactId, TransportProperties> remote; private Map<ContactId, TransportProperties> remote;
@@ -91,9 +94,7 @@ public abstract class StreamServerTest extends StreamTest {
public void incomingConnectionCreated(StreamTransportConnection s) { public void incomingConnectionCreated(StreamTransportConnection s) {
System.out.println("Connection received"); System.out.println("Connection received");
sendChallengeReceiveResponse(s); sendChallengeReceiveResponse(s);
synchronized(this) { latch.countDown();
notifyAll();
}
} }
public void outgoingConnectionCreated(ContactId contactId, public void outgoingConnectionCreated(ContactId contactId,

View File

@@ -6,7 +6,6 @@ import java.util.Scanner;
import net.sf.briar.api.ContactId; import net.sf.briar.api.ContactId;
import net.sf.briar.api.plugins.StreamPlugin; import net.sf.briar.api.plugins.StreamPlugin;
import net.sf.briar.api.plugins.StreamPluginCallback;
import net.sf.briar.api.transport.StreamTransportConnection; import net.sf.briar.api.transport.StreamTransportConnection;
abstract class StreamTest { abstract class StreamTest {
@@ -17,7 +16,6 @@ abstract class StreamTest {
protected final ContactId contactId = new ContactId(0); protected final ContactId contactId = new ContactId(0);
protected StreamPluginCallback callback = null;
protected StreamPlugin plugin = null; protected StreamPlugin plugin = null;
protected void sendChallengeReceiveResponse(StreamTransportConnection s) { protected void sendChallengeReceiveResponse(StreamTransportConnection s) {

View File

@@ -2,8 +2,9 @@ package net.sf.briar.plugins.bluetooth;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import net.sf.briar.api.ContactId; import net.sf.briar.api.ContactId;
import net.sf.briar.api.TransportConfig; import net.sf.briar.api.TransportConfig;
@@ -14,7 +15,7 @@ import net.sf.briar.plugins.StreamClientTest;
// is running on another machine // is running on another machine
public class BluetoothClientTest extends StreamClientTest { public class BluetoothClientTest extends StreamClientTest {
private BluetoothClientTest(String serverAddress) { private BluetoothClientTest(Executor executor, String serverAddress) {
// Store the server's Bluetooth address and UUID // Store the server's Bluetooth address and UUID
TransportProperties p = new TransportProperties(); TransportProperties p = new TransportProperties();
p.put("address", serverAddress); p.put("address", serverAddress);
@@ -24,7 +25,6 @@ public class BluetoothClientTest extends StreamClientTest {
// Create the plugin // Create the plugin
callback = new ClientCallback(new TransportConfig(), callback = new ClientCallback(new TransportConfig(),
new TransportProperties(), remote); new TransportProperties(), remote);
Executor executor = Executors.newCachedThreadPool();
plugin = new BluetoothPlugin(executor, callback, 0L); plugin = new BluetoothPlugin(executor, callback, 0L);
} }
@@ -33,6 +33,11 @@ public class BluetoothClientTest extends StreamClientTest {
System.err.println("Please specify the server's Bluetooth address"); System.err.println("Please specify the server's Bluetooth address");
System.exit(1); System.exit(1);
} }
new BluetoothClientTest(args[0]).run(); ExecutorService executor = Executors.newCachedThreadPool();
try {
new BluetoothClientTest(executor, args[0]).run();
} finally {
executor.shutdown();
}
} }
} }

View File

@@ -1,8 +1,9 @@
package net.sf.briar.plugins.bluetooth; package net.sf.briar.plugins.bluetooth;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.Executors;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import net.sf.briar.api.TransportConfig; import net.sf.briar.api.TransportConfig;
import net.sf.briar.api.TransportProperties; import net.sf.briar.api.TransportProperties;
@@ -12,18 +13,22 @@ import net.sf.briar.plugins.StreamServerTest;
// is running on another machine // is running on another machine
public class BluetoothServerTest extends StreamServerTest { public class BluetoothServerTest extends StreamServerTest {
private BluetoothServerTest() { private BluetoothServerTest(Executor executor) {
// Store the UUID // Store the UUID
TransportProperties local = new TransportProperties(); TransportProperties local = new TransportProperties();
local.put("uuid", BluetoothTest.UUID); local.put("uuid", BluetoothTest.UUID);
// Create the plugin // Create the plugin
callback = new ServerCallback(new TransportConfig(), local, callback = new ServerCallback(new TransportConfig(), local,
Collections.singletonMap(contactId, new TransportProperties())); Collections.singletonMap(contactId, new TransportProperties()));
Executor executor = Executors.newCachedThreadPool();
plugin = new BluetoothPlugin(executor, callback, 0L); plugin = new BluetoothPlugin(executor, callback, 0L);
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
new BluetoothServerTest().run(); ExecutorService executor = Executors.newCachedThreadPool();
try {
new BluetoothServerTest(executor).run();
} finally {
executor.shutdown();
}
} }
} }

View File

@@ -2,6 +2,7 @@ package net.sf.briar.plugins.socket;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -14,7 +15,8 @@ import net.sf.briar.plugins.StreamClientTest;
// is running on another machine // is running on another machine
public class LanSocketClientTest extends StreamClientTest { public class LanSocketClientTest extends StreamClientTest {
private LanSocketClientTest(String serverAddress, String serverPort) { private LanSocketClientTest(Executor executor, String serverAddress,
String serverPort) {
// Store the server's internal address and port // Store the server's internal address and port
TransportProperties p = new TransportProperties(); TransportProperties p = new TransportProperties();
p.put("internal", serverAddress); p.put("internal", serverAddress);
@@ -24,7 +26,6 @@ public class LanSocketClientTest extends StreamClientTest {
// Create the plugin // Create the plugin
callback = new ClientCallback(new TransportConfig(), callback = new ClientCallback(new TransportConfig(),
new TransportProperties(), remote); new TransportProperties(), remote);
Executor executor = Executors.newCachedThreadPool();
plugin = new LanSocketPlugin(executor, callback, 0L); plugin = new LanSocketPlugin(executor, callback, 0L);
} }
@@ -33,6 +34,11 @@ public class LanSocketClientTest extends StreamClientTest {
System.err.println("Please specify the server's address and port"); System.err.println("Please specify the server's address and port");
System.exit(1); System.exit(1);
} }
new LanSocketClientTest(args[0], args[1]).run(); ExecutorService executor = Executors.newCachedThreadPool();
try {
new LanSocketClientTest(executor, args[0], args[1]).run();
} finally {
executor.shutdown();
}
} }
} }

View File

@@ -1,8 +1,9 @@
package net.sf.briar.plugins.socket; package net.sf.briar.plugins.socket;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.Executors;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import net.sf.briar.api.TransportConfig; import net.sf.briar.api.TransportConfig;
import net.sf.briar.api.TransportProperties; import net.sf.briar.api.TransportProperties;
@@ -12,15 +13,19 @@ import net.sf.briar.plugins.StreamServerTest;
// is running on another machine // is running on another machine
public class LanSocketServerTest extends StreamServerTest { public class LanSocketServerTest extends StreamServerTest {
private LanSocketServerTest() { private LanSocketServerTest(Executor executor) {
callback = new ServerCallback(new TransportConfig(), callback = new ServerCallback(new TransportConfig(),
new TransportProperties(), new TransportProperties(),
Collections.singletonMap(contactId, new TransportProperties())); Collections.singletonMap(contactId, new TransportProperties()));
Executor executor = Executors.newCachedThreadPool();
plugin = new LanSocketPlugin(executor, callback, 0L); plugin = new LanSocketPlugin(executor, callback, 0L);
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
new LanSocketServerTest().run(); ExecutorService executor = Executors.newCachedThreadPool();
try {
new LanSocketServerTest(executor).run();
} finally {
executor.shutdown();
}
} }
} }