From 7eae7c5664d57adfdcec4248947c102da85409a9 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Sun, 24 Mar 2024 21:14:54 +1300 Subject: [PATCH] Change aura manager task to blocking. Remove idle tasks that keep hanging --- Cargo.toml | 4 +- asusd/Cargo.toml | 1 + asusd/src/ctrl_aura/manager.rs | 220 ++++++++++++++------------------- asusd/src/daemon.rs | 1 + 4 files changed, 96 insertions(+), 130 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c25d3efc..3d7509a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,11 +28,11 @@ version = "6.0.0-alpha1" rust-version = "1.76" [workspace.dependencies] -tokio = { version = "^1.23.0", default-features = false, features = [ +tokio = { version = "^1.36.0", default-features = false, features = [ "macros", "sync", "time", - "rt", + "rt-multi-thread", ] } concat-idents = "^1.1" dirs = "^4.0" diff --git a/asusd/Cargo.toml b/asusd/Cargo.toml index 2e5abfba..2f774baf 100644 --- a/asusd/Cargo.toml +++ b/asusd/Cargo.toml @@ -26,6 +26,7 @@ inotify.workspace = true mio.workspace = true tokio.workspace = true +# console-subscriber = "0.2.0" # cli and logging log.workspace = true diff --git a/asusd/src/ctrl_aura/manager.rs b/asusd/src/ctrl_aura/manager.rs index c9fe6f48..c164e29c 100644 --- a/asusd/src/ctrl_aura/manager.rs +++ b/asusd/src/ctrl_aura/manager.rs @@ -5,14 +5,14 @@ // - If udev sees device removed then remove the zbus path use std::collections::HashSet; -use std::sync::Arc; +use std::time::Duration; use log::{debug, error, info, warn}; use mio::{Events, Interest, Poll, Token}; use rog_aura::aura_detection::LaptopLedData; use rog_aura::usb::AuraDevice; use rog_platform::hid_raw::HidRaw; -use tokio::sync::Mutex; +use tokio::task::spawn_blocking; use udev::{Device, MonitorBuilder}; // use zbus::fdo::ObjectManager; use zbus::object_server::SignalContext; @@ -29,7 +29,7 @@ pub struct AuraManager { } impl AuraManager { - pub async fn new(mut connection: Connection) -> Result { + pub async fn new(connection: Connection) -> Result { let conn_copy = connection.clone(); let data = LaptopLedData::get_data(); let mut interfaces = HashSet::new(); @@ -42,20 +42,15 @@ impl AuraManager { let sig_ctx = CtrlAuraZbus::signal_context(&connection)?; let sig_ctx2 = sig_ctx.clone(); let zbus = CtrlAuraZbus::new(ctrl, sig_ctx); - start_tasks(zbus, &mut connection, sig_ctx2, &path).await?; + start_tasks(zbus, connection.clone(), sig_ctx2, path).await?; } - // connection.object_server().at("/org/asuslinux", - // ObjectManager).await.unwrap(); - let manager = Self { _connection: connection, }; // detect all plugged in aura devices (eventually) - let interfaces = Arc::new(Mutex::new(interfaces)); - let mut count = 0; - tokio::spawn(async move { + spawn_blocking(move || { let mut monitor = MonitorBuilder::new()?.match_subsystem("hidraw")?.listen()?; let mut poll = Poll::new()?; let mut events = Events::with_capacity(1024); @@ -66,135 +61,107 @@ impl AuraManager { if poll.poll(&mut events, None).is_err() { continue; } - // collect and sort so remove events are first - // let mut events: Vec = monitor.iter().filter(|e| - // &*e.action().unwrap_or_default() == "remove").collect(); - // let mut adds: Vec = monitor.iter().filter(|e| - // &*e.action().unwrap_or_default() == "add").collect(); - // events.append(&mut adds); - - dbg!("LOOPED", count); - count += 1; for event in monitor.iter() { if event.parent_with_subsystem("hidraw").is_err() { continue; } - if let Some(parent) = + let parent = if let Some(parent) = event.parent_with_subsystem_devtype("usb", "usb_device")? { - let action = if let Some(action) = event.action() { - action - } else { - continue; - }; + parent + } else { + continue; + }; - let id_product = - if let Some(id_product) = parent.attribute_value("idProduct") { - id_product.to_string_lossy() - } else { - continue; - }; - let aura_device = AuraDevice::from(&*id_product); - if aura_device == AuraDevice::Unknown { - warn!("idProduct:{id_product:?} is unknown, not using"); + let action = if let Some(action) = event.action() { + action + } else { + continue; + }; + + let id_product = if let Some(id_product) = parent.attribute_value("idProduct") { + id_product.to_string_lossy() + } else { + continue; + }; + + let path = if let Some(path) = dbus_path_for_dev(&parent) { + path + } else { + continue; + }; + + let aura_device = AuraDevice::from(&*id_product); + if aura_device == AuraDevice::Unknown { + warn!("idProduct:{id_product:?} is unknown, not using"); + continue; + } + + if action == "remove" { + if interfaces.remove(&path) { + info!("AuraManager removing: {path:?}"); + let conn_copy = conn_copy.clone(); + tokio::spawn(async move { + let res = conn_copy + .object_server() + .remove::(&path) + .await + .map_err(|e| { + error!("Failed to remove {path:?}, {e:?}"); + e + })?; + info!("AuraManager removed: {path:?}, {res}"); + Ok::<(), RogError>(()) + }); + } + } else if action == "add" { + if interfaces.contains(&path) { + debug!("Already a ctrl at {path:?}"); continue; } - let path = if let Some(path) = dbus_path_for_dev(&parent) { - path - } else { - continue; - }; - - dbg!(action, &aura_device, &path); - if action == "remove" { - info!("AuraManager removing: {path:?}"); - let conn_copy = conn_copy.clone(); - let interfaces_copy = interfaces.clone(); - tokio::spawn(async move { - let mut interfaces = interfaces_copy.lock().await; // hold until completed - dbg!(&interfaces); - if interfaces.remove(&path) { - let res = conn_copy - .object_server() - .remove::(&path) - .await - .map_err(|e| { - error!("Failed to remove {path:?}, {e:?}"); - e - })?; - info!("AuraManager removed: {path:?}, {res}"); - } - dbg!(&interfaces); - Ok::<(), RogError>(()) - }); - } else if action == "add" { - if let Some(p2) = event.parent() { - if let Some(driver) = p2.driver() { - // There is a tree of devices added so filter by driver - if driver != "asus" { - debug!("{id_product:?} driver was not asus, skipping"); - continue; - } - } else { + // Need to check the driver is asus to prevent using hid_generic + if let Some(p2) = event.parent() { + if let Some(driver) = p2.driver() { + // There is a tree of devices added so filter by driver + if driver != "asus" { + debug!("{id_product:?} driver was not asus, skipping"); continue; } + } else { + continue; } + } - let path = if let Some(path) = dbus_path_for_dev(&parent) { - path - } else { - continue; - }; - - let dev_node = if let Some(dev_node) = event.devnode() { - dev_node.to_owned() - } else { - continue; - }; - + if let Some(dev_node) = event.devnode() { if let Ok(raw) = HidRaw::from_device(event.device()) .map_err(|e| error!("device path error: {e:?}")) { - // bah... shitty clone TODO: fix - let data_clone = data.clone(); - let mut conn_copy = conn_copy.clone(); - let interfaces_copy = interfaces.clone(); - // - tokio::spawn(async move { - let mut interfaces = interfaces_copy.lock().await; - dbg!(&interfaces); - if interfaces.contains(&path) { - debug!("Already a ctrl at {path:?}"); - return Ok(()); - } - if let Ok(mut ctrl) = - CtrlKbdLed::from_hidraw(raw, path.clone(), &data_clone) - { - info!( - "AuraManager found device at: {dev_node:?}, {path:?}" - ); - debug!("Starting Aura at {path}"); - interfaces.insert(path.clone()); - let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?; - ctrl.config = - CtrlKbdLed::init_config(aura_device, &data_clone); - let zbus = CtrlAuraZbus::new(ctrl, sig_ctx); - // Now add it to device list - let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?; - start_tasks(zbus, &mut conn_copy, sig_ctx, &path).await?; - } - dbg!(&interfaces); - Ok::<(), RogError>(()) - }); // Can't get result from here due to - // MonitorSocket + if let Ok(mut ctrl) = + CtrlKbdLed::from_hidraw(raw, path.clone(), &data) + { + ctrl.config = CtrlKbdLed::init_config(aura_device, &data); + interfaces.insert(path.clone()); + info!("AuraManager starting device at: {dev_node:?}, {path:?}"); + let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?; + let zbus = CtrlAuraZbus::new(ctrl, sig_ctx); + let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?; + let conn_copy = conn_copy.clone(); + tokio::spawn(async move { + return tokio::time::timeout( + Duration::from_millis(1000), + start_tasks(zbus, conn_copy.clone(), sig_ctx, path), + ) + .await; + }); + } } } - } + }; } } - // Required for return type on tokio::spawn + // Required for return type on spawn #[allow(unreachable_code)] Ok::<(), RogError>(()) }); @@ -223,20 +190,17 @@ pub(crate) fn dbus_path_for_dev(parent: &Device) -> Option { async fn start_tasks( mut zbus: CtrlAuraZbus, - connection: &mut Connection, - signal_ctx: SignalContext<'static>, - path: &ObjectPath<'static>, + connection: Connection, + _signal_ctx: SignalContext<'static>, + path: OwnedObjectPath, ) -> Result<(), RogError> { - let task = zbus.clone(); + // let task = zbus.clone(); + // let signal_ctx = signal_ctx.clone(); zbus.reload() .await .unwrap_or_else(|err| warn!("Controller error: {}", err)); - - connection - .object_server() - .at(&ObjectPath::from_str_unchecked(path), zbus) - .await - .unwrap(); - task.create_tasks(signal_ctx).await.ok(); + connection.object_server().at(path, zbus).await.unwrap(); + // TODO: skip this until we keep handles to tasks so they can be killed + // task.create_tasks(signal_ctx).await Ok(()) } diff --git a/asusd/src/daemon.rs b/asusd/src/daemon.rs index e6d09984..b9d68cd1 100644 --- a/asusd/src/daemon.rs +++ b/asusd/src/daemon.rs @@ -18,6 +18,7 @@ use zbus::fdo::ObjectManager; #[tokio::main] async fn main() -> Result<(), Box> { + // console_subscriber::init(); let mut logger = env_logger::Builder::new(); logger .parse_default_env()