Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75a56d59 authored by Hsin-chen Chuang's avatar Hsin-chen Chuang
Browse files

floss: Fix racing in start/stop scan

Consider the following race:
1. The 1st StartScan is called with filter:
     has_active_unfiltered_scanner = false
2. The 2nd StartScan is called without filter:
     has_active_unfiltered_scanner = true
3. Async task of the 2nd StartScan is done -> Unfiltered scanning mode
4. Async task of the 1st StartScan is done -> MSFT scanning mode
==> Want unfiltered scan, but got MSFT scan

This patch move the decision into the async tasks, so it is protected
by the lock and the real executing order doesn't matter.

Bug: 279233527
Tag: #floss
Test: Manual test
Change-Id: Ib41d2bbf965a81edce23d62ae6df9832362fc1af
parent e1aabebe
Loading
Loading
Loading
Loading
+13 −14
Original line number Diff line number Diff line
@@ -1615,13 +1615,6 @@ impl BluetoothGatt {
        scanner_id: u8,
        filter: Option<ScanFilter>,
    ) -> BtStatus {
        let has_active_unfiltered_scanner = self
            .scanners
            .lock()
            .unwrap()
            .iter()
            .any(|(_uuid, scanner)| scanner.is_active && scanner.filter.is_none());

        let gatt_async = self.gatt_async.clone();
        let scanners = self.scanners.clone();
        let is_msft_supported = self.is_msft_supported();
@@ -1657,6 +1650,12 @@ impl BluetoothGatt {
                    log::debug!("Added adv monitor handle = {}", monitor_handle);
                }

                let has_active_unfiltered_scanner = scanners
                    .lock()
                    .unwrap()
                    .iter()
                    .any(|(_uuid, scanner)| scanner.is_active && scanner.filter.is_none());

                if !gatt_async
                    .msft_adv_monitor_enable(!has_active_unfiltered_scanner)
                    .await
@@ -1941,14 +1940,8 @@ impl IBluetoothGatt for BluetoothGatt {
            }
        };

        let has_active_unfiltered_scanner = self
            .scanners
            .lock()
            .unwrap()
            .iter()
            .any(|(_uuid, scanner)| scanner.is_active && scanner.filter.is_none());

        let gatt_async = self.gatt_async.clone();
        let scanners = self.scanners.clone();
        let is_msft_supported = self.is_msft_supported();
        tokio::spawn(async move {
            // The two operations below (monitor remove, update scan) happen one after another, and
@@ -1963,6 +1956,12 @@ impl IBluetoothGatt for BluetoothGatt {
                    let _res = gatt_async.msft_adv_monitor_remove(handle).await;
                }

                let has_active_unfiltered_scanner = scanners
                    .lock()
                    .unwrap()
                    .iter()
                    .any(|(_uuid, scanner)| scanner.is_active && scanner.filter.is_none());

                if !gatt_async
                    .msft_adv_monitor_enable(!has_active_unfiltered_scanner)
                    .await