use core::mem::ManuallyDrop;
use parking_lot_core::{DEFAULT_PARK_TOKEN, DEFAULT_UNPARK_TOKEN};
#[allow(unused_imports)]
use crate::msrv::StrictProvenance;
use crate::{
msrv::ptr,
sync::{condvar::CondVar, mutex::Mutex, parker::Parker},
};
#[derive(Debug)]
pub struct ParkingLotParker(
#[allow(dead_code)] u8,
);
impl ParkingLotParker {
#[inline]
#[allow(clippy::incompatible_msrv, unstable_name_collisions)]
fn key(&self) -> usize {
ptr::from_ref(self).addr()
}
}
impl Parker for ParkingLotParker {
const INIT: Self = Self(0);
#[inline]
unsafe fn park_until<T>(&self, mut notified: impl FnMut() -> Option<T>) -> T {
loop {
let mut res = None;
unsafe {
parking_lot_core::park(
self.key(),
|| {
res = notified();
res.is_none()
},
|| {},
|_, _| {},
DEFAULT_PARK_TOKEN,
None,
);
}
if let Some(res) = res {
return res;
}
}
}
#[inline]
unsafe fn unpark(&self, _parked_state: *mut ()) {
unsafe { parking_lot_core::unpark_one(self.key(), |_| DEFAULT_UNPARK_TOKEN) };
}
}
unsafe impl CondVar<parking_lot::Mutex<()>> for parking_lot::Condvar {
const INIT: Self = parking_lot::Condvar::new();
#[inline]
unsafe fn wait<'a>(
&self,
mutex: &'a parking_lot::Mutex<()>,
_guard: <parking_lot::Mutex<()> as Mutex>::Guard<'a>,
) -> <parking_lot::Mutex<()> as Mutex>::Guard<'a> {
let mut guard = ManuallyDrop::new(unsafe { mutex.make_guard_unchecked() });
parking_lot::Condvar::wait(self, &mut guard);
}
#[inline]
fn notify_one(&self) {
parking_lot::Condvar::notify_one(self);
}
}