From 835f213e499da76413f66895dfb3ae7a4954b9c47f7a5951c3e16f9b782d7147 Mon Sep 17 00:00:00 2001 From: sisungo Date: Sun, 6 Sep 2026 10:52:23 +0000 Subject: [PATCH] feat: add wait-for-idle Signed-off-by: sisungo --- cli/src/main.rs | 3 +++ cli/src/wait_for_idle.rs | 11 +++++++++++ daemon/src/device.rs | 20 ++++++++++++++++++++ daemon/src/ipc.rs | 6 ++++++ libs/ipc/src/client.rs | 4 ++++ libs/ipc/src/repr.rs | 3 +++ 6 files changed, 47 insertions(+) create mode 100644 cli/src/wait_for_idle.rs diff --git a/cli/src/main.rs b/cli/src/main.rs index ba79b77..a851695 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,16 +1,19 @@ mod trigger; +mod wait_for_idle; use clap::Parser; #[derive(Debug, Parser)] enum Cli { Trigger(trigger::Cli), + WaitForIdle(wait_for_idle::Cli), } fn main() { let cli = Cli::parse(); let result = match cli { Cli::Trigger(cli) => trigger::main(cli), + Cli::WaitForIdle(cli) => wait_for_idle::main(cli), }; if let Err(err) = result { eprintln!("device: error: {err}"); diff --git a/cli/src/wait_for_idle.rs b/cli/src/wait_for_idle.rs new file mode 100644 index 0000000..a4f174d --- /dev/null +++ b/cli/src/wait_for_idle.rs @@ -0,0 +1,11 @@ +use clap::Parser; +use ipc::client::Client; + +#[derive(Debug, Parser)] +pub struct Cli {} + +pub fn main(_: Cli) -> anyhow::Result<()> { + let mut client = Client::connect()?; + client.wait_for_idle()?; + Ok(()) +} diff --git a/daemon/src/device.rs b/daemon/src/device.rs index 166894a..06004e5 100644 --- a/daemon/src/device.rs +++ b/daemon/src/device.rs @@ -201,6 +201,26 @@ pub async fn list_devices(when: When) -> Vec { ret } +pub async fn wait_for_idle() { + loop { + let mut waited = false; + let keys: Vec = DEVICES.read().unwrap().keys().map(Into::into).collect(); + for key in keys { + let Some(device) = DEVICES.read().unwrap().get(&key).cloned() else { + continue; + }; + if device.lock.try_lock().is_ok() { + continue; + } + waited = true; + _ = device.lock.lock().await; + } + if !waited { + return; + } + } +} + fn dev_root() -> PathBuf { std::env::var("LXDEVICED_DEV_ROOT") .as_deref() diff --git a/daemon/src/ipc.rs b/daemon/src/ipc.rs index b8f151a..bd462c5 100644 --- a/daemon/src/ipc.rs +++ b/daemon/src/ipc.rs @@ -34,6 +34,7 @@ async fn handle_connection(mut connection: Connection) -> std::io::Result<()> { Request::Trigger(set, action) => handler(trigger(set, action)), Request::ReloadRules => handler(reload_rules()), Request::ListDevices(when) => handler(list_devices(when)), + Request::WaitForIdle => handler(wait_for_idle()), }; let reply = handler.await; connection.send(reply).await?; @@ -57,6 +58,11 @@ async fn list_devices(when: When) -> Result, Error> { Ok(crate::device::list_devices(when).await) } +async fn wait_for_idle() -> Result<(), Error> { + crate::device::wait_for_idle().await; + Ok(()) +} + fn handler( fut: impl Future> + Send + 'static, ) -> Pin> + Send>> { diff --git a/libs/ipc/src/client.rs b/libs/ipc/src/client.rs index 71fc76b..0422abf 100644 --- a/libs/ipc/src/client.rs +++ b/libs/ipc/src/client.rs @@ -60,4 +60,8 @@ impl Client { pub fn list_devices(&mut self, when: When) -> Result, Error> { self.invoke(&Request::ListDevices(when)) } + + pub fn wait_for_idle(&mut self) -> Result<(), Error> { + self.invoke(&Request::WaitForIdle) + } } diff --git a/libs/ipc/src/repr.rs b/libs/ipc/src/repr.rs index c92847e..1cccf86 100644 --- a/libs/ipc/src/repr.rs +++ b/libs/ipc/src/repr.rs @@ -12,6 +12,9 @@ pub enum Request { #[serde(rename = "/org.semilabs.os/LxDeviced/ListDevices@LXDEVICED_0.1.0")] ListDevices(When), + + #[serde(rename = "/org.semilabs.os/LxDeviced/WaitForIdle@LXDEVICED_0.1.0")] + WaitForIdle, } pub fn ser_reply(result: Result) -> String {