Always call the callback outside the plugin's lock.

This commit is contained in:
akwizgran
2011-10-08 13:13:28 +01:00
parent 50e5c51d77
commit 125ae1b640
5 changed files with 38 additions and 64 deletions

View File

@@ -16,10 +16,7 @@ public interface TransportPlugin {
Map<ContactId, Map<String, String>> remoteProperties,
Map<String, String> config) throws IOException;
/**
* Stops the plugin. No further connections will be passed to the callback
* after this method has returned.
*/
/** Stops the plugin. */
void stop() throws IOException;
/** Updates the plugin's local transport properties. */

View File

@@ -54,13 +54,15 @@ class BluetoothPlugin extends AbstractPlugin implements StreamTransportPlugin {
}
@Override
public synchronized void start(Map<String, String> localProperties,
public void start(Map<String, String> localProperties,
Map<ContactId, Map<String, String>> remoteProperties,
Map<String, String> config) throws IOException {
super.start(localProperties, remoteProperties, config);
// Initialise the Bluetooth stack
try {
localDevice = LocalDevice.getLocalDevice();
synchronized(this) {
super.start(localProperties, remoteProperties, config);
localDevice = LocalDevice.getLocalDevice();
}
} catch(UnsatisfiedLinkError e) {
// On Linux the user may need to install libbluetooth-dev
if(OsUtils.isLinux())
@@ -89,14 +91,16 @@ class BluetoothPlugin extends AbstractPlugin implements StreamTransportPlugin {
private void bind() {
String uuid;
LocalDevice ld;
synchronized(this) {
if(!started) return;
uuid = config.get("uuid");
if(uuid == null) uuid = createAndSetUuid();
ld = localDevice;
}
if(uuid == null) uuid = createAndSetUuid();
// Try to make the device discoverable (requires root on Linux)
try {
localDevice.setDiscoverable(DiscoveryAgent.GIAC);
ld.setDiscoverable(DiscoveryAgent.GIAC);
} catch(BluetoothStateException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
}
@@ -120,17 +124,20 @@ class BluetoothPlugin extends AbstractPlugin implements StreamTransportPlugin {
return;
}
streamConnectionNotifier = scn;
setLocalBluetoothAddress(localDevice.getBluetoothAddress());
startListener();
}
setLocalBluetoothAddress(ld.getBluetoothAddress());
}
private String createAndSetUuid() {
assert started;
byte[] b = new byte[16];
new Random().nextBytes(b); // FIXME: Use a SecureRandom?
String uuid = StringUtils.toHexString(b);
Map<String, String> m = new TreeMap<String, String>(config);
Map<String, String> m;
synchronized(this) {
if(!started) return uuid;
m = new TreeMap<String, String>(config);
}
m.put("uuid", uuid);
callback.setConfig(m);
return uuid;
@@ -160,26 +167,18 @@ class BluetoothPlugin extends AbstractPlugin implements StreamTransportPlugin {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
return;
}
synchronized(this) {
if(!started) {
try {
s.close();
} catch(IOException e) {
if(LOG.isLoggable(Level.WARNING))
LOG.warning(e.getMessage());
}
return;
}
BluetoothTransportConnection conn =
new BluetoothTransportConnection(s);
callback.incomingConnectionCreated(conn);
}
BluetoothTransportConnection conn =
new BluetoothTransportConnection(s);
callback.incomingConnectionCreated(conn);
}
}
private void setLocalBluetoothAddress(String address) {
assert started;
Map<String, String> m = new TreeMap<String, String>(localProperties);
Map<String, String> m;
synchronized(this) {
if(!started) return;
m = new TreeMap<String, String>(localProperties);
}
m.put("address", address);
callback.setLocalProperties(m);
}
@@ -211,11 +210,7 @@ class BluetoothPlugin extends AbstractPlugin implements StreamTransportPlugin {
ContactId c = e.getKey();
String url = e.getValue();
StreamTransportConnection conn = createConnection(c, url);
if(conn != null) {
synchronized(this) {
if(started) callback.outgoingConnectionCreated(c, conn);
}
}
if(conn != null) callback.outgoingConnectionCreated(c, conn);
}
}

View File

@@ -93,15 +93,10 @@ implements BatchTransportPlugin {
if(f.length() < TransportConstants.MIN_CONNECTION_LENGTH) return;
try {
FileInputStream in = new FileInputStream(f);
synchronized(FilePlugin.this) {
if(started) {
callback.readerCreated(new FileTransportReader(f, in,
FilePlugin.this));
}
}
callback.readerCreated(new FileTransportReader(f, in,
FilePlugin.this));
} catch(IOException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
return;
}
}
}

View File

@@ -69,14 +69,17 @@ class SimpleSocketPlugin extends SocketPlugin {
@Override
protected void setLocalSocketAddress(SocketAddress s) {
assert started;
Map<String, String> m;
synchronized(this) {
if(!started) return;
m = new TreeMap<String, String>(localProperties);
}
if(!(s instanceof InetSocketAddress))
throw new IllegalArgumentException();
InetSocketAddress i = (InetSocketAddress) s;
String host = i.getAddress().getHostAddress();
String port = String.valueOf(i.getPort());
// FIXME: Special handling for private IP addresses?
Map<String, String> m = new TreeMap<String, String>(localProperties);
m.put("host", host);
m.put("port", port);
callback.setLocalProperties(m);

View File

@@ -26,10 +26,11 @@ implements StreamTransportPlugin {
// This field should be accessed with this's lock held
protected ServerSocket socket = null;
protected abstract void setLocalSocketAddress(SocketAddress s);
// These methods should be called with this's lock held and started == true
protected abstract SocketAddress getLocalSocketAddress();
protected abstract SocketAddress getSocketAddress(ContactId c);
protected abstract void setLocalSocketAddress(SocketAddress s);
protected abstract Socket createClientSocket() throws IOException;
protected abstract ServerSocket createServerSocket() throws IOException;
@@ -104,8 +105,7 @@ implements StreamTransportPlugin {
ServerSocket ss;
Socket s;
synchronized(this) {
if(!started) return;
if(socket == null) return;
if(!started || socket == null) return;
ss = socket;
}
try {
@@ -114,20 +114,8 @@ implements StreamTransportPlugin {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
return;
}
synchronized(this) {
if(!started) {
try {
s.close();
} catch(IOException e) {
if(LOG.isLoggable(Level.WARNING))
LOG.warning(e.getMessage());
}
return;
}
SocketTransportConnection conn =
new SocketTransportConnection(s);
callback.incomingConnectionCreated(conn);
}
SocketTransportConnection conn = new SocketTransportConnection(s);
callback.incomingConnectionCreated(conn);
}
}
@@ -179,11 +167,7 @@ implements StreamTransportPlugin {
private void connectAndCallBack(ContactId c) {
StreamTransportConnection conn = createConnection(c);
if(conn != null) {
synchronized(this) {
if(started) callback.outgoingConnectionCreated(c, conn);
}
}
if(conn != null) callback.outgoingConnectionCreated(c, conn);
}
public StreamTransportConnection createConnection(ContactId c) {