Skip to content

Commit 82cb15e

Browse files
committed
init
1 parent 5f3b84a commit 82cb15e

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

Diff for: library/std/src/sync/poison/rwlock.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::sync::PoisonError;
12
use crate::cell::UnsafeCell;
23
use crate::fmt;
34
use crate::marker::PhantomData;
@@ -918,6 +919,19 @@ impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
918919
None => Err(orig),
919920
}
920921
}
922+
923+
pub fn try_upgrade<T>(orig: Self) -> Result<RwLockWriteGuard<'a, T>, RwLockReadGuard<'a, T>> {
924+
read_lock = orig.inner_lock;
925+
926+
// don't call the constructor
927+
forget(read_lock);
928+
929+
// SAFETY: We have ownership of the read guard, so it must be in read mode already
930+
match unsafe { read_lock.try_upgrade() } {
931+
true => RwLockWriteGuard::new(read_lock).unwrap_or_else(PoisonError::into_inner),
932+
false => RwLockReadGuard::new(read_lock).unwrap_or_else(PoisonError::into_inner)
933+
}
934+
}
921935
}
922936

923937
impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {

Diff for: library/std/src/sys/sync/rwlock/futex.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::sync::atomic::Ordering::{Acquire, Relaxed};
12
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
23
use crate::sys::futex::{Futex, Primitive, futex_wait, futex_wake, futex_wake_all};
34

@@ -33,6 +34,11 @@ fn is_write_locked(state: Primitive) -> bool {
3334
state & MASK == WRITE_LOCKED
3435
}
3536

37+
#[inline]
38+
fn is_read_locked(state: Primitive) -> bool {
39+
state & MASK == READ_LOCKED
40+
}
41+
3642
#[inline]
3743
fn has_readers_waiting(state: Primitive) -> bool {
3844
state & READERS_WAITING != 0
@@ -205,6 +211,16 @@ impl RwLock {
205211
}
206212
}
207213

214+
/// # Safety
215+
///
216+
/// The 'RwLock' must be read-locked in order to call this. Calling this function in a loop
217+
/// in at least 2 threads will deadlock.
218+
#[inline]
219+
pub unsafe fn try_upgrade(&self) -> bool {
220+
debug_assert!(is_read_locked(self.state), "RwLock must be read locked to call `try_upgrade`");
221+
self.state.compare_exchange(READ_LOCKED, WRITE_LOCKED, Acquire, Relaxed).is_ok()
222+
}
223+
208224
#[cold]
209225
fn write_contended(&self) {
210226
let mut state = self.spin_write();

0 commit comments

Comments
 (0)