]> git.proxmox.com Git - rustc.git/blame - library/std/src/sys_common/condvar/check.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / library / std / src / sys_common / condvar / check.rs
CommitLineData
5e7ed085
FG
1use crate::ptr;
2use crate::sync::atomic::{AtomicPtr, Ordering};
3use crate::sys::locks as imp;
923072b8 4use crate::sys_common::lazy_box::{LazyBox, LazyInit};
29967ef6
XL
5use crate::sys_common::mutex::MovableMutex;
6
7pub trait CondvarCheck {
8 type Check;
9}
10
11/// For boxed mutexes, a `Condvar` will check it's only ever used with the same
12/// mutex, based on its (stable) address.
923072b8 13impl<T: LazyInit> CondvarCheck for LazyBox<T> {
29967ef6
XL
14 type Check = SameMutexCheck;
15}
16
17pub struct SameMutexCheck {
5e7ed085 18 addr: AtomicPtr<()>,
29967ef6
XL
19}
20
21#[allow(dead_code)]
22impl SameMutexCheck {
23 pub const fn new() -> Self {
5e7ed085 24 Self { addr: AtomicPtr::new(ptr::null_mut()) }
29967ef6
XL
25 }
26 pub fn verify(&self, mutex: &MovableMutex) {
5e7ed085 27 let addr = mutex.raw() as *const imp::Mutex as *const () as *mut _;
04454e1e
FG
28 // Relaxed is okay here because we never read through `self.addr`, and only use it to
29 // compare addresses.
30 match self.addr.compare_exchange(
31 ptr::null_mut(),
32 addr,
33 Ordering::Relaxed,
34 Ordering::Relaxed,
35 ) {
fc512014
XL
36 Ok(_) => {} // Stored the address
37 Err(n) if n == addr => {} // Lost a race to store the same address
29967ef6
XL
38 _ => panic!("attempted to use a condition variable with two mutexes"),
39 }
40 }
41}
42
43/// Unboxed mutexes may move, so `Condvar` can not require its address to stay
44/// constant.
5e7ed085 45impl CondvarCheck for imp::Mutex {
29967ef6
XL
46 type Check = NoCheck;
47}
48
49pub struct NoCheck;
50
51#[allow(dead_code)]
52impl NoCheck {
53 pub const fn new() -> Self {
54 Self
55 }
56 pub fn verify(&self, _: &MovableMutex) {}
57}