| 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<SpinMutex<WaitVariable<()>>>, |
| } |
| |
| impl Condvar { |
| pub const fn new() -> Condvar { |
| Condvar { inner: OnceBox::new() } |
| } |
| |
| fn get(&self) -> &SpinMutex<WaitVariable<()>> { |
| 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 |
| } |
| } |