Skip to content

Stabilize rwlock_downgrade library feature #143191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

connortsui20
Copy link
Contributor

@connortsui20 connortsui20 commented Jun 29, 2025

Tracking Issue: #128203

Method to be stabilized:

impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
    pub fn downgrade(s: Self) -> RwLockReadGuard<'a, T> {}
}

I would like to point out that my documentation comment is longer than ideal, but at the same time I don't really know how else to show why downgrade is actually necessary (instead of just unlocking and relocking). If anyone has ideas for making this more concise that would be great!

Current doc comment

Downgrades a write-locked RwLockWriteGuard into a read-locked [RwLockReadGuard].

This method will atomically change the state of the [RwLock] from exclusive mode into
shared mode. This means that it is impossible for a writing thread to get in between a
thread calling downgrade and the same thread reading whatever it wrote while it had the
[RwLock] in write mode.

Note that since we have the RwLockWriteGuard, we know that the [RwLock] is already
locked for writing, so this method cannot fail.

Example

use std::sync::{Arc, RwLock, RwLockWriteGuard};

// The inner value starts as 0.
let rw = Arc::new(RwLock::new(0));

// Put the lock in write mode.
let mut main_write_guard = rw.write().unwrap();

let evil = rw.clone();
let handle = std::thread::spawn(move || {
    // This will not return until the main thread drops the `main_read_guard`.
    let mut evil_guard = evil.write().unwrap();

    assert_eq!(*evil_guard, 1);
    *evil_guard = 2;
});

// After spawning the writer thread, set the inner value to 1.
*main_write_guard = 1;

// Atomically downgrade the write guard into a read guard.
let main_read_guard = RwLockWriteGuard::downgrade(main_write_guard);

// Since `downgrade` is atomic, the writer thread cannot have set the inner value to 2.
assert_eq!(*main_read_guard, 1, "`downgrade` was not atomic");

// Clean up everything now
drop(main_read_guard);
handle.join().unwrap();

let final_check = rw.read().unwrap();
assert_eq!(*final_check, 2);

Stabilization report: #128203 (comment)

@rustbot
Copy link
Collaborator

rustbot commented Jun 29, 2025

r? @tgross35

rustbot has assigned @tgross35.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jun 29, 2025
@tgross35 tgross35 added the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Jun 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-libs-api-nominated Nominated for discussion during a libs-api team meeting. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants