Merge branch '283-die-bluetooth-die' into 'master'

Ensure key agreement tasks finish if they ignore interrupts

The problem here was that `BluetoothSocket#connect()` was throwing an IOException when the task was interrupted - the task treated this like any other connection failure and retried, so the task never finished.

The fix is to check whether the timeout has expired before retrying, so the task eventually finishes even if it ignores the original interrupt.

Closes #283

See merge request !443
This commit is contained in:
Torsten Grote
2016-12-06 11:02:19 +00:00
2 changed files with 15 additions and 11 deletions

View File

@@ -341,8 +341,10 @@ class DroidtoothPlugin implements DuplexPlugin {
LOG.info("Connected to " + scrubMacAddress(address));
return s;
} catch (IOException e) {
if (LOG.isLoggable(INFO))
LOG.info("Failed to connect to " + scrubMacAddress(address));
if (LOG.isLoggable(INFO)) {
LOG.info("Failed to connect to " + scrubMacAddress(address)
+ ": " + e);
}
tryToClose(s);
return null;
}
@@ -588,9 +590,10 @@ class DroidtoothPlugin implements DuplexPlugin {
finished.countDown();
} else if (action.equals(FOUND)) {
BluetoothDevice d = intent.getParcelableExtra(EXTRA_DEVICE);
if (LOG.isLoggable(INFO))
if (LOG.isLoggable(INFO)) {
LOG.info("Discovered device: " +
scrubMacAddress(d.getAddress()));
}
addresses.add(d.getAddress());
}
}

View File

@@ -148,9 +148,9 @@ class KeyAgreementConnector {
private void closePending(@Nullable KeyAgreementConnection chosen) {
for (Future<KeyAgreementConnection> f : pending) {
try {
if (f.cancel(true))
if (f.cancel(true)) {
LOG.info("Cancelled task");
else if (!f.isCancelled()) {
} else if (!f.isCancelled()) {
KeyAgreementConnection c = f.get();
if (c != null && c != chosen)
tryToClose(c.getConnection(), false);
@@ -193,9 +193,10 @@ class KeyAgreementConnector {
@Override
public KeyAgreementConnection call() throws Exception {
// Repeat attempts until we connect or get interrupted
// Repeat attempts until we connect, get interrupted, or time out
while (true) {
long now = clock.currentTimeMillis();
if (now > end) throw new IOException();
DuplexTransportConnection conn =
plugin.createKeyAgreementConnection(commitment,
descriptor, end - now);
@@ -221,8 +222,7 @@ class KeyAgreementConnector {
}
@Override
public KeyAgreementConnection call()
throws Exception {
public KeyAgreementConnection call() throws Exception {
KeyAgreementConnection c = connectionTask.call();
InputStream in = c.getConnection().getReader().getInputStream();
boolean waitingSent = false;
@@ -232,13 +232,14 @@ class KeyAgreementConnector {
callbacks.connectionWaiting();
waitingSent = true;
}
if (LOG.isLoggable(INFO))
LOG.info(c.getTransportId().toString() +
if (LOG.isLoggable(INFO)) {
LOG.info(c.getTransportId().getString() +
": Waiting for connection");
}
Thread.sleep(1000);
}
if (!alice && LOG.isLoggable(INFO))
LOG.info(c.getTransportId().toString() + ": Data available");
LOG.info(c.getTransportId().getString() + ": Data available");
return c;
}
}