From 97951027dc06ef419383925e86bd6f2143dfd51d Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 18 Sep 2020 05:51:22 +0200 Subject: DBTDevice: Resolve disconnect/remove resource race condition @ rapid connect w/ one thread per device 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. --- examples/java/ScannerTinyB10.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'examples/java') 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 ) { -- cgit v1.2.3