Proposal
Problem statement
I would like to be able to avoid pointer casts for unguarded accesses of the inner value of an RwLock, similar to RefCells try_borrow_unguarded.
Motivating examples or use cases
I am the maintainer of the readlock crate.
About this crate
At its core, this crate provides a a few types that can act as a replacement for Arc<RwLock<T>> if only a single clone of that Arc is ever used for writing. This is done by introducing two wrapper types around Arc<RwLock<T>>, Shared<T> which can be used for writing but cannot be cloned, and ReadLock<T> which can be obtained from Shared<T> and cloned, but only used for reading. Splitting the capabilities into two types like this reduces the potential for deadlock bugs for code that fits this pattern, and can allow downstream crates to expose a handle to some internally-managed state in a read-only way without introducing custom lock types.
Its type Shared<T> has shared ownership of an RwLock<T>, but guarantees that no other reference to that RwLock ever locks it for writing. It also requires &mut self for write-locking the inner value. Due to this, it can implement Deref<Target = T>.
To implement Deref<Target = T>, I currently call .read() on the inner RwLock, then (unless there's a PoisonError) dereference the RwLockReadGuard and unsafely lifetime-extend the resulting reference using two casts (to raw pointer and back).
If I could instead call an unsafe fn on the RwLock with clear safety requirements that gives me &T directly w/o going through RwLockReadGuard, it would be a lot easier for me to prove my code sound - I am pretty certain the concept is sound (but happy to be proven wrong), but less certain about the current implementation being sound.
Further, and this may deserve to be split into its own ACP, but it seems worth pointing out here: It should also be sound here, and benefit performance, if the new API also allowed unchecked access to the inner value, i.e. if it did not require any reads the reader / writer count of the RwLock.
Solution sketch
Honestly, I don't know. I guess a direct equivalent of RefCell::try_borrow_unguarded would be possible and solve my bigger problem around soundness, but it would be really nice to get the performance benefits of unchecked access as well.
Alternatives
As described above, I already have an implementation of the sort of thing this would enable, I'm just not sure whether it's sound. See the readlock crate's source if you want to see the details.
Proposal
Problem statement
I would like to be able to avoid pointer casts for unguarded accesses of the inner value of an
RwLock, similar toRefCellstry_borrow_unguarded.Motivating examples or use cases
I am the maintainer of the
readlockcrate.About this crate
At its core, this crate provides a a few types that can act as a replacement for
Arc<RwLock<T>>if only a single clone of thatArcis ever used for writing. This is done by introducing two wrapper types aroundArc<RwLock<T>>,Shared<T>which can be used for writing but cannot be cloned, andReadLock<T>which can be obtained fromShared<T>and cloned, but only used for reading. Splitting the capabilities into two types like this reduces the potential for deadlock bugs for code that fits this pattern, and can allow downstream crates to expose a handle to some internally-managed state in a read-only way without introducing custom lock types.Its type
Shared<T>has shared ownership of anRwLock<T>, but guarantees that no other reference to thatRwLockever locks it for writing. It also requires&mut selffor write-locking the inner value. Due to this, it can implementDeref<Target = T>.To implement
Deref<Target = T>, I currently call.read()on the innerRwLock, then (unless there's aPoisonError) dereference theRwLockReadGuardand unsafely lifetime-extend the resulting reference using two casts (to raw pointer and back).If I could instead call an
unsafe fnon theRwLockwith clear safety requirements that gives me&Tdirectly w/o going throughRwLockReadGuard, it would be a lot easier for me to prove my code sound - I am pretty certain the concept is sound (but happy to be proven wrong), but less certain about the current implementation being sound.Further, and this may deserve to be split into its own ACP, but it seems worth pointing out here: It should also be sound here, and benefit performance, if the new API also allowed unchecked access to the inner value, i.e. if it did not require any reads the reader / writer count of the
RwLock.Solution sketch
Honestly, I don't know. I guess a direct equivalent of
RefCell::try_borrow_unguardedwould be possible and solve my bigger problem around soundness, but it would be really nice to get the performance benefits of unchecked access as well.Alternatives
As described above, I already have an implementation of the sort of thing this would enable, I'm just not sure whether it's sound. See the
readlockcrate's source if you want to see the details.