Skip to content

Commit

Permalink
clean up docs
Browse files Browse the repository at this point in the history
  • Loading branch information
connortsui20 committed Aug 16, 2024
1 parent 80ae3bb commit 5b1daa6
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
48 changes: 45 additions & 3 deletions library/std/src/sync/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ impl<T> From<T> for RwLock<T> {
}

impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
/// Create a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
/// Creates a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
///
/// # Safety
///
Expand Down Expand Up @@ -964,9 +964,51 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {

/// Downgrades a write-locked `RwLockWriteGuard` into a read-locked [`RwLockReadGuard`].
///
/// Atomically changes the state of the [`RwLock`] from exclusive mode into shared mode.
/// 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.
///
/// FIXME MORE DOCS COMING SOON.
/// Note that since we have the `RwLockWriteGuard`, we know that the [`RwLock`] is already
/// locked for writing, so this method cannot fail.
///
/// # Example
///
/// ```
/// #![feature(rwlock_downgrade)]
/// 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);
/// ```
#[unstable(feature = "rwlock_downgrade", issue = "128203")]
pub fn downgrade(s: Self) -> RwLockReadGuard<'a, T> {
let lock = s.lock;
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/sync/rwlock/teeos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ impl RwLock {
#[inline]
pub unsafe fn downgrade(&self) {
// Since there is no difference between read-locked and write-locked on this platform, this
// function is a no-op.
// function is simply a no-op as only 1 reader can read - the original writer.
}
}

0 comments on commit 5b1daa6

Please sign in to comment.