Fix tasks not always running correctly on boot/sleep/wake/shutdown

This commit is contained in:
Luke D. Jones
2022-12-08 20:12:55 +13:00
parent 07daa0df61
commit 245c035dc9
8 changed files with 125 additions and 80 deletions

View File

@@ -166,28 +166,32 @@ impl crate::CtrlTask for CtrlAnimeZbus {
self.create_sys_event_tasks(
// Loop is required to try an attempt to get the mutex *without* blocking
// other threads - it is possible to end up with deadlocks otherwise.
move || loop {
if let Some(lock) = inner1.try_lock() {
move || {
let inner1 = inner1.clone();
async move {
let lock = inner1.lock().await;
run_action(true, lock, inner1.clone());
break;
}
},
move || loop {
if let Some(lock) = inner2.try_lock() {
run_action(false, lock, inner2.clone());
break;
move || {
let inner2 = inner2.clone();
async move {
let lock = inner2.lock().await;
run_action(true, lock, inner2.clone());
}
},
move || loop {
if let Some(lock) = inner3.try_lock() {
move || {
let inner3 = inner3.clone();
async move {
let lock = inner3.lock().await;
run_action(true, lock, inner3.clone());
break;
}
},
move || loop {
if let Some(lock) = inner4.try_lock() {
run_action(false, lock, inner4.clone());
break;
move || {
let inner4 = inner4.clone();
async move {
let lock = inner4.lock().await;
run_action(true, lock, inner4.clone());
}
},
)

View File

@@ -262,28 +262,32 @@ impl CtrlTask for CtrlKbdLedZbus {
self.create_sys_event_tasks(
// Loop so that we do aquire the lock but also don't block other
// threads (prevents potential deadlocks)
move || loop {
if let Some(lock) = inner1.try_lock() {
move || {
let inner1 = inner1.clone();
async move {
let lock = inner1.lock().await;
load_save(true, lock);
break;
}
},
move || loop {
if let Some(lock) = inner2.try_lock() {
move || {
let inner2 = inner2.clone();
async move {
let lock = inner2.lock().await;
load_save(false, lock);
break;
}
},
move || loop {
if let Some(lock) = inner3.try_lock() {
load_save(true, lock);
break;
}
},
move || loop {
if let Some(lock) = inner4.try_lock() {
move || {
let inner3 = inner3.clone();
async move {
let lock = inner3.lock().await;
load_save(false, lock);
}
},
move || {
let inner4 = inner4.clone();
async move {
let lock = inner4.lock().await;
load_save(false, lock);
break;
}
},
)

View File

@@ -332,10 +332,12 @@ impl CtrlTask for CtrlPlatform {
let platform1 = self.clone();
let platform2 = self.clone();
self.create_sys_event_tasks(
move || {},
move || async { {} },
move || {
info!("CtrlRogBios reloading panel_od");
if let Some(lock) = platform1.config.try_lock() {
let platform1 = platform1.clone();
async move {
info!("CtrlRogBios reloading panel_od");
let lock = platform1.config.lock().await;
if platform1.platform.has_panel_od() {
platform1
.set_panel_overdrive(lock.panel_od)
@@ -347,10 +349,12 @@ impl CtrlTask for CtrlPlatform {
}
}
},
move || {},
move || async { {} },
move || {
info!("CtrlRogBios reloading panel_od");
if let Some(lock) = platform2.config.try_lock() {
let platform2 = platform2.clone();
async move {
info!("CtrlRogBios reloading panel_od");
let lock = platform2.config.lock().await;
if platform2.platform.has_panel_od() {
platform2
.set_panel_overdrive(lock.panel_od)

View File

@@ -155,10 +155,12 @@ impl CtrlTask for CtrlPower {
let power1 = self.clone();
let power2 = self.clone();
self.create_sys_event_tasks(
move || {},
move || async {},
move || {
info!("CtrlCharge reloading charge limit");
if let Some(lock) = power1.config.try_lock() {
let power1 = power1.clone();
async move {
info!("CtrlCharge reloading charge limit");
let lock = power1.config.lock().await;
power1
.set(lock.bat_charge_limit)
.map_err(|err| {
@@ -166,22 +168,25 @@ impl CtrlTask for CtrlPower {
err
})
.ok();
}
if let Ok(value) = power1.power.get_online() {
let action = if value == 1 {
SystemdUnitAction::Restart
} else {
SystemdUnitAction::Stop
};
if do_systemd_unit_action(action, NVIDIA_POWERD).is_ok() {
info!("CtrlPower task: did {action:?} on {NVIDIA_POWERD}");
if let Ok(value) = power1.power.get_online() {
let action = if value == 1 {
SystemdUnitAction::Restart
} else {
SystemdUnitAction::Stop
};
if do_systemd_unit_action(action, NVIDIA_POWERD).is_ok() {
info!("CtrlPower task: did {action:?} on {NVIDIA_POWERD}");
}
}
}
},
move || {},
move || async {},
move || {
info!("CtrlCharge reloading charge limit");
if let Some(lock) = power2.config.try_lock() {
let power2 = power2.clone();
async move {
info!("CtrlCharge reloading charge limit");
let lock = power2.config.lock().await;
power2
.set(lock.bat_charge_limit)
.map_err(|err| {
@@ -189,15 +194,16 @@ impl CtrlTask for CtrlPower {
err
})
.ok();
}
if let Ok(value) = power2.power.get_online() {
let action = if value == 1 {
SystemdUnitAction::Restart
} else {
SystemdUnitAction::Stop
};
if do_systemd_unit_action(action, NVIDIA_POWERD).is_ok() {
info!("CtrlPower task: did {action:?} on {NVIDIA_POWERD}");
if let Ok(value) = power2.power.get_online() {
let action = if value == 1 {
SystemdUnitAction::Restart
} else {
SystemdUnitAction::Stop
};
if do_systemd_unit_action(action, NVIDIA_POWERD).is_ok() {
info!("CtrlPower task: did {action:?} on {NVIDIA_POWERD}");
}
}
}
},

View File

@@ -21,9 +21,11 @@ pub mod ctrl_supported;
pub mod error;
use std::future::Future;
use crate::error::RogError;
use async_trait::async_trait;
use log::warn;
use log::{debug, warn};
use logind_zbus::manager::ManagerProxy;
use zbus::{export::futures_util::StreamExt, zvariant::ObjectPath, Connection, SignalContext};
@@ -134,13 +136,31 @@ pub trait CtrlTask {
///
/// The closures can potentially block, so execution time should be the minimal possible
/// such as save a variable.
async fn create_sys_event_tasks(
async fn create_sys_event_tasks<
Fut1,
Fut2,
Fut3,
Fut4,
F1: Send + 'static,
F2: Send + 'static,
F3: Send + 'static,
F4: Send + 'static,
>(
&self,
mut on_sleep: impl FnMut() + Send + 'static,
mut on_wake: impl FnMut() + Send + 'static,
mut on_shutdown: impl FnMut() + Send + 'static,
mut on_boot: impl FnMut() + Send + 'static,
) {
mut on_sleep: F1,
mut on_wake: F2,
mut on_shutdown: F3,
mut on_boot: F4,
) where
F1: FnMut() -> Fut1,
F2: FnMut() -> Fut2,
F3: FnMut() -> Fut3,
F4: FnMut() -> Fut4,
Fut1: Future<Output = ()> + Send,
Fut2: Future<Output = ()> + Send,
Fut3: Future<Output = ()> + Send,
Fut4: Future<Output = ()> + Send,
{
let connection = Connection::system()
.await
.expect("Controller could not create dbus connection");
@@ -154,9 +174,11 @@ pub trait CtrlTask {
while let Some(event) = notif.next().await {
if let Ok(args) = event.args() {
if args.start {
on_sleep();
debug!("Doing on_sleep()");
on_sleep().await;
} else if !args.start() {
on_wake();
debug!("Doing on_wake()");
on_wake().await;
}
}
}
@@ -172,9 +194,11 @@ pub trait CtrlTask {
while let Some(event) = notif.next().await {
if let Ok(args) = event.args() {
if args.start {
on_shutdown();
debug!("Doing on_shutdown()");
on_shutdown().await;
} else if !args.start() {
on_boot();
debug!("Doing on_boot()");
on_boot().await;
}
}
}