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
) {}