Is there such-thing as an "owner-limited RwLock"?

Imagine you are writing a program that requires only a single static owner of a write-lock (by this, I mean that the owner which requests a write lock is called in only 1 closure and no more), but need multi-threaded read access via something like an Arc. The write-lock is thus only ever executed on one thread within 1 closure, and the read-locks are distributed throughout the program on possibly multiple threads. Is there a design that has this idea in mind? Or, would this just have to be manually implemented?

How is that meaningfully different from a normal RwLock?

The two are very similar indeed. In a matter of fact, both can accomplish what needs to be done, but where it differs is when Arc steps-in: Arc allows for the distribution of multiple callers of the write() function from different threads; I, however, only want a single caller. It would be optimized in the sense that there would be only 1 owner of the &mut T from a single thread and closure, but with possibly infinitely many &T's scattered across different threads and closures.

Here you go:

struct CanOnlyReadLock<T> {
    inner: Arc<RwLock<T>>,
}
impl<T> CanOnlyReadLock<T> {
    pub fn new(t: T) -> (Arc<RwLock<T>>, Self) {
        let lock = Arc::new(RwLock::new(t));
        let lock2 = lock.clone();
        (lock, Self { inner: lock2 })
    }
    pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
        self.inner.read()
    }
    pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
        self.inner.try_read()
    }
}

playground

2 Likes

You won't be able to make it faster by somehow making use of the fact that there is only one writer. You still have to lock and unlock the writer to allow immutable access when the writer isn't using it.

RwLock requires T: Send + Sync for its Sync, but in this "owner-limited" design you could get away with giving readers a handle that only requires T: Sync.

2 Likes

You're awesome @alice <3 !!

I suppose you are right... the inner sempahore would be ultimately rate-limiting.