diff options
author | Sven Gothel <[email protected]> | 2020-09-18 05:51:22 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-09-18 05:51:22 +0200 |
commit | 97951027dc06ef419383925e86bd6f2143dfd51d (patch) | |
tree | a7ef35d8ba58702a0178fe1f040185858d353f68 /examples | |
parent | 5878830cd6dcb18c2cab53bb47e82e94d6c75d79 (diff) |
DBTDevice: Resolve disconnect/remove resource race condition @ rapid connect w/ one thread per devicev2.1.22
Testing w/ 2 devices in fastest rapid reconnect (using automatic disconnect) on Raspberry-Pi:
(1) Native run-dbt_scanner10.sh -silent_gatt -mac C0:26:DA:01:DA:B1 -mac C0:26:DF:01:E5:CA -disconnect -count 12
(2) Java run-java-scanner10.sh -silent_gatt -mac C0:26:DA:01:DA:B1 -mac C0:26:DF:01:E5:CA -disconnect -count 12
The Java (2) test case disclosed a race condition as follows:
"An application using one thread per device and rapid connect, should either use disconnect() or remove(),
but never issue remove() after disconnect(). Doing so would eventually delete the device being already
in use by another thread due to discovery post disconnect!"
The example code was issuing (1) disconnect and waiting for being diconnected and only then
(2) removing the device. In between the device got discovered already and a new processing thread has started
while the closing previous processing thread is removing the device and hence the underlying DBTDevice.
A user shall either use disconnect() or remove(), period.
Diffstat (limited to 'examples')
-rw-r--r-- | examples/direct_bt_scanner10/dbt_scanner10.cpp | 9 | ||||
-rw-r--r-- | examples/java/ScannerTinyB10.java | 12 |
2 files changed, 7 insertions, 14 deletions
diff --git a/examples/direct_bt_scanner10/dbt_scanner10.cpp b/examples/direct_bt_scanner10/dbt_scanner10.cpp index 84d2ff13..f1f296fa 100644 --- a/examples/direct_bt_scanner10/dbt_scanner10.cpp +++ b/examples/direct_bt_scanner10/dbt_scanner10.cpp @@ -368,15 +368,14 @@ exit: fprintf(stderr, "****** Processing Device: pingGATT failed: %s\n", device->getAddressString().c_str()); } - fprintf(stderr, "****** Processing Device: disconnecting: %s\n", device->getAddressString().c_str()); - device->disconnect(); // will implicitly purge the GATT data, including GATTCharacteristic listener. - while( device->getConnected() ) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } if( REMOVE_DEVICE ) { fprintf(stderr, "****** Processing Device: removing: %s\n", device->getAddressString().c_str()); device->remove(); + } else { + fprintf(stderr, "****** Processing Device: disconnecting: %s\n", device->getAddressString().c_str()); + device->disconnect(); // will implicitly purge the GATT data, including GATTCharacteristic listener. } + if( !SILENT_GATT ) { device->getAdapter().printSharedPtrListOfDevices(); } diff --git a/examples/java/ScannerTinyB10.java b/examples/java/ScannerTinyB10.java index 3afb97e4..d40864af 100644 --- a/examples/java/ScannerTinyB10.java +++ b/examples/java/ScannerTinyB10.java @@ -384,18 +384,12 @@ public class ScannerTinyB10 { println("****** Processing Device: pingGATT failed: "+device.getAddress()); } - println("****** Processing Device: disconnecting: "+device.getAddress()); - device.disconnect(); // will implicitly purge the GATT data, including GATTCharacteristic listener. - while( device.getConnected() ) { - try { - Thread.sleep(100); - } catch (final InterruptedException e) { - e.printStackTrace(); - } - } if( REMOVE_DEVICE ) { println("****** Processing Device: removing: "+device.getAddress()); device.remove(); + } else { + println("****** Processing Device: disconnecting: "+device.getAddress()); + device.disconnect(); // will implicitly purge the GATT data, including GATTCharacteristic listener. } if( 0 < MULTI_MEASUREMENTS ) { |