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

Commit 922b7767 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "floss: listen for thread_event_cb to exit main thread" into main

parents dd8fa73a ab4519bd
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ use btstack::{
    battery_manager::BatteryManager,
    battery_provider_manager::BatteryProviderManager,
    battery_service::BatteryService,
    bluetooth::{Bluetooth, IBluetooth},
    bluetooth::{Bluetooth, IBluetooth, SigData},
    bluetooth_admin::BluetoothAdmin,
    bluetooth_gatt::BluetoothGatt,
    bluetooth_logging::BluetoothLogging,
@@ -49,6 +49,8 @@ const ADMIN_SETTINGS_FILE_PATH: &str = "/var/lib/bluetooth/admin_policy.json";
// The maximum ACL disconnect timeout is 3.5s defined by BTA_DM_DISABLE_TIMER_MS
// and BTA_DM_DISABLE_TIMER_RETRIAL_MS
const STACK_TURN_OFF_TIMEOUT_MS: Duration = Duration::from_millis(4000);
// Time bt_stack_manager waits for cleanup
const STACK_CLEANUP_TIMEOUT_MS: Duration = Duration::from_millis(1000);

const VERBOSE_ONLY_LOG_TAGS: &[&str] = &[
    "bt_bta_av", // AV apis
@@ -135,7 +137,12 @@ fn main() -> Result<(), Box<dyn Error>> {
    init_flags.push(String::from("INIT_classic_discovery_only=true"));

    let (tx, rx) = Stack::create_channel();
    let sig_notifier = Arc::new((Mutex::new(false), Condvar::new()));
    let sig_notifier = Arc::new(SigData {
        enabled: Mutex::new(false),
        enabled_notify: Condvar::new(),
        thread_attached: Mutex::new(false),
        thread_notify: Condvar::new(),
    });

    let intf = Arc::new(Mutex::new(get_btinterface().unwrap()));
    let bluetooth_gatt =
@@ -424,7 +431,7 @@ fn main() -> Result<(), Box<dyn Error>> {

lazy_static! {
    /// Data needed for signal handling.
    static ref SIG_DATA: Mutex<Option<(Sender<Message>, Arc<(Mutex<bool>, Condvar)>)>> = Mutex::new(None);
    static ref SIG_DATA: Mutex<Option<(Sender<Message>, Arc<(SigData)>)>> = Mutex::new(None);
}

extern "C" fn handle_sigterm(_signum: i32) {
@@ -437,10 +444,23 @@ extern "C" fn handle_sigterm(_signum: i32) {
            let _ = txl.send(Message::Shutdown).await;
        });

        let guard = notifier.0.lock().unwrap();
        let guard = notifier.enabled.lock().unwrap();
        if *guard {
            log::debug!("Waiting for stack to turn off for {:?}", STACK_TURN_OFF_TIMEOUT_MS);
            let _ = notifier.1.wait_timeout(guard, STACK_TURN_OFF_TIMEOUT_MS);
            let _ = notifier.enabled_notify.wait_timeout(guard, STACK_TURN_OFF_TIMEOUT_MS);
        }

        log::debug!("SIGTERM cleaning up the stack.");
        let txl = tx.clone();
        tokio::spawn(async move {
            // Send the cleanup message here.
            let _ = txl.send(Message::Cleanup).await;
        });

        let guard = notifier.thread_attached.lock().unwrap();
        if *guard {
            log::debug!("Waiting for stack to clean up for {:?}", STACK_CLEANUP_TIMEOUT_MS);
            let _ = notifier.thread_notify.wait_timeout(guard, STACK_CLEANUP_TIMEOUT_MS);
        }
    }

+35 −8
Original line number Diff line number Diff line
@@ -4,8 +4,8 @@ use bt_topshim::btif::{
    BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BluetoothProperty, BtAclState,
    BtBondState, BtConnectionDirection, BtConnectionState, BtDeviceType, BtDiscMode,
    BtDiscoveryState, BtHciErrorCode, BtPinCode, BtPropertyType, BtScanMode, BtSspVariant, BtState,
    BtStatus, BtTransport, BtVendorProductInfo, DisplayAddress, RawAddress, ToggleableProfile,
    Uuid, Uuid128Bit,
    BtStatus, BtThreadEvent, BtTransport, BtVendorProductInfo, DisplayAddress, RawAddress,
    ToggleableProfile, Uuid, Uuid128Bit,
};
use bt_topshim::{
    metrics,
@@ -382,6 +382,15 @@ impl BluetoothDeviceContext {
    }
}

/// Structure to track all the signals for SIGTERM.
pub struct SigData {
    pub enabled: Mutex<bool>,
    pub enabled_notify: Condvar,

    pub thread_attached: Mutex<bool>,
    pub thread_notify: Condvar,
}

/// The interface for adapter callbacks registered through `IBluetooth::register_callback`.
pub trait IBluetoothCallback: RPCProxy {
    /// When any adapter property changes.
@@ -500,7 +509,7 @@ pub struct Bluetooth {
    discoverable_timeout: Option<JoinHandle<()>>,

    /// Used to notify signal handler that we have turned off the stack.
    sig_notifier: Arc<(Mutex<bool>, Condvar)>,
    sig_notifier: Arc<(SigData)>,
}

impl Bluetooth {
@@ -509,7 +518,7 @@ impl Bluetooth {
        adapter_index: i32,
        hci_index: i32,
        tx: Sender<Message>,
        sig_notifier: Arc<(Mutex<bool>, Condvar)>,
        sig_notifier: Arc<(SigData)>,
        intf: Arc<Mutex<BluetoothInterface>>,
        bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
        bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
@@ -1173,6 +1182,9 @@ pub(crate) trait BtifBluetoothCallbacks {
        min_16_digit: bool,
    ) {
    }

    #[btif_callback(ThreadEvent)]
    fn thread_event(&mut self, event: BtThreadEvent) {}
}

#[btif_callbacks_dispatcher(dispatch_hid_host_callbacks, HHCallbacks)]
@@ -1240,8 +1252,8 @@ impl BtifBluetoothCallbacks for Bluetooth {
                }

                // Let the signal notifier know we are turned off.
                *self.sig_notifier.0.lock().unwrap() = false;
                self.sig_notifier.1.notify_all();
                *self.sig_notifier.enabled.lock().unwrap() = false;
                self.sig_notifier.enabled_notify.notify_all();
            }

            BtState::On => {
@@ -1265,8 +1277,8 @@ impl BtifBluetoothCallbacks for Bluetooth {
                self.set_connectable(true);

                // Notify the signal notifier that we are turned on.
                *self.sig_notifier.0.lock().unwrap() = true;
                self.sig_notifier.1.notify_all();
                *self.sig_notifier.enabled.lock().unwrap() = true;
                self.sig_notifier.enabled_notify.notify_all();

                // Signal that the stack is up and running.
                match self.create_pid_file() {
@@ -1726,6 +1738,21 @@ impl BtifBluetoothCallbacks for Bluetooth {
            None => (),
        };
    }

    fn thread_event(&mut self, event: BtThreadEvent) {
        match event {
            BtThreadEvent::Associate => {
                // Let the signal notifier know stack is initialized.
                *self.sig_notifier.thread_attached.lock().unwrap() = true;
                self.sig_notifier.thread_notify.notify_all();
            }
            BtThreadEvent::Disassociate => {
                // Let the signal notifier know stack is done.
                *self.sig_notifier.thread_attached.lock().unwrap() = false;
                self.sig_notifier.thread_notify.notify_all();
            }
        }
    }
}

struct BleDiscoveryCallbacks {
+4 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ use bt_topshim::{
pub enum Message {
    // Shuts down the stack.
    Shutdown,
    Cleanup,

    // Adapter is enabled and ready.
    AdapterReady,
@@ -196,6 +197,9 @@ impl Stack {
            match m.unwrap() {
                Message::Shutdown => {
                    bluetooth.lock().unwrap().disable();
                }

                Message::Cleanup => {
                    bluetooth.lock().unwrap().cleanup();
                }

+17 −2
Original line number Diff line number Diff line
@@ -330,6 +330,19 @@ impl Into<u32> for BtDiscMode {
    }
}

#[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
#[repr(u32)]
pub enum BtThreadEvent {
    Associate = 0,
    Disassociate,
}

impl From<bindings::bt_cb_thread_evt> for BtThreadEvent {
    fn from(item: bindings::bt_cb_thread_evt) -> Self {
        BtThreadEvent::from_u32(item).unwrap_or(BtThreadEvent::Associate)
    }
}

#[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
#[repr(u32)]
pub enum BtIoCap {
@@ -883,8 +896,8 @@ pub enum BaseCallbacks {
        BtConnectionDirection,
        u16,
    ),
    ThreadEvent(BtThreadEvent),
    // Unimplemented so far:
    // thread_evt_cb
    // dut_mode_recv_cb
    // le_test_mode_cb
    // energy_info_cb
@@ -944,6 +957,8 @@ cb_variant!(BaseCb, le_address_associate_cb -> BaseCallbacks::LeAddressAssociate
    let _1 = unsafe { *(_1 as *const RawAddress) };
});

cb_variant!(BaseCb, thread_evt_cb -> BaseCallbacks::ThreadEvent, u32 -> BtThreadEvent);

cb_variant!(BaseCb, acl_state_cb -> BaseCallbacks::AclState,
u32 -> BtStatus, *mut RawAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, bindings::bt_conn_direction_t -> BtConnectionDirection, u16 -> u16, {
    let _1 = unsafe { *(_1 as *const RawAddress) };
@@ -1072,7 +1087,7 @@ impl BluetoothInterface {
            address_consolidate_cb: Some(address_consolidate_cb),
            le_address_associate_cb: Some(le_address_associate_cb),
            acl_state_changed_cb: Some(acl_state_cb),
            thread_evt_cb: None,
            thread_evt_cb: Some(thread_evt_cb),
            dut_mode_recv_cb: None,
            le_test_mode_cb: None,
            energy_info_cb: None,