@@ -1073,49 +1073,61 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
10731073
10741074 /// Downgrades a write-locked `RwLockWriteGuard` into a read-locked [`RwLockReadGuard`].
10751075 ///
1076- /// This method will atomically change the state of the [`RwLock`] from exclusive mode into
1077- /// shared mode. This means that it is impossible for a writing thread to get in between a
1078- /// thread calling `downgrade` and the same thread reading whatever it wrote while it had the
1079- /// [`RwLock`] in write mode.
1076+ /// Since we have the `RwLockWriteGuard`, the [`RwLock`] must already be locked for writing, so
1077+ /// this method cannot fail.
10801078 ///
1081- /// Note that since we have the `RwLockWriteGuard`, we know that the [`RwLock`] is already
1082- /// locked for writing, so this method cannot fail.
1079+ /// After downgrading, other readers will be allowed to read the protected data.
10831080 ///
1084- /// # Example
1081+ /// # Examples
1082+ ///
1083+ /// `downgrade` takes ownership of the `RwLockWriteGuard` and returns a [`RwLockReadGuard`].
1084+ ///
1085+ /// ```
1086+ /// use std::sync::{RwLock, RwLockWriteGuard};
1087+ ///
1088+ /// let rw = RwLock::new(0);
1089+ ///
1090+ /// let mut write_guard = rw.write().unwrap();
1091+ /// *write_guard = 42;
1092+ ///
1093+ /// let read_guard = RwLockWriteGuard::downgrade(write_guard);
1094+ /// assert_eq!(42, *read_guard);
1095+ /// ```
1096+ ///
1097+ /// `downgrade` will _atomically_ change the state of the [`RwLock`] from exclusive mode into
1098+ /// shared mode. This means that it is impossible for another writing thread to get in between a
1099+ /// thread calling `downgrade` and any reads it performs after downgrading.
10851100 ///
10861101 /// ```
10871102 /// use std::sync::{Arc, RwLock, RwLockWriteGuard};
10881103 ///
1089- /// // The inner value starts as 0.
1090- /// let rw = Arc::new(RwLock::new(0));
1104+ /// let rw = Arc::new(RwLock::new(1));
10911105 ///
10921106 /// // Put the lock in write mode.
10931107 /// let mut main_write_guard = rw.write().unwrap();
10941108 ///
1095- /// let evil = rw.clone();
1096- /// let handle = std::thread::spawn(move || {
1109+ /// let rw_clone = rw.clone();
1110+ /// let evil_handle = std::thread::spawn(move || {
10971111 /// // This will not return until the main thread drops the `main_read_guard`.
1098- /// let mut evil_guard = evil .write().unwrap();
1112+ /// let mut evil_guard = rw_clone .write().unwrap();
10991113 ///
1100- /// assert_eq!(*evil_guard, 1 );
1101- /// *evil_guard = 2 ;
1114+ /// assert_eq!(*evil_guard, 2 );
1115+ /// *evil_guard = 3 ;
11021116 /// });
11031117 ///
1104- /// // After spawning the writer thread, set the inner value to 1.
1105- /// *main_write_guard = 1;
1118+ /// *main_write_guard = 2;
11061119 ///
11071120 /// // Atomically downgrade the write guard into a read guard.
11081121 /// let main_read_guard = RwLockWriteGuard::downgrade(main_write_guard);
11091122 ///
1110- /// // Since `downgrade` is atomic, the writer thread cannot have set the inner value to 2.
1111- /// assert_eq!(*main_read_guard, 1, "`downgrade` was not atomic");
1112- ///
1113- /// // Clean up everything now
1114- /// drop(main_read_guard);
1115- /// handle.join().unwrap();
1116- ///
1117- /// let final_check = rw.read().unwrap();
1118- /// assert_eq!(*final_check, 2);
1123+ /// // Since `downgrade` is atomic, the writer thread cannot have changed the protected data.
1124+ /// assert_eq!(*main_read_guard, 2, "`downgrade` was not atomic");
1125+ /// #
1126+ /// # drop(main_read_guard);
1127+ /// # evil_handle.join().unwrap();
1128+ /// #
1129+ /// # let final_check = rw.read().unwrap();
1130+ /// # assert_eq!(*final_check, 3);
11191131 /// ```
11201132 #[ stable( feature = "rwlock_downgrade" , since = "CURRENT_RUSTC_VERSION" ) ]
11211133 pub fn downgrade ( s : Self ) -> RwLockReadGuard < ' a , T > {
0 commit comments