4 ms·
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?
by senorrib 2y ago
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?
- anderskaseorg 2y agoYes, 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
- NobodyNada 2y agoIt 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);
- anderskaseorg 2y agoOf course (but that’s not relevant to the original scenario, where the programmer is hypothetically not aware that the read lock is still being held, let alone that they could manually upgrade it after changing to a different lock library).
- kelnos 2y agoThe problem is that in the 'if let' case, the 'else' block has no access to the read guard. It's out of scope, except that the compiler hasn't dropped it yet.
- webkike 2y agoWould be much more expensive to implement. RwLocks are basically Atomics wrapping a pointer and have no knowledge of who has acquired the lock