@@ -574,8 +574,12 @@ impl<T> From<T> for RwLock<T> {
574
574
575
575
impl < ' rwlock , T : ?Sized > RwLockReadGuard < ' rwlock , T > {
576
576
/// Create a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
577
- // SAFETY: if and only if `lock.inner.read()` (or `lock.inner.try_read()`) has been
578
- // successfully called from the same thread before instantiating this object.
577
+ ///
578
+ /// # Safety
579
+ ///
580
+ /// This function is safe if and only if the same thread has successfully and safely called
581
+ /// `lock.inner.read()`, `lock.inner.try_read()`, or `lock.inner.downgrade()` before
582
+ /// instantiating this object.
579
583
unsafe fn new ( lock : & ' rwlock RwLock < T > ) -> LockResult < RwLockReadGuard < ' rwlock , T > > {
580
584
poison:: map_result ( lock. poison . borrow ( ) , |( ) | RwLockReadGuard {
581
585
data : unsafe { NonNull :: new_unchecked ( lock. data . get ( ) ) } ,
@@ -957,6 +961,25 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
957
961
None => Err ( orig) ,
958
962
}
959
963
}
964
+
965
+ /// Downgrades a write-locked `RwLockWriteGuard` into a read-locked [`RwLockReadGuard`].
966
+ ///
967
+ /// Atomically changes the state of the [`RwLock`] from exclusive mode into shared mode.
968
+ ///
969
+ /// MORE DOCS COMING SOON.
970
+ #[ unstable( feature = "rwlock_downgrade" , issue = "128203" ) ]
971
+ pub fn downgrade ( s : Self ) -> RwLockReadGuard < ' a , T > {
972
+ // SAFETY: We take ownership of a write guard, so we must already have the `RwLock` in write
973
+ // mode, satisfying the `downgrade` contract.
974
+ unsafe { s. lock . inner . downgrade ( ) } ;
975
+
976
+ // SAFETY: We have just successfully called `downgrade`, so we fulfill the safety contract.
977
+ unsafe {
978
+ RwLockReadGuard :: new ( s. lock )
979
+ . expect ( "We had the exclusive lock so we can't have panicked while holding it" )
980
+ }
981
+ }
982
+
960
983
}
961
984
962
985
impl < ' a , T : ?Sized > MappedRwLockWriteGuard < ' a , T > {
0 commit comments