Deadlock caused by watch::Sender::send_if_modified

My program runs into a deadlock when trying to invoke send_if_notified. I looked under the hood and Sender seems to be using an RwLock internally, but the documentation does not mention what are safe / unsafe ways of using watch::Sender / Receiver. What are the situations that could lead to a deadlock?

Two things:

  1. Don't take the lock twice from a single task, e.g. don't try to send while holding the lock.
  2. Never keep it locked when you perform an .await. (Only applies if you're in a !Send environment with e.g. spawn_local.)
1 Like

Does this hold the lock:

let rx: Receiver<Whatever> = ...;
select! {
     _ = r.changed() => {
       // does it hold any locks here and is it safe to directly update the corresponding  sender here in the same thread?
    }
}

The lock is held whenever a tokio::sync::watch::Ref object exists. Since changed does not return such an object, the lock is not held inside the select.

1 Like