Why is the Mutex lock held for the entire match statement?
⚓ Rust 📅 2026-02-11 👤 surdeus 👁️ 1So I was making a concurrent web crawler with BFS expansion to learn concurrency with Tokio in Rust, and for a part I needed to do this:
let queue: Arc<tokio::sync::Mutex<VecDeque<String>>> = Arc::clone(&queue);
let item = {
let mut mutex_guard = queue.lock().await;
mutex_guard.pop_front().await?
};
match item {
Some(item) => todo!(),
None => todo!(),
}
Note: This is a simplified implementation because the actual one is 500+ lines
This works fine, the lock is only held until the pop is done and other workers can also access it, but if I do this:
let queue: Arc<tokio::sync::Mutex<VecDeque<String>>> = Arc::clone(&queue);
match queue.lock().await.pop_front().await? {
Some(item) => todo!(),
None => todo!(),
}
It's locked until the worker finishes the call, and if the worker doesn't find any items in the queue, it waits until other workers finish in the actual implementation, so if there aren't any items in the queue at a given time, the program is deadlocked.
Why does this happen? Why doesn't the MutexGuard get dropped after the pop?
4 posts - 3 participants
🏷️ Rust_feed