Is there any explicit reason as to why RWLock can’t simply try to upgrade the read-lock to write-lock given they’re both being held by the same thread?
Rust's Sneaky Deadlock With `if let` Blocks
31–40 of 85 posts
Re: Rust's Sneaky Deadlock With `if let` Blocks
#32Re: Rust's Sneaky Deadlock With `if let` Blocks
#33Re: Rust's Sneaky Deadlock With `if let` Blocks
#34Is there any explicit reason as to why RWLock can’t simply try to upgrade the read-lock to write-lock given they’re both being held by the same thread?
Yes, allowing this to execute would be very unsound: let lock = RwLock::new(Box::new(111)); let r: &i32 = &**lock.read().unwrap(); // points to 111 *lock.write().unwrap() = Box::new(222); // allocates a new Box and deallocates 111 println!("{}", *r); // use after free
let lock = RwLock::new(Box::new(111));
let read = lock.upgradable_read();
let r: &i32 = &**read; // points to 111
*RwLockUpgradableReadGuard::upgrade(read) = Box::new(222); // error[E0505]: cannot move out of `read` because it is borrowed
println!("{}", *r);Re: Rust's Sneaky Deadlock With `if let` Blocks
#35Earlier quoted context omitted.
Yes, allowing this to execute would be very unsound: let lock = RwLock::new(Box::new(111)); let r: &i32 = &**lock.read().unwrap(); // points to 111 *lock.write().unwrap() = Box::new(222); // allocates a new Box and deallocates 111 println!("{}", *r); // use after free
It can be done safely with an upgrade method that requires an owned read guard. The RwLock implementation provided by the parking_lot crate supports this safely: let lock = RwLock::new(Box::new(111)); let read = lock.upgradable_read(); let r: &i32 = &**read; // points to 111 *RwLockUpgradableReadGuard::upgrade(read) = Box::new(222); // error[E0505]: cannot move out of `read` because it is borrowed println!("{}", *r);
Re: Rust's Sneaky Deadlock With `if let` Blocks
#36A lock taken in the conditional test term should lock for the duration of the if-clause. If you release the lock early, you add the risk of a race condition, where some other thread executes between the test and the execution of the if or else clause, changing the state.
Re: Rust's Sneaky Deadlock With `if let` Blocks
#37Happy to be corrected, but from what I gathered RWLock should mostly be avoided in favour of a simple Mutex unless you have a very read-heavy usecase and even then the performances are subpar compared to mutex.
Re: Rust's Sneaky Deadlock With `if let` Blocks
#38Quoted post unavailable.
Re: Rust's Sneaky Deadlock With `if let` Blocks
#39Earlier quoted context omitted.
This really reads like satire but feels like the author is actually being sincere. I’ve seen so many deadlocks happening due to pthread mutexes. Certainly way more than this syntactic corner case. It’s so common in fact that I saw a codebase that made their mutexes recursive to avoid having to think about it.
[flagged]
Re: Rust's Sneaky Deadlock With `if let` Blocks
#40Earlier quoted context omitted.
Did they just miss this in the spec?
From my understanding: The original implementation is consistent with the behavior of `match`. However it was realized that it is both less intuitive than early dropping (as this post suggests) and also gets in the way of understandable semantics for if let chains, so the decision was made to change it in the next edition. match still retains the old behavior.