perf: avoid holding async mutex guards across await points

tokio recommends using a sync mutex with a notifier instead of the
async mutex where possible. Rust forbids holding a sync mutex guard
across await points so we can prevent a potential deadlock this way.

This adds a custom channel based on the tokio mpmc example for
handling gvfs events from callbacks to avoid the async mutex
requirement. Messages are held in a `VecDeque` behind a sync mutex
and the receiver will get notified via the notifier when a message
is added to the queue.

Weak references used in gio callbacks in case the sender is dropped
by the application.
This commit is contained in:
Michael Aaron Murphy 2026-04-14 16:38:56 +02:00
parent 971374f60b
commit e35d5123f0
No known key found for this signature in database
GPG key ID: B2732D4240C9212C
5 changed files with 139 additions and 39 deletions

View file

@ -6958,8 +6958,7 @@ impl Application for App {
|_| {
stream::channel(
1,
move |msg_tx: futures::channel::mpsc::Sender<_>| async move {
let msg_tx = Arc::new(tokio::sync::Mutex::new(msg_tx));
move |mut msg_tx: futures::channel::mpsc::Sender<_>| async move {
tokio::task::spawn_blocking(move || {
match notify_rust::Notification::new()
.summary(&fl!("notification-in-progress"))
@ -6969,8 +6968,6 @@ impl Application for App {
Ok(notification) => {
let _ = futures::executor::block_on(async {
msg_tx
.lock()
.await
.send(Message::Notification(Arc::new(
Mutex::new(notification),
)))