Repository navigation
feat(rwlock): add an upgradable readers-writer lock - #366
Kaileshwar16 wants to merge 2 commits into
Conversation
orthur2
left a comment
There was a problem hiding this comment.
Thanks for taking this on. The reservation protocol and the cancellation paths look sound to me.
On the borrowed guards question, I think they’re fine for a first version. The existing owned guards hold an Arc<RwLock>, which we can’t get by projecting an Arc<UpgradableRwLock>, so owned support couldn’t reuse them as they are.
Please also add UpgradableRwLock to the API map in lib.rs and README.
|
|
||
| ### New features | ||
|
|
||
| * Add `rwlock::UpgradableRwLock` with a single upgradable reader, atomic upgrade and downgrade, and cancellation that releases a pending upgrade's guard; writers and upgradable readers share a FIFO reservation while ordinary readers use the data-permit queue. |
There was a problem hiding this comment.
Please move this under Unreleased. After a rebase it lands in ## v0.7.4.
| /// This consumes the guard. Dropping the future releases the original reader slot, any | ||
| /// partially or fully assigned upgrade permits, and the reservation. This also holds if the | ||
| /// future has never been polled. The original guard is not returned on cancellation. | ||
| pub async fn upgrade(self) -> RwLockWriteGuard<'a, T> { |
There was a problem hiding this comment.
Because the guard derefs to T, this method shadows any upgrade on the value. For example, with UpgradableRwLock<Weak>, guard.upgrade() returns this future instead of calling Weak::upgrade.
Could we make upgrade and try_upgrade associated functions, as map already is for the same reason? Switching after a release would be a breaking change. downgrade can stay a method, as on RwLockWriteGuard.
e675886 to
4c117c6
Compare
Closes #169.
Add
UpgradableRwLockwith ordinary readers, exclusive writers, and one upgradablereader. Support asynchronous upgrade, guard-preserving
try_upgrade(), and downgrade toan ordinary reader.
Cancelling a pending upgrade releases the consumed guard and its permits. Include rustdoc
examples and deterministic tests for ordering, cancellation, reader limits, cross-thread
visibility, and guard traits.
Design Notes
Reuse the existing RwLock and semaphore implementation. Writers and upgradable readers
acquire a FIFO reservation before requesting data permits, preventing an upgrade from
queuing behind a writer waiting for the upgrader’s read permit.
Ordering is FIFO within each queue, rather than globally: ordinary readers can pass
writers waiting for the reservation. Existing RwLock behavior remains unchanged.
Validation:
cargo x lintandcargo x checkpassed.cargo x test: 625 passed.cargo x miri: 194 passed, 10 existing skips.This is an initial implementation intended to help settle the API design in #169. I'd especially appreciate feedback on the two-queue fairness model, cancellation semantics for a pending upgrade, and whether borrowed guards are sufficient for the first version. I'm happy to adjust the design based on maintainer feedback.