From 55401b1e53661a91f13269b2266c6429d2d7ff10 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Tue, 17 Jun 2025 17:50:30 -0700 Subject: [PATCH] dbus: Use `ThreadPool` instead of zbus blocking API The `zbus` blocking API just wraps the async API with `block_on`, so we may as well use our own executor. --- Cargo.lock | 1 + Cargo.toml | 1 + src/dbus/mod.rs | 37 +++++++++++++++---------------------- src/dbus/power.rs | 10 +++++----- src/state.rs | 6 ++++-- 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5e28b32..46f9128a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -834,6 +834,7 @@ dependencies = [ "egui", "egui_plot", "futures-executor", + "futures-util", "i18n-embed", "i18n-embed-fl", "iced_tiny_skia", diff --git a/Cargo.toml b/Cargo.toml index 394d19f8..409f3e32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,6 +88,7 @@ clap_lex = "0.7" parking_lot = "0.12.5" logind-zbus = { version = "5.3.2", optional = true } futures-executor = { version = "0.3.31", features = ["thread-pool"] } +futures-util = "0.3.31" [dependencies.id_tree] branch = "feature/copy_clone" diff --git a/src/dbus/mod.rs b/src/dbus/mod.rs index d66fa665..7f20c72b 100644 --- a/src/dbus/mod.rs +++ b/src/dbus/mod.rs @@ -5,6 +5,8 @@ use crate::{ use anyhow::{Context, Result}; use calloop::{InsertError, LoopHandle, RegistrationToken}; use cosmic_comp_config::output::comp::OutputState; +use futures_executor::{ThreadPool, block_on}; +use futures_util::stream::StreamExt; use std::collections::HashMap; use tracing::{error, warn}; use zbus::blocking::{Connection, fdo::DBusProxy}; @@ -13,10 +15,13 @@ use zbus::blocking::{Connection, fdo::DBusProxy}; pub mod logind; mod power; -pub fn init(evlh: &LoopHandle<'static, State>) -> Result> { +pub fn init( + evlh: &LoopHandle<'static, State>, + executor: &ThreadPool, +) -> Result> { let mut tokens = Vec::new(); - match power::init() { + match block_on(power::init()) { Ok(power_daemon) => { let (tx, rx) = calloop::channel::channel(); @@ -56,29 +61,17 @@ pub fn init(evlh: &LoopHandle<'static, State>) -> Result> .with_context(|| "Failed to add channel to event_loop")?; // start helper thread - let result = std::thread::Builder::new() - .name("system76-power-hotplug".to_string()) - .spawn(move || { - if let Ok(msg_iter) = power_daemon.receive_hot_plug_detect() { - for msg in msg_iter { - if tx.send(msg).is_err() { - break; - } + executor.spawn_ok(async move { + if let Ok(mut msg_iter) = power_daemon.receive_hot_plug_detect().await { + while let Some(msg) = msg_iter.next().await { + if tx.send(msg).is_err() { + break; } } - }) - .with_context(|| "Failed to start helper thread"); + } + }); - match result { - Ok(_handle) => { - tokens.push(token); - // detach thread - } - Err(err) => { - evlh.remove(token); - return Err(err); - } - } + tokens.push(token); } Err(err) => { tracing::info!(?err, "Failed to connect to com.system76.PowerDaemon"); diff --git a/src/dbus/power.rs b/src/dbus/power.rs index 9d9d37b6..346b8107 100644 --- a/src/dbus/power.rs +++ b/src/dbus/power.rs @@ -18,7 +18,7 @@ //! //! …consequently `zbus-xmlgen` did not generate code for the above interfaces. -use zbus::blocking::Connection; +use zbus::Connection; #[zbus::proxy( interface = "com.system76.PowerDaemon", @@ -79,9 +79,9 @@ pub trait PowerDaemon { fn power_profile_switch(&self, profile: &str) -> zbus::Result<()>; } -pub fn init() -> anyhow::Result> { - let conn = Connection::system()?; - let proxy = PowerDaemonProxyBlocking::new(&conn)?; - proxy.0.introspect()?; +pub async fn init() -> anyhow::Result> { + let conn = Connection::system().await?; + let proxy = PowerDaemonProxy::new(&conn).await?; + proxy.0.introspect().await?; Ok(proxy) } diff --git a/src/state.rs b/src/state.rs index 1dc7b6ef..3d755e4a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -696,7 +696,9 @@ impl State { ); let workspace_state = WorkspaceState::new(dh, client_not_sandboxed); - if let Err(err) = crate::dbus::init(&handle) { + let async_executor = ThreadPool::builder().pool_size(1).create().unwrap(); + + if let Err(err) = crate::dbus::init(&handle, &async_executor) { tracing::warn!(?err, "Failed to initialize dbus handlers"); } @@ -712,7 +714,7 @@ impl State { display_handle: dh.clone(), event_loop_handle: handle, event_loop_signal: signal, - async_executor: ThreadPool::builder().pool_size(1).create().unwrap(), + async_executor, popups: PopupManager::default(), shell,