Fix: prevent an aura manager deadlock

This commit is contained in:
Luke D. Jones
2024-12-18 10:33:14 +13:00
parent ccdc576319
commit c05c8ba648
6 changed files with 554 additions and 314 deletions

829
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,7 @@ tokio = { version = "^1.39.0", default-features = false, features = [
"macros", "macros",
"sync", "sync",
"time", "time",
"rt",
"rt-multi-thread", "rt-multi-thread",
] } ] }
concat-idents = "^1.1" concat-idents = "^1.1"

View File

@@ -13,6 +13,9 @@ edition.workspace = true
name = "asusd" name = "asusd"
path = "src/daemon.rs" path = "src/daemon.rs"
[features]
tokio_debug = []
[dependencies] [dependencies]
config-traits = { path = "../config-traits" } config-traits = { path = "../config-traits" }
rog_anime = { path = "../rog-anime", features = ["dbus"] } rog_anime = { path = "../rog-anime", features = ["dbus"] }
@@ -27,7 +30,7 @@ inotify.workspace = true
mio.workspace = true mio.workspace = true
tokio.workspace = true tokio.workspace = true
# console-subscriber = "0.2.0" console-subscriber = "0.2.0"
# cli and logging # cli and logging
log.workspace = true log.workspace = true

View File

@@ -8,7 +8,6 @@ use std::collections::HashSet;
use log::{error, info, warn}; use log::{error, info, warn};
use mio::{Events, Interest, Poll, Token}; use mio::{Events, Interest, Poll, Token};
use tokio::task::spawn_blocking;
use udev::{Device, MonitorBuilder}; use udev::{Device, MonitorBuilder};
use zbus::object_server::SignalEmitter; use zbus::object_server::SignalEmitter;
use zbus::zvariant::{ObjectPath, OwnedObjectPath}; use zbus::zvariant::{ObjectPath, OwnedObjectPath};
@@ -45,7 +44,7 @@ impl AuraManager {
// detect all plugged in aura devices (eventually) // detect all plugged in aura devices (eventually)
// only USB devices are detected for here // only USB devices are detected for here
spawn_blocking(move || { std::thread::spawn(move || {
let mut monitor = MonitorBuilder::new()?.match_subsystem("hidraw")?.listen()?; let mut monitor = MonitorBuilder::new()?.match_subsystem("hidraw")?.listen()?;
let mut poll = Poll::new()?; let mut poll = Poll::new()?;
let mut events = Events::with_capacity(1024); let mut events = Events::with_capacity(1024);

View File

@@ -94,8 +94,14 @@ impl CtrlAuraZbus {
/// The current mode data /// The current mode data
#[zbus(property)] #[zbus(property)]
async fn led_mode(&self) -> Result<AuraModeNum, ZbErr> { async fn led_mode(&self) -> Result<AuraModeNum, ZbErr> {
let ctrl = self.0.lock().await; // entirely possible to deadlock here, so use try instead of lock()
Ok(ctrl.config.current_mode) // let ctrl = self.0.lock().await;
// Ok(ctrl.config.current_mode)
if let Some(ctrl) = self.0.try_lock() {
Ok(ctrl.config.current_mode)
} else {
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
}
} }
/// Set an Aura effect if the effect mode or zone is supported. /// Set an Aura effect if the effect mode or zone is supported.
@@ -116,6 +122,7 @@ impl CtrlAuraZbus {
} }
ctrl.config.write(); ctrl.config.write();
self.led_mode_changed(&self.1).await.ok();
self.led_mode_data_changed(&self.1).await.ok(); self.led_mode_data_changed(&self.1).await.ok();
Ok(()) Ok(())
} }
@@ -123,11 +130,15 @@ impl CtrlAuraZbus {
/// The current mode data /// The current mode data
#[zbus(property)] #[zbus(property)]
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> { async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
let ctrl = self.0.lock().await; // entirely possible to deadlock here, so use try instead of lock()
let mode = ctrl.config.current_mode; if let Some(ctrl) = self.0.try_lock() {
match ctrl.config.builtins.get(&mode) { let mode = ctrl.config.current_mode;
Some(effect) => Ok(effect.clone()), match ctrl.config.builtins.get(&mode) {
None => Err(ZbErr::Failed("Could not get the current effect".into())), Some(effect) => Ok(effect.clone()),
None => Err(ZbErr::Failed("Could not get the current effect".into())),
}
} else {
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
} }
} }

View File

@@ -19,17 +19,18 @@ use zbus::fdo::ObjectManager;
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> { async fn main() -> Result<(), Box<dyn std::error::Error>> {
// console_subscriber::init(); console_subscriber::init();
let mut logger = env_logger::Builder::new(); let mut logger = env_logger::Builder::new();
logger logger
.parse_default_env() .parse_default_env()
.target(env_logger::Target::Stdout) .target(env_logger::Target::Stdout)
.format_timestamp(None) .format_timestamp(None)
.filter_level(log::LevelFilter::Debug)
.init(); .init();
let is_service = match env::var_os("IS_SERVICE") { let is_service = match env::var_os("IS_SERVICE") {
Some(val) => val == "1", Some(val) => val == "1",
None => false, None => true,
}; };
if !is_service { if !is_service {