daemon: Vastly improved task creation

This commit is contained in:
Luke D. Jones
2022-08-21 20:15:36 +12:00
parent 92009ef96c
commit 1f697b5ff1
6 changed files with 185 additions and 225 deletions

View File

@@ -1,10 +1,8 @@
pub mod config;
pub mod zbus;
use ::zbus::Connection;
use async_trait::async_trait;
use log::{error, info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_anime::{
error::AnimeError,
usb::{
@@ -14,7 +12,7 @@ use rog_anime::{
ActionData, AnimeDataBuffer, AnimePacketType, AnimeType,
};
use rog_platform::{hid_raw::HidRaw, supported::AnimeSupportedFunctions, usb_raw::USBRaw};
use smol::{stream::StreamExt, Executor};
use smol::Executor;
use std::sync::atomic::{AtomicBool, Ordering};
use std::{
convert::TryFrom,
@@ -232,14 +230,6 @@ impl CtrlAnimeTask {
#[async_trait]
impl crate::CtrlTask for CtrlAnimeTask {
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let connection = Connection::system()
.await
.expect("CtrlAnimeTask could not create dbus connection");
let manager = ManagerProxy::new(&connection)
.await
.expect("CtrlAnimeTask could not create ManagerProxy");
let run_action =
|start: bool, lock: MutexGuard<CtrlAnime>, inner: Arc<Mutex<CtrlAnime>>| {
if start {
@@ -251,50 +241,40 @@ impl crate::CtrlTask for CtrlAnimeTask {
}
};
let inner = self.inner.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
// Loop is required to try an attempt to get the mutex *without* blocking
// other threads - it is possible to end up with deadlocks otherwise.
loop {
if let Ok(lock) = inner.clone().try_lock() {
run_action(args.start, lock, inner.clone());
break;
}
}
}
})
.await;
let inner1 = self.inner.clone();
let inner2 = self.inner.clone();
let inner3 = self.inner.clone();
let inner4 = self.inner.clone();
self.create_sys_event_tasks(
executor,
// 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 Ok(lock) = inner1.clone().try_lock() {
run_action(true, lock, inner1.clone());
break;
}
})
.detach();
let manager = ManagerProxy::new(&connection)
.await
.expect("CtrlAnimeTask could not create ManagerProxy");
let inner = self.inner.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_shutdown().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
loop {
if let Ok(lock) = inner.clone().try_lock() {
run_action(args.start, lock, inner.clone());
}
}
}
})
.await;
},
move || loop {
if let Ok(lock) = inner2.clone().try_lock() {
run_action(false, lock, inner2.clone());
break;
}
})
.detach();
},
move || loop {
if let Ok(lock) = inner3.clone().try_lock() {
run_action(true, lock, inner3.clone());
break;
}
},
move || loop {
if let Ok(lock) = inner4.clone().try_lock() {
run_action(false, lock, inner4.clone());
break;
}
},
)
.await;
Ok(())
}

View File

@@ -5,19 +5,17 @@ use crate::{
};
use async_trait::async_trait;
use log::{error, info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_aura::{
usb::{AuraDevice, LED_APPLY, LED_SET},
AuraEffect, LedBrightness, LED_MSG_LEN,
};
use rog_aura::{AuraZone, Direction, Speed, GRADIENT};
use rog_platform::{hid_raw::HidRaw, keyboard_led::KeyboardLed, supported::LedSupportedFunctions};
use smol::{stream::StreamExt, Executor};
use smol::Executor;
use std::collections::BTreeMap;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::MutexGuard;
use zbus::Connection;
use crate::GetSupported;
@@ -95,14 +93,6 @@ impl CtrlKbdLedTask {
#[async_trait]
impl CtrlTask for CtrlKbdLedTask {
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let connection = Connection::system()
.await
.expect("CtrlKbdLedTask could not create dbus connection");
let manager = ManagerProxy::new(&connection)
.await
.expect("CtrlKbdLedTask could not create ManagerProxy");
let load_save = |start: bool, mut lock: MutexGuard<CtrlKbdLed>| {
// If waking up
if !start {
@@ -121,41 +111,41 @@ impl CtrlTask for CtrlKbdLedTask {
}
};
let inner = self.inner.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
loop {
// Loop so that we do aquire the lock but also don't block other
// threads (prevents potential deadlocks)
if let Ok(lock) = inner.clone().try_lock() {
load_save(args.start, lock);
break;
}
}
}
})
.await;
let inner1 = self.inner.clone();
let inner2 = self.inner.clone();
let inner3 = self.inner.clone();
let inner4 = self.inner.clone();
self.create_sys_event_tasks(
executor,
// Loop so that we do aquire the lock but also don't block other
// threads (prevents potential deadlocks)
move || loop {
if let Ok(lock) = inner1.clone().try_lock() {
load_save(true, lock);
break;
}
if let Ok(notif) = manager.receive_prepare_for_shutdown().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
loop {
if let Ok(lock) = inner.clone().try_lock() {
load_save(args.start, lock);
break;
}
}
}
})
.await;
},
move || loop {
if let Ok(lock) = inner2.clone().try_lock() {
load_save(false, lock);
break;
}
})
.detach();
},
move || loop {
if let Ok(lock) = inner3.clone().try_lock() {
load_save(false, lock);
break;
}
},
move || loop {
if let Ok(lock) = inner4.clone().try_lock() {
load_save(false, lock);
break;
}
},
)
.await;
Ok(())
}
}

View File

@@ -2,10 +2,8 @@ use crate::CtrlTask;
use crate::{config::Config, error::RogError, GetSupported};
use async_trait::async_trait;
use log::{info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_platform::platform::{AsusPlatform, GpuMode};
use rog_platform::supported::RogBiosSupportedFunctions;
use smol::stream::StreamExt;
use smol::Executor;
use std::fs::OpenOptions;
use std::io::{Read, Write};
@@ -260,71 +258,39 @@ impl crate::Reloadable for CtrlRogBios {
#[async_trait]
impl CtrlTask for CtrlRogBios {
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let connection = Connection::system()
.await
.expect("CtrlRogBios could not create dbus connection");
let manager = ManagerProxy::new(&connection)
.await
.expect("CtrlRogBios could not create ManagerProxy");
let platform = self.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
// If waking up
if !args.start {
info!("CtrlRogBios reloading panel_od");
if let Ok(lock) = platform.config.try_lock() {
platform
.set_panel_od(lock.panel_od)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
}
}
}
let platform1 = self.clone();
let platform2 = self.clone();
self.create_sys_event_tasks(
executor,
move || {},
move || {
info!("CtrlRogBios reloading panel_od");
if let Ok(lock) = platform1.config.try_lock() {
platform1
.set_panel_od(lock.panel_od)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.await;
.ok();
}
})
.detach();
let manager = ManagerProxy::new(&connection)
.await
.expect("CtrlCharge could not create ManagerProxy");
let platform = self.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_shutdown().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
// If waking up - intention is to catch hibernation event
if !args.start {
info!("CtrlRogBios reloading panel_od");
if let Ok(lock) = platform.config.try_lock() {
platform
.set_panel_od(lock.panel_od)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
}
}
}
},
move || {},
move || {
info!("CtrlRogBios reloading panel_od");
if let Ok(lock) = platform2.config.try_lock() {
platform2
.set_panel_od(lock.panel_od)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.await;
.ok();
}
})
.detach();
},
)
.await;
Ok(())
}
}

View File

@@ -2,10 +2,8 @@ use crate::CtrlTask;
use crate::{config::Config, error::RogError, GetSupported};
use async_trait::async_trait;
use log::{info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_platform::power::AsusPower;
use rog_platform::supported::ChargeSupportedFunctions;
use smol::stream::StreamExt;
use smol::Executor;
use std::sync::Arc;
use std::sync::Mutex;
@@ -111,71 +109,39 @@ impl CtrlPower {
#[async_trait]
impl CtrlTask for CtrlPower {
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let connection = Connection::system()
.await
.expect("CtrlCharge could not create dbus connection");
let manager = ManagerProxy::new(&connection)
.await
.expect("CtrlCharge could not create ManagerProxy");
let power = self.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
// If waking up
if !args.start {
info!("CtrlCharge reloading charge limit");
if let Ok(lock) = power.config.try_lock() {
power
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
}
}
}
let power1 = self.clone();
let power2 = self.clone();
self.create_sys_event_tasks(
executor,
move || {},
move || {
info!("CtrlCharge reloading charge limit");
if let Ok(lock) = power1.config.try_lock() {
power1
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.await;
.ok();
}
})
.detach();
let manager = ManagerProxy::new(&connection)
.await
.expect("CtrlCharge could not create ManagerProxy");
let power = self.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_shutdown().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
// If waking up - intention is to catch hibernation event
if !args.start {
info!("CtrlCharge reloading charge limit");
if let Ok(lock) = power.config.try_lock() {
power
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
}
}
}
},
move || {},
move || {
info!("CtrlCharge reloading charge limit");
if let Ok(lock) = power2.config.try_lock() {
power2
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.await;
.ok();
}
})
.detach();
},
)
.await;
Ok(())
}
}

View File

@@ -35,6 +35,7 @@ use crate::error::RogError;
use async_trait::async_trait;
use config::Config;
use log::warn;
use logind_zbus::manager::ManagerProxy;
use smol::{stream::StreamExt, Executor, Timer};
use zbus::Connection;
use zvariant::ObjectPath;
@@ -87,6 +88,64 @@ pub trait CtrlTask {
})
.detach();
}
/// Free helper method to create tasks to run on: sleep, wake, shutdown, boot
async fn create_sys_event_tasks(
&self,
executor: &mut Executor,
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,
) {
let connection = Connection::system()
.await
.expect("Controller could not create dbus connection");
let manager = ManagerProxy::new(&connection)
.await
.expect("Controller could not create ManagerProxy");
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
if args.start {
on_sleep();
} else if !args.start() {
on_wake();
}
}
})
.await;
}
})
.detach();
let manager = ManagerProxy::new(&connection)
.await
.expect("Controller could not create ManagerProxy");
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_shutdown().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
if args.start {
on_shutdown();
} else if !args.start() {
on_boot();
}
}
})
.await;
}
})
.detach();
}
}
pub trait CtrlTaskComplex {

View File

@@ -271,8 +271,7 @@ mod tests {
"CPU: 30c:1%,49c:1%,59c:3%,69c:3%,79c:30%,89c:49%,99c:56%,109c:58%"
);
let curve =
CurveData::from_str("30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%");
let curve = CurveData::from_str("30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%");
assert!(curve.is_err());
}