Skip to content

Commit a91dab6

Browse files
committed
fix(CompositeDevice): asyncronously fetch target capabilities instead of blocking
1 parent 8425f13 commit a91dab6

File tree

3 files changed

+35
-33
lines changed

3 files changed

+35
-33
lines changed

src/input/composite_device/mod.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -334,16 +334,7 @@ impl CompositeDevice {
334334
}
335335
}
336336
CompositeCommand::GetTargetCapabilities(sender) => {
337-
let target_caps = match self.targets.get_capabilities().await {
338-
Ok(caps) => caps,
339-
Err(e) => {
340-
log::error!("Failed to get target capabilities: {e:?}");
341-
continue;
342-
}
343-
};
344-
if let Err(e) = sender.send(target_caps).await {
345-
log::error!("Failed to send target capabilities: {:?}", e);
346-
}
337+
self.targets.send_capabilities(sender);
347338
}
348339
CompositeCommand::SetInterceptMode(mode) => self.set_intercept_mode(mode).await,
349340
CompositeCommand::GetInterceptMode(sender) => {

src/input/composite_device/targets.rs

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use std::{
44
time::Duration,
55
};
66

7-
use tokio::sync::mpsc::{self, Sender};
7+
use tokio::{
8+
sync::mpsc::{self, Sender},
9+
task::JoinSet,
10+
};
811
use zbus::Connection;
912

1013
use crate::{
@@ -388,33 +391,41 @@ impl CompositeDeviceTargets {
388391
}
389392
}
390393

391-
// Get the capabilities of all target devices
392-
pub async fn get_capabilities(&self) -> Result<HashSet<Capability>, Box<dyn Error>> {
393-
let mut target_caps = HashSet::new();
394+
/// Get the capabilities of all target devices and send the result to the
395+
/// given channel.
396+
pub fn send_capabilities(&self, sender: Sender<HashSet<Capability>>) {
397+
// Use a JoinSet to query all targets simultaneously
398+
let mut tasks = JoinSet::new();
394399
for target in self.target_devices.values() {
395-
let caps = match target.get_capabilities().await {
396-
Ok(caps) => caps,
397-
Err(e) => {
398-
return Err(format!("Failed to get target capabilities: {e:?}").into());
399-
}
400-
};
401-
for cap in caps {
402-
target_caps.insert(cap);
403-
}
400+
let target = target.clone();
401+
tasks.spawn(async move { target.get_capabilities().await });
404402
}
405403
for target in self.target_dbus_devices.values() {
406-
let caps = match target.get_capabilities().await {
407-
Ok(caps) => caps,
408-
Err(e) => {
409-
return Err(format!("Failed to get target capabilities: {e:?}").into());
404+
let target = target.clone();
405+
tasks.spawn(async move { target.get_capabilities().await });
406+
}
407+
408+
// Collect the results in a task and send them to the given channel
409+
tokio::task::spawn(async move {
410+
let mut target_caps = HashSet::new();
411+
let results = tasks.join_all().await;
412+
for result in results {
413+
let caps = match result {
414+
Ok(caps) => caps,
415+
Err(e) => {
416+
log::warn!("Failed to get target capabilities: {e}");
417+
continue;
418+
}
419+
};
420+
for cap in caps {
421+
target_caps.insert(cap);
410422
}
411-
};
412-
for cap in caps {
413-
target_caps.insert(cap);
414423
}
415-
}
416424

417-
Ok(target_caps)
425+
if let Err(e) = sender.send(target_caps).await {
426+
log::error!("Failed to send target capabilities: {e}");
427+
}
428+
});
418429
}
419430

420431
/// Update the target capabilities of the given target device

src/input/target/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub enum ClientError {
2929
#[error("failed to try to send command to device: {0}")]
3030
TrySendError(TrySendError<TargetCommand>),
3131
#[error("service encountered an error processing the request: {0}")]
32-
ServiceError(Box<dyn std::error::Error>),
32+
ServiceError(Box<dyn std::error::Error + Send + Sync>),
3333
#[error("device no longer exists")]
3434
ChannelClosed,
3535
}

0 commit comments

Comments
 (0)