Moving a conversation in a closed GitHub issue over here...
The problem is that Rust is so paranoid about data races, that one has to uses mutexes all over the place (if using shared memory) to fight the borrow checker off. This results then in increased risk of deadlocks due to the fact that locks are not reentrant.
@havelund parking_lot crate provides reentrant mutex if you need it:
I‘m curious what’re the reasons behind not providing reentrant mutex as the default implementation in the standard library?
I think it's because Mutex and friends were originally meant to be wrappers around the native OS synchronization primitives, and some OS mutexes are not reentrant, though I'm not 100% sure on that.
I'd rather say that rentrant mutexes don't make a ton of sense in Rust most of the time.
The idiomatic Rust API for a mutext is to have a lock method which, given a
&Mutex<T>, returns an
&mut T (apropriately wrapped into a guard object). For reentrant mutex, this API doesn't work: you can't return
&mut T because reentrancy allows one to get the second
&mut T, violating aliasing guarantees. And
fn lock(&Mutext<T>) -> &T signature is much less useful, as you naturally just have
&T if you have
Mutex<T>. I think it might makes sense when
T: !Sync, because
ReentrantMutex<T> maybe can be
Sync (not sure about this).