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

View File

@ -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);
/**

View File

@ -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,13 +68,18 @@ 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);
}
if (action.run(mBluetoothGatt)) {
if (waitForResult) {
mWaitForActionResultLatch.await();
mWaitForActionResultLatch = null;
if (mAbortTransaction) {
break;
}
}
} else {
LOG.error("Action returned false: " + action);
break; // abort the transaction
@ -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)");
}
}
}
};

View File

@ -19,4 +19,9 @@ public class ReadAction extends BtLEAction {
public boolean run(BluetoothGatt gatt) {
return gatt.readCharacteristic(getCharacteristic());
}
@Override
public boolean expectsResult() {
return true;
}
}

View File

@ -19,4 +19,10 @@ public class WaitAction extends BtLEAction {
return false;
}
}
@Override
public boolean expectsResult() {
// no BT communication at all, no result
return false;
}
}

View File

@ -25,4 +25,9 @@ public class WriteAction extends BtLEAction {
}
return false;
}
@Override
public boolean expectsResult() {
return true;
}
}