use std::fmt;
use std::task::Waker;
use crate::internal;
use crate::mutex;
use crate::mutex::MutexGuard;
use crate::mutex::OwnedMutexGuard;
#[cfg(test)]
mod tests;
pub struct Condvar {
s: internal::Semaphore,
}
impl fmt::Debug for Condvar {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Condvar").finish_non_exhaustive()
}
}
impl Default for Condvar {
fn default() -> Self {
Self::new()
}
}
impl Condvar {
pub const fn new() -> Condvar {
Condvar {
s: internal::Semaphore::new(0),
}
}
pub fn notify_one(&self) {
self.s.release(1);
}
pub fn notify_all(&self) {
self.s.notify_all();
}
pub async fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> {
let mutex = mutex::guard_lock(&guard);
let mut acquire = self.s.poll_acquire(1);
let _ = acquire.poll_once(Waker::noop());
drop(guard);
acquire.await;
mutex.lock().await
}
pub async fn wait_owned<T>(&self, guard: OwnedMutexGuard<T>) -> OwnedMutexGuard<T> {
let mutex = mutex::owned_guard_lock(&guard);
let mut acquire = self.s.poll_acquire(1);
let _ = acquire.poll_once(Waker::noop());
drop(guard);
acquire.await;
mutex.lock_owned().await
}
pub async fn wait_while<'a, T, F>(
&self,
mut guard: MutexGuard<'a, T>,
mut condition: F,
) -> MutexGuard<'a, T>
where
F: FnMut(&mut T) -> bool,
{
while condition(&mut *guard) {
guard = self.wait(guard).await;
}
guard
}
pub async fn wait_while_owned<T, F>(
&self,
mut guard: OwnedMutexGuard<T>,
mut condition: F,
) -> OwnedMutexGuard<T>
where
F: FnMut(&mut T) -> bool,
{
while condition(&mut *guard) {
guard = self.wait_owned(guard).await;
}
guard
}
}