Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 53 additions & 17 deletions crates/cardwire-daemon/src/tasks/monitor_udev.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,66 @@
//! Used to listen to other dbus interface, mainly for auto battery switch and display detection

use log::{error, info};
use tokio::io::{Interest, unix::AsyncFd};

use crate::interface::DebugInterface;
use log::{error, info};
use tokio::io::unix::AsyncFd;

/// listen to pci/thunderbolt event and refres the GPU list when necessary
pub async fn monitor_pci_changes(debug_int: DebugInterface) -> zbus::Result<()> {
let udev_monitor = udev::MonitorBuilder::new()?.match_subsystem("pci")?;
let udev_fd = AsyncFd::new(udev_monitor.listen()?)?;
let udev_pci_monitor = udev::MonitorBuilder::new()?.match_subsystem("pci")?;
let udev_pci_fd = AsyncFd::new(udev_pci_monitor.listen()?)?;
let udev_thunderbolt_monitor = udev::MonitorBuilder::new()?.match_subsystem("thunderbolt")?;
let udev_thunderbolt_fd = AsyncFd::new(udev_thunderbolt_monitor.listen()?)?;
loop {
let mut guard = udev_fd.ready(Interest::READABLE).await?;
if guard.ready().is_readable() {
for event in udev_fd.get_ref().iter() {
if let Some(action) = event.action()
&& (action == "bind" || action == "unbind")
{
info!("detected pci event, refreshing GPU interfaces");
match debug_int.refresh_gpu().await {
Ok(()) => {}
Err(e) => {
error!("failed to refresh gpu interface: {}", e);
tokio::select! {
guard_res = udev_pci_fd.readable() => {
match guard_res {
Ok(mut guard) => {
for event in udev_pci_fd.get_ref().iter() {
if let Some(action) = event.action()
&& (action == "bind" || action == "unbind")
{
info!("detected pci event, refreshing GPU interfaces");
match debug_int.refresh_gpu().await {
Ok(()) => {}
Err(e) => {
error!("failed to refresh gpu interface: {}", e);
}
}
}
}
guard.clear_ready();
}
Err(err) => {
error!("[UDEV_MONITOR_PCI]: {:?}", err);
return Err(err.into())
}
}
}
guard_res = udev_thunderbolt_fd.readable() => {
match guard_res {
Ok(mut guard) => {
for event in udev_thunderbolt_fd.get_ref().iter() {
if let Some(action) = event.action()
&& (action == "add" || action == "remove" || action == "change")
// try to match most actions, refreshing isnt that ressource intensive
{
info!("detected pci event, refreshing GPU interfaces");
match debug_int.refresh_gpu().await {
Ok(()) => {}
Err(e) => {
error!("failed to refresh gpu interface: {}", e);
}
}
}
}
guard.clear_ready();
}
Err(err) => {
error!("[UDEV_MONITOR_THUNDERBOLT]: {:?}", err);
return Err(err.into())
}
}
}
}
guard.clear_ready();
}
}
Loading