]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys_common/condvar/check.rs
Move pthread locks to own module.
[rust.git] / library / std / src / sys_common / condvar / check.rs
1 use crate::sync::atomic::{AtomicUsize, Ordering};
2 use crate::sys::locks as imp;
3 use crate::sys_common::mutex::MovableMutex;
4
5 pub trait CondvarCheck {
6     type Check;
7 }
8
9 /// For boxed mutexes, a `Condvar` will check it's only ever used with the same
10 /// mutex, based on its (stable) address.
11 impl CondvarCheck for Box<imp::Mutex> {
12     type Check = SameMutexCheck;
13 }
14
15 pub struct SameMutexCheck {
16     addr: AtomicUsize,
17 }
18
19 #[allow(dead_code)]
20 impl SameMutexCheck {
21     pub const fn new() -> Self {
22         Self { addr: AtomicUsize::new(0) }
23     }
24     pub fn verify(&self, mutex: &MovableMutex) {
25         let addr = mutex.raw() as *const imp::Mutex as usize;
26         match self.addr.compare_exchange(0, addr, Ordering::SeqCst, Ordering::SeqCst) {
27             Ok(_) => {}               // Stored the address
28             Err(n) if n == addr => {} // Lost a race to store the same address
29             _ => panic!("attempted to use a condition variable with two mutexes"),
30         }
31     }
32 }
33
34 /// Unboxed mutexes may move, so `Condvar` can not require its address to stay
35 /// constant.
36 impl CondvarCheck for imp::Mutex {
37     type Check = NoCheck;
38 }
39
40 pub struct NoCheck;
41
42 #[allow(dead_code)]
43 impl NoCheck {
44     pub const fn new() -> Self {
45         Self
46     }
47     pub fn verify(&self, _: &MovableMutex) {}
48 }