-
IntroI really don't know where to ask this. I looks more like a Rust behavior. But since my doubt started from tokio, I'd like to discuss it here. PreludeSuppose I have a struct MutexWrapper {
mutex: tokio::sync::Mutex<()>,
...
}
impl Deref<Target = Mutex> for MutexWrapper { ... } I also have a struct that dispatches these "named" mutexes to ensure there's only one corresponding to an id. I don't know if it's relevant, but it looks like this: struct IDLock {
inner: Arc<Mutex<HashMap<String, Arc<Mutex<()>>>>>,
...
}
impl Clone for IDLock {
fn clone(&self) -> IDLock {
IDLock { inner: Arc::clone(&self.inner) }
}
}
impl IDLock {
async fn mutex(&self, id: &str) -> MutexWrapper {
let id_mutex = {
// global block to get id's mutex
let mut inner = self.inner.lock().await;
inner.entry(id.to_owned())
.or_insert_with(|| Arc::new(Mutex::new(())) )
.clone()
};
// return custom mutex
// needed for drop calling back home
MutexWrapper { mutex: id_mutex, ... }
}
...
} That way I can access to a "named" mutex for a unique ID. IssueConsider this integration: async fn worker(idl: IDLock, id: String, delay: u64) {
let m = idl.mutex(&id).await;
let _l = m.lock().await;
println!("worker({}) delaying {}s", id, delay);
delay_for(Duration::from_secs(delay)).await;
}
#[tokio::main(core_threads = 2)]
async fn main() {
let id = IDLock::new();
let v = vec![
tokio::spawn(worker(id.clone(), "1".to_owned(), 2)),
tokio::spawn(worker(id.clone(), "1".to_owned(), 3)),
tokio::spawn(worker(id.clone(), "2".to_owned(), 1)),
tokio::spawn(worker(id.clone(), "2".to_owned(), 2)),
tokio::spawn(worker(id.clone(), "3".to_owned(), 2)),
tokio::spawn(worker(id.clone(), "3".to_owned(), 1)),
tokio::spawn(worker(id.clone(), "3".to_owned(), 1)),
];
join_all(v).await;
} This works as intended: all unique ids are concurrently executed but no more than 1 worker is concurrently working on the same id. All good then? Let's make the following change: let _l = m.lock().await; For: let _ = m.lock().await; Surprise! now it DOES NOT work as intended, since all 7 tasks are concurrently executed. ConclusionThe only think I can think of is that the compiler thinks I don't need that variable then it has no effect. But why is it like that? why is |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Assignment uses patterns, and |
Beta Was this translation helpful? Give feedback.
Assignment uses patterns, and
_
is a pattern that discards its value immediately: https://doc.rust-lang.org/book/ch18-01-all-the-places-for-patterns.html#let-statements.