diff --git a/daemon/src/ctrl_anime/mod.rs b/daemon/src/ctrl_anime/mod.rs index 424e2c60..01291047 100644 --- a/daemon/src/ctrl_anime/mod.rs +++ b/daemon/src/ctrl_anime/mod.rs @@ -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, inner: Arc>| { 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(()) } diff --git a/daemon/src/ctrl_aura/controller.rs b/daemon/src/ctrl_aura/controller.rs index 0c19444f..61756304 100644 --- a/daemon/src/ctrl_aura/controller.rs +++ b/daemon/src/ctrl_aura/controller.rs @@ -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| { // 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(()) } } diff --git a/daemon/src/ctrl_platform.rs b/daemon/src/ctrl_platform.rs index 10c76611..36df38ce 100644 --- a/daemon/src/ctrl_platform.rs +++ b/daemon/src/ctrl_platform.rs @@ -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(()) } } diff --git a/daemon/src/ctrl_power.rs b/daemon/src/ctrl_power.rs index 4b39ea0a..6f01fd30 100644 --- a/daemon/src/ctrl_power.rs +++ b/daemon/src/ctrl_power.rs @@ -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(()) } } diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index 6f297277..c2978b55 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -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 { diff --git a/rog-profiles/src/fan_curve_set.rs b/rog-profiles/src/fan_curve_set.rs index 94bca095..d3eb923e 100644 --- a/rog-profiles/src/fan_curve_set.rs +++ b/rog-profiles/src/fan_curve_set.rs @@ -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()); }