Cancellation safety of locks in `select!`

⚓ Rust    📅 2025-12-27    👤 surdeus    👁️ 3      

surdeus

In the documentation for tokio’s select macro, it’s mentioned in the “Cancellation Safety” section that locking Mutex and RwLock is not cancellation safe and may lead to losing place in the queue. I assume this applies to something like

tokio::select! {
  mut locked = mutex.lock() => // blah
  // other branches
}

My question is: would I still lose my place in the queue if I avoid dropping the lock future?
In particular something like this

let mutex = tokio::sync::Mutex::new(123);

// create the lock future
let mut mutex_lock = std::pin::pin!(mutex.lock());

tokio::select! {
  mut locked = &mut mutex_lock => {
    // blah
    // once the lock future is used, replace it with a new one (if selecting in a loop)
    std::pin::Pin::set(&mut mutex_lock, mutex.lock());
  },
  // other branches
}

Here, the lock future is not dropped when select picks another branch. Is this enough the ensure cancellation safety (not losing my place in the queue)? Or am I missing some potential pitfalls?

playground link

6 posts - 3 participants

Read full topic

🏷️ Rust_feed