Skip to content

Commit fb0dc78

Browse files
committed
Add the downgrade method on RwLockWriteGuard
1 parent 84c257e commit fb0dc78

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

library/std/src/sync/rwlock.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,12 @@ impl<T> From<T> for RwLock<T> {
574574

575575
impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
576576
/// 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.
579583
unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
580584
poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard {
581585
data: unsafe { NonNull::new_unchecked(lock.data.get()) },
@@ -957,6 +961,25 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
957961
None => Err(orig),
958962
}
959963
}
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+
960983
}
961984

962985
impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {

0 commit comments

Comments
 (0)