Close the invitation socket early if a connection is received.

This commit is contained in:
akwizgran
2011-12-09 21:36:53 +00:00
parent 8af7e72943
commit 4671b50b37

View File

@@ -1,10 +1,10 @@
package net.sf.briar.plugins.bluetooth; package net.sf.briar.plugins.bluetooth;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
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;
@@ -45,7 +45,8 @@ class BluetoothPlugin implements StreamPlugin {
private final StreamPluginCallback callback; private final StreamPluginCallback callback;
private final long pollingInterval; private final long pollingInterval;
private final Object discoveryLock = new Object(); private final Object discoveryLock = new Object();
private final Collection<ScheduledFuture<?>> socketClosers; // Locking: this // Locking: this
private final Collection<StreamConnectionNotifier> invitationSockets;
private boolean running = false; // Locking: this private boolean running = false; // Locking: this
private LocalDevice localDevice = null; // Locking: this private LocalDevice localDevice = null; // Locking: this
@@ -56,7 +57,7 @@ class BluetoothPlugin implements StreamPlugin {
this.pluginExecutor = pluginExecutor; this.pluginExecutor = pluginExecutor;
this.callback = callback; this.callback = callback;
this.pollingInterval = pollingInterval; this.pollingInterval = pollingInterval;
socketClosers = new ArrayList<ScheduledFuture<?>>(); invitationSockets = new HashSet<StreamConnectionNotifier>();
} }
public TransportId getId() { public TransportId getId() {
@@ -169,12 +170,13 @@ class BluetoothPlugin implements StreamPlugin {
} }
} }
public synchronized void stop() throws IOException { public synchronized void stop() {
running = false; running = false;
for(ScheduledFuture<?> close : socketClosers) close.cancel(false);
localDevice = null; localDevice = null;
for(StreamConnectionNotifier scn : invitationSockets) tryToClose(scn);
invitationSockets.clear();
if(socket != null) { if(socket != null) {
socket.close(); tryToClose(socket);
socket = null; socket = null;
} }
} }
@@ -381,18 +383,34 @@ 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;
}
invitationSockets.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() {
synchronized(this) {
invitationSockets.remove(scn);
}
tryToClose(scn); tryToClose(scn);
} }
}; };
synchronized(this) { ScheduledFuture<?> future = pluginExecutor.schedule(close,
socketClosers.add(pluginExecutor.schedule(close, c.getTimeout(), c.getTimeout(), TimeUnit.MILLISECONDS);
TimeUnit.MILLISECONDS)); // Try to accept a connection
}
try { try {
StreamConnection s = scn.acceptAndOpen(); StreamConnection s = scn.acceptAndOpen();
// Close the socket and return the connection
if(future.cancel(false)) {
synchronized(this) {
invitationSockets.remove(scn);
}
tryToClose(scn);
}
c.addConnection(s); c.addConnection(s);
} catch(IOException e) { } catch(IOException e) {
// This is expected when the socket is closed // This is expected when the socket is closed