Create the wait-latch before running the action, and only if neeeded

Otherwise the result handler might be called before the wait-latch
has been created, leading to a deadlock of the thread.

Also: only wait for read- and write actions, but not for wait-actions.
This commit is contained in:
cpfeiffer
2015-05-17 21:55:02 +02:00
parent 55400817b4
commit 9819819b92
5 changed files with 45 additions and 6 deletions
@@ -22,6 +22,20 @@ public abstract class BtLEAction {
this.characteristic = characteristic;
}
/**
* Returns true if this actions expects an (async) result which must
* be waited for, before continuing with other actions.
*
* This is needed because the current Bluedroid stack can only deal
* with one single bluetooth operation at a time.
*/
public abstract boolean expectsResult();
/**
* Executes this action, e.g. reads or write a GATT characteristic.
* @param gatt the characteristic to manipulate, or null if none.
* @return true if the action was successful, false otherwise
*/
public abstract boolean run(BluetoothGatt gatt);
/**
@@ -42,7 +42,7 @@ public final class BtLEQueue {
private BluetoothGattCharacteristic mWaitCharacteristic;
private GattCallback mExternalGattCallback;
private Thread dispatchThread = new Thread("Bluetooth GATT Dispatcher") {
private Thread dispatchThread = new Thread("GadgetBridge GATT Dispatcher") {
@Override
public void run() {
@@ -68,12 +68,17 @@ public final class BtLEQueue {
// Run all actions of the transaction until one doesn't succeed
for (BtLEAction action : transaction.getActions()) {
mWaitCharacteristic = action.getCharacteristic();
if (action.run(mBluetoothGatt)) {
boolean waitForResult = action.expectsResult();
if (waitForResult) {
mWaitForActionResultLatch = new CountDownLatch(1);
mWaitForActionResultLatch.await();
mWaitForActionResultLatch = null;
if (mAbortTransaction) {
break;
}
if (action.run(mBluetoothGatt)) {
if (waitForResult) {
mWaitForActionResultLatch.await();
mWaitForActionResultLatch = null;
if (mAbortTransaction) {
break;
}
}
} else {
LOG.error("Action returned false: " + action);
@@ -286,6 +291,10 @@ public final class BtLEQueue {
if (mWaitForActionResultLatch != null) {
mWaitForActionResultLatch.countDown();
}
} else {
if (BtLEQueue.this.mWaitCharacteristic != null) {
LOG.error("checkWaitingCharacteristic: mismatched characteristic received: " + characteristic != null ? characteristic.getUuid().toString() : "(null)");
}
}
}
};
@@ -19,4 +19,9 @@ public class ReadAction extends BtLEAction {
public boolean run(BluetoothGatt gatt) {
return gatt.readCharacteristic(getCharacteristic());
}
@Override
public boolean expectsResult() {
return true;
}
}
@@ -19,4 +19,10 @@ public class WaitAction extends BtLEAction {
return false;
}
}
@Override
public boolean expectsResult() {
// no BT communication at all, no result
return false;
}
}
@@ -25,4 +25,9 @@ public class WriteAction extends BtLEAction {
}
return false;
}
@Override
public boolean expectsResult() {
return true;
}
}