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",
"sync",
"time",
"rt",
"rt-multi-thread",
] }
concat-idents = "^1.1"

View File

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

View File

@@ -8,7 +8,6 @@ use std::collections::HashSet;
use log::{error, info, warn};
use mio::{Events, Interest, Poll, Token};
use tokio::task::spawn_blocking;
use udev::{Device, MonitorBuilder};
use zbus::object_server::SignalEmitter;
use zbus::zvariant::{ObjectPath, OwnedObjectPath};
@@ -45,7 +44,7 @@ impl AuraManager {
// detect all plugged in aura devices (eventually)
// 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 poll = Poll::new()?;
let mut events = Events::with_capacity(1024);

View File

@@ -94,8 +94,14 @@ impl CtrlAuraZbus {
/// The current mode data
#[zbus(property)]
async fn led_mode(&self) -> Result<AuraModeNum, ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.config.current_mode)
// entirely possible to deadlock here, so use try instead of lock()
// 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.
@@ -116,6 +122,7 @@ impl CtrlAuraZbus {
}
ctrl.config.write();
self.led_mode_changed(&self.1).await.ok();
self.led_mode_data_changed(&self.1).await.ok();
Ok(())
}
@@ -123,11 +130,15 @@ impl CtrlAuraZbus {
/// The current mode data
#[zbus(property)]
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
let ctrl = self.0.lock().await;
let mode = ctrl.config.current_mode;
match ctrl.config.builtins.get(&mode) {
Some(effect) => Ok(effect.clone()),
None => Err(ZbErr::Failed("Could not get the current effect".into())),
// entirely possible to deadlock here, so use try instead of lock()
if let Some(ctrl) = self.0.try_lock() {
let mode = ctrl.config.current_mode;
match ctrl.config.builtins.get(&mode) {
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]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// console_subscriber::init();
console_subscriber::init();
let mut logger = env_logger::Builder::new();
logger
.parse_default_env()
.target(env_logger::Target::Stdout)
.format_timestamp(None)
.filter_level(log::LevelFilter::Debug)
.init();
let is_service = match env::var_os("IS_SERVICE") {
Some(val) => val == "1",
None => false,
None => true,
};
if !is_service {