Skip to content

Commit 5b1daa6

Browse files
committed
clean up docs
1 parent 80ae3bb commit 5b1daa6

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

library/std/src/sync/rwlock.rs

+45-3
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ impl<T> From<T> for RwLock<T> {
573573
}
574574

575575
impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
576-
/// Create a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
576+
/// Creates a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
577577
///
578578
/// # Safety
579579
///
@@ -964,9 +964,51 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
964964

965965
/// Downgrades a write-locked `RwLockWriteGuard` into a read-locked [`RwLockReadGuard`].
966966
///
967-
/// Atomically changes the state of the [`RwLock`] from exclusive mode into shared mode.
967+
/// This method will atomically change the state of the [`RwLock`] from exclusive mode into
968+
/// shared mode. This means that it is impossible for a writing thread to get in between a
969+
/// thread calling `downgrade` and the same thread reading whatever it wrote while it had the
970+
/// [`RwLock`] in write mode.
968971
///
969-
/// FIXME MORE DOCS COMING SOON.
972+
/// Note that since we have the `RwLockWriteGuard`, we know that the [`RwLock`] is already
973+
/// locked for writing, so this method cannot fail.
974+
///
975+
/// # Example
976+
///
977+
/// ```
978+
/// #![feature(rwlock_downgrade)]
979+
/// use std::sync::{Arc, RwLock, RwLockWriteGuard};
980+
///
981+
/// // The inner value starts as 0.
982+
/// let rw = Arc::new(RwLock::new(0));
983+
///
984+
/// // Put the lock in write mode.
985+
/// let mut main_write_guard = rw.write().unwrap();
986+
///
987+
/// let evil = rw.clone();
988+
/// let handle = std::thread::spawn(move || {
989+
/// // This will not return until the main thread drops the `main_read_guard`.
990+
/// let mut evil_guard = evil.write().unwrap();
991+
///
992+
/// assert_eq!(*evil_guard, 1);
993+
/// *evil_guard = 2;
994+
/// });
995+
///
996+
/// // After spawning the writer thread, set the inner value to 1.
997+
/// *main_write_guard = 1;
998+
///
999+
/// // Atomically downgrade the write guard into a read guard.
1000+
/// let main_read_guard = RwLockWriteGuard::downgrade(main_write_guard);
1001+
///
1002+
/// // Since `downgrade` is atomic, the writer thread cannot have set the inner value to 2.
1003+
/// assert_eq!(*main_read_guard, 1, "`downgrade` was not atomic");
1004+
///
1005+
/// // Clean up everything now
1006+
/// drop(main_read_guard);
1007+
/// handle.join().unwrap();
1008+
///
1009+
/// let final_check = rw.read().unwrap();
1010+
/// assert_eq!(*final_check, 2);
1011+
/// ```
9701012
#[unstable(feature = "rwlock_downgrade", issue = "128203")]
9711013
pub fn downgrade(s: Self) -> RwLockReadGuard<'a, T> {
9721014
let lock = s.lock;

library/std/src/sys/sync/rwlock/teeos.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,6 @@ impl RwLock {
4545
#[inline]
4646
pub unsafe fn downgrade(&self) {
4747
// Since there is no difference between read-locked and write-locked on this platform, this
48-
// function is a no-op.
48+
// function is simply a no-op as only 1 reader can read - the original writer.
4949
}
5050
}

0 commit comments

Comments
 (0)