Skip to content

feat(rwlock): add an upgradable readers-writer lock - #366

Open
Kaileshwar16 wants to merge 2 commits into
apache:mainfrom
Kaileshwar16:feat/169-upgradable-rwlock
Open

Kaileshwar16 wants to merge 2 commits into
apache:mainfrom
Kaileshwar16:feat/169-upgradable-rwlock

Conversation

@Kaileshwar16

Copy link
Copy Markdown
Contributor

Closes #169.

Add UpgradableRwLock with ordinary readers, exclusive writers, and one upgradable
reader. Support asynchronous upgrade, guard-preserving try_upgrade(), and downgrade to
an 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 lint and cargo x check passed.
  • cargo x test: 625 passed.
  • cargo x miri: 194 passed, 10 existing skips.
  • All 24 feature tests passed 20 repetitions and four Miri seeds.

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.

@orthur2
orthur2 self-requested a review October 23, 2026 15:39

@orthur2 orthur2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread CHANGELOG.md

### 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this under Unreleased. After a rebase it lands in ## v0.7.4.

Comment thread asyncband/src/rwlock/upgradable.rs Outdated
/// 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> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Kaileshwar16
Kaileshwar16 force-pushed the feat/169-upgradable-rwlock branch from e675886 to 4c117c6 Compare October 24, 2026 09:53
@Kaileshwar16
Kaileshwar16 requested a review from orthur2 October 24, 2026 09:55

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide an upgradable readers-writer lock

2 participants