use crate::sys::pal::waitqueue::{SpinMutex, WaitQueue, WaitVariable}; use crate::sys::sync::{Mutex, OnceBox}; use crate::time::Duration; pub struct Condvar { // FIXME: `UnsafeList` is not movable. inner: OnceBox>>, } impl Condvar { pub const fn new() -> Condvar { Condvar { inner: OnceBox::new() } } fn get(&self) -> &SpinMutex> { self.inner.get_or_init(|| Box::pin(SpinMutex::new(WaitVariable::new(())))).get_ref() } #[inline] pub fn notify_one(&self) { let guard = self.get().lock(); let _ = WaitQueue::notify_one(guard); } #[inline] pub fn notify_all(&self) { let guard = self.get().lock(); let _ = WaitQueue::notify_all(guard); } pub unsafe fn wait(&self, mutex: &Mutex) { let guard = self.get().lock(); WaitQueue::wait(guard, || unsafe { mutex.unlock() }); mutex.lock() } pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { let success = WaitQueue::wait_timeout(self.get(), dur, || unsafe { mutex.unlock() }); mutex.lock(); success } }