summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys_common/condvar/check.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /library/std/src/sys_common/condvar/check.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/std/src/sys_common/condvar/check.rs')
-rw-r--r--library/std/src/sys_common/condvar/check.rs57
1 files changed, 57 insertions, 0 deletions
diff --git a/library/std/src/sys_common/condvar/check.rs b/library/std/src/sys_common/condvar/check.rs
new file mode 100644
index 000000000..ce8f36704
--- /dev/null
+++ b/library/std/src/sys_common/condvar/check.rs
@@ -0,0 +1,57 @@
+use crate::ptr;
+use crate::sync::atomic::{AtomicPtr, Ordering};
+use crate::sys::locks as imp;
+use crate::sys_common::lazy_box::{LazyBox, LazyInit};
+use crate::sys_common::mutex::MovableMutex;
+
+pub trait CondvarCheck {
+ type Check;
+}
+
+/// For boxed mutexes, a `Condvar` will check it's only ever used with the same
+/// mutex, based on its (stable) address.
+impl<T: LazyInit> CondvarCheck for LazyBox<T> {
+ type Check = SameMutexCheck;
+}
+
+pub struct SameMutexCheck {
+ addr: AtomicPtr<()>,
+}
+
+#[allow(dead_code)]
+impl SameMutexCheck {
+ pub const fn new() -> Self {
+ Self { addr: AtomicPtr::new(ptr::null_mut()) }
+ }
+ pub fn verify(&self, mutex: &MovableMutex) {
+ let addr = mutex.raw() as *const imp::Mutex as *const () as *mut _;
+ // Relaxed is okay here because we never read through `self.addr`, and only use it to
+ // compare addresses.
+ match self.addr.compare_exchange(
+ ptr::null_mut(),
+ addr,
+ Ordering::Relaxed,
+ Ordering::Relaxed,
+ ) {
+ Ok(_) => {} // Stored the address
+ Err(n) if n == addr => {} // Lost a race to store the same address
+ _ => panic!("attempted to use a condition variable with two mutexes"),
+ }
+ }
+}
+
+/// Unboxed mutexes may move, so `Condvar` can not require its address to stay
+/// constant.
+impl CondvarCheck for imp::Mutex {
+ type Check = NoCheck;
+}
+
+pub struct NoCheck;
+
+#[allow(dead_code)]
+impl NoCheck {
+ pub const fn new() -> Self {
+ Self
+ }
+ pub fn verify(&self, _: &MovableMutex) {}
+}