mirror of
https://github.com/rust-lang/rust.git
synced 2025-11-01 21:45:15 +00:00
55 lines
1.4 KiB
Rust
55 lines
1.4 KiB
Rust
use crate::ptr;
|
|
use crate::sync::atomic::{AtomicPtr, Ordering};
|
|
use crate::sys::locks as imp;
|
|
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 CondvarCheck for Box<imp::Mutex> {
|
|
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 _;
|
|
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) {}
|
|
}
|