mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-01-22 17:33:19 +01:00
Change aura manager task to blocking. Remove idle tasks that keep hanging
This commit is contained in:
@@ -28,11 +28,11 @@ version = "6.0.0-alpha1"
|
||||
rust-version = "1.76"
|
||||
|
||||
[workspace.dependencies]
|
||||
tokio = { version = "^1.23.0", default-features = false, features = [
|
||||
tokio = { version = "^1.36.0", default-features = false, features = [
|
||||
"macros",
|
||||
"sync",
|
||||
"time",
|
||||
"rt",
|
||||
"rt-multi-thread",
|
||||
] }
|
||||
concat-idents = "^1.1"
|
||||
dirs = "^4.0"
|
||||
|
||||
@@ -26,6 +26,7 @@ inotify.workspace = true
|
||||
|
||||
mio.workspace = true
|
||||
tokio.workspace = true
|
||||
# console-subscriber = "0.2.0"
|
||||
|
||||
# cli and logging
|
||||
log.workspace = true
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
// - If udev sees device removed then remove the zbus path
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use log::{debug, error, info, warn};
|
||||
use mio::{Events, Interest, Poll, Token};
|
||||
use rog_aura::aura_detection::LaptopLedData;
|
||||
use rog_aura::usb::AuraDevice;
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::task::spawn_blocking;
|
||||
use udev::{Device, MonitorBuilder};
|
||||
// use zbus::fdo::ObjectManager;
|
||||
use zbus::object_server::SignalContext;
|
||||
@@ -29,7 +29,7 @@ pub struct AuraManager {
|
||||
}
|
||||
|
||||
impl AuraManager {
|
||||
pub async fn new(mut connection: Connection) -> Result<Self, RogError> {
|
||||
pub async fn new(connection: Connection) -> Result<Self, RogError> {
|
||||
let conn_copy = connection.clone();
|
||||
let data = LaptopLedData::get_data();
|
||||
let mut interfaces = HashSet::new();
|
||||
@@ -42,20 +42,15 @@ impl AuraManager {
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&connection)?;
|
||||
let sig_ctx2 = sig_ctx.clone();
|
||||
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
|
||||
start_tasks(zbus, &mut connection, sig_ctx2, &path).await?;
|
||||
start_tasks(zbus, connection.clone(), sig_ctx2, path).await?;
|
||||
}
|
||||
|
||||
// connection.object_server().at("/org/asuslinux",
|
||||
// ObjectManager).await.unwrap();
|
||||
|
||||
let manager = Self {
|
||||
_connection: connection,
|
||||
};
|
||||
|
||||
// detect all plugged in aura devices (eventually)
|
||||
let interfaces = Arc::new(Mutex::new(interfaces));
|
||||
let mut count = 0;
|
||||
tokio::spawn(async move {
|
||||
spawn_blocking(move || {
|
||||
let mut monitor = MonitorBuilder::new()?.match_subsystem("hidraw")?.listen()?;
|
||||
let mut poll = Poll::new()?;
|
||||
let mut events = Events::with_capacity(1024);
|
||||
@@ -66,135 +61,107 @@ impl AuraManager {
|
||||
if poll.poll(&mut events, None).is_err() {
|
||||
continue;
|
||||
}
|
||||
// collect and sort so remove events are first
|
||||
// let mut events: Vec<udev::Event> = monitor.iter().filter(|e|
|
||||
// &*e.action().unwrap_or_default() == "remove").collect();
|
||||
// let mut adds: Vec<udev::Event> = monitor.iter().filter(|e|
|
||||
// &*e.action().unwrap_or_default() == "add").collect();
|
||||
// events.append(&mut adds);
|
||||
|
||||
dbg!("LOOPED", count);
|
||||
count += 1;
|
||||
for event in monitor.iter() {
|
||||
if event.parent_with_subsystem("hidraw").is_err() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(parent) =
|
||||
let parent = if let Some(parent) =
|
||||
event.parent_with_subsystem_devtype("usb", "usb_device")?
|
||||
{
|
||||
let action = if let Some(action) = event.action() {
|
||||
action
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
parent
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let id_product =
|
||||
if let Some(id_product) = parent.attribute_value("idProduct") {
|
||||
id_product.to_string_lossy()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let aura_device = AuraDevice::from(&*id_product);
|
||||
if aura_device == AuraDevice::Unknown {
|
||||
warn!("idProduct:{id_product:?} is unknown, not using");
|
||||
let action = if let Some(action) = event.action() {
|
||||
action
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let id_product = if let Some(id_product) = parent.attribute_value("idProduct") {
|
||||
id_product.to_string_lossy()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let path = if let Some(path) = dbus_path_for_dev(&parent) {
|
||||
path
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let aura_device = AuraDevice::from(&*id_product);
|
||||
if aura_device == AuraDevice::Unknown {
|
||||
warn!("idProduct:{id_product:?} is unknown, not using");
|
||||
continue;
|
||||
}
|
||||
|
||||
if action == "remove" {
|
||||
if interfaces.remove(&path) {
|
||||
info!("AuraManager removing: {path:?}");
|
||||
let conn_copy = conn_copy.clone();
|
||||
tokio::spawn(async move {
|
||||
let res = conn_copy
|
||||
.object_server()
|
||||
.remove::<CtrlAuraZbus, _>(&path)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("Failed to remove {path:?}, {e:?}");
|
||||
e
|
||||
})?;
|
||||
info!("AuraManager removed: {path:?}, {res}");
|
||||
Ok::<(), RogError>(())
|
||||
});
|
||||
}
|
||||
} else if action == "add" {
|
||||
if interfaces.contains(&path) {
|
||||
debug!("Already a ctrl at {path:?}");
|
||||
continue;
|
||||
}
|
||||
|
||||
let path = if let Some(path) = dbus_path_for_dev(&parent) {
|
||||
path
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
dbg!(action, &aura_device, &path);
|
||||
if action == "remove" {
|
||||
info!("AuraManager removing: {path:?}");
|
||||
let conn_copy = conn_copy.clone();
|
||||
let interfaces_copy = interfaces.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut interfaces = interfaces_copy.lock().await; // hold until completed
|
||||
dbg!(&interfaces);
|
||||
if interfaces.remove(&path) {
|
||||
let res = conn_copy
|
||||
.object_server()
|
||||
.remove::<CtrlAuraZbus, _>(&path)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("Failed to remove {path:?}, {e:?}");
|
||||
e
|
||||
})?;
|
||||
info!("AuraManager removed: {path:?}, {res}");
|
||||
}
|
||||
dbg!(&interfaces);
|
||||
Ok::<(), RogError>(())
|
||||
});
|
||||
} else if action == "add" {
|
||||
if let Some(p2) = event.parent() {
|
||||
if let Some(driver) = p2.driver() {
|
||||
// There is a tree of devices added so filter by driver
|
||||
if driver != "asus" {
|
||||
debug!("{id_product:?} driver was not asus, skipping");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Need to check the driver is asus to prevent using hid_generic
|
||||
if let Some(p2) = event.parent() {
|
||||
if let Some(driver) = p2.driver() {
|
||||
// There is a tree of devices added so filter by driver
|
||||
if driver != "asus" {
|
||||
debug!("{id_product:?} driver was not asus, skipping");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let path = if let Some(path) = dbus_path_for_dev(&parent) {
|
||||
path
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let dev_node = if let Some(dev_node) = event.devnode() {
|
||||
dev_node.to_owned()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Some(dev_node) = event.devnode() {
|
||||
if let Ok(raw) = HidRaw::from_device(event.device())
|
||||
.map_err(|e| error!("device path error: {e:?}"))
|
||||
{
|
||||
// bah... shitty clone TODO: fix
|
||||
let data_clone = data.clone();
|
||||
let mut conn_copy = conn_copy.clone();
|
||||
let interfaces_copy = interfaces.clone();
|
||||
//
|
||||
tokio::spawn(async move {
|
||||
let mut interfaces = interfaces_copy.lock().await;
|
||||
dbg!(&interfaces);
|
||||
if interfaces.contains(&path) {
|
||||
debug!("Already a ctrl at {path:?}");
|
||||
return Ok(());
|
||||
}
|
||||
if let Ok(mut ctrl) =
|
||||
CtrlKbdLed::from_hidraw(raw, path.clone(), &data_clone)
|
||||
{
|
||||
info!(
|
||||
"AuraManager found device at: {dev_node:?}, {path:?}"
|
||||
);
|
||||
debug!("Starting Aura at {path}");
|
||||
interfaces.insert(path.clone());
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
ctrl.config =
|
||||
CtrlKbdLed::init_config(aura_device, &data_clone);
|
||||
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
|
||||
// Now add it to device list
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
start_tasks(zbus, &mut conn_copy, sig_ctx, &path).await?;
|
||||
}
|
||||
dbg!(&interfaces);
|
||||
Ok::<(), RogError>(())
|
||||
}); // Can't get result from here due to
|
||||
// MonitorSocket
|
||||
if let Ok(mut ctrl) =
|
||||
CtrlKbdLed::from_hidraw(raw, path.clone(), &data)
|
||||
{
|
||||
ctrl.config = CtrlKbdLed::init_config(aura_device, &data);
|
||||
interfaces.insert(path.clone());
|
||||
info!("AuraManager starting device at: {dev_node:?}, {path:?}");
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
let conn_copy = conn_copy.clone();
|
||||
tokio::spawn(async move {
|
||||
return tokio::time::timeout(
|
||||
Duration::from_millis(1000),
|
||||
start_tasks(zbus, conn_copy.clone(), sig_ctx, path),
|
||||
)
|
||||
.await;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
// Required for return type on tokio::spawn
|
||||
// Required for return type on spawn
|
||||
#[allow(unreachable_code)]
|
||||
Ok::<(), RogError>(())
|
||||
});
|
||||
@@ -223,20 +190,17 @@ pub(crate) fn dbus_path_for_dev(parent: &Device) -> Option<OwnedObjectPath> {
|
||||
|
||||
async fn start_tasks(
|
||||
mut zbus: CtrlAuraZbus,
|
||||
connection: &mut Connection,
|
||||
signal_ctx: SignalContext<'static>,
|
||||
path: &ObjectPath<'static>,
|
||||
connection: Connection,
|
||||
_signal_ctx: SignalContext<'static>,
|
||||
path: OwnedObjectPath,
|
||||
) -> Result<(), RogError> {
|
||||
let task = zbus.clone();
|
||||
// let task = zbus.clone();
|
||||
// let signal_ctx = signal_ctx.clone();
|
||||
zbus.reload()
|
||||
.await
|
||||
.unwrap_or_else(|err| warn!("Controller error: {}", err));
|
||||
|
||||
connection
|
||||
.object_server()
|
||||
.at(&ObjectPath::from_str_unchecked(path), zbus)
|
||||
.await
|
||||
.unwrap();
|
||||
task.create_tasks(signal_ctx).await.ok();
|
||||
connection.object_server().at(path, zbus).await.unwrap();
|
||||
// TODO: skip this until we keep handles to tasks so they can be killed
|
||||
// task.create_tasks(signal_ctx).await
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ use zbus::fdo::ObjectManager;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// console_subscriber::init();
|
||||
let mut logger = env_logger::Builder::new();
|
||||
logger
|
||||
.parse_default_env()
|
||||
|
||||
Reference in New Issue
Block a user