2 use crate::sync::atomic::{AtomicPtr, Ordering};
3 use crate::sys::locks as imp;
4 use crate::sys_common::lazy_box::{LazyBox, LazyInit};
5 use crate::sys_common::mutex::MovableMutex;
7 pub trait CondvarCheck {
11 /// For boxed mutexes, a `Condvar` will check it's only ever used with the same
12 /// mutex, based on its (stable) address.
13 impl<T: LazyInit> CondvarCheck for LazyBox<T> {
14 type Check = SameMutexCheck;
17 pub struct SameMutexCheck {
23 pub const fn new() -> Self {
24 Self { addr: AtomicPtr::new(ptr::null_mut()) }
26 pub fn verify(&self, mutex: &MovableMutex) {
27 let addr = mutex.raw() as *const imp::Mutex as *const () as *mut _;
28 // Relaxed is okay here because we never read through `self.addr`, and only use it to
30 match self.addr.compare_exchange(
36 Ok(_) => {} // Stored the address
37 Err(n) if n == addr => {} // Lost a race to store the same address
38 _ => panic!("attempted to use a condition variable with two mutexes"),
43 /// Unboxed mutexes may move, so `Condvar` can not require its address to stay
45 impl CondvarCheck for imp::Mutex {
53 pub const fn new() -> Self {
56 pub fn verify(&self, _: &MovableMutex) {}