use crate::rt;
use crate::thread;
use std::sync::Mutex;
use std::task::Waker;
#[derive(Debug)]
pub struct AtomicWaker {
waker: Mutex<Option<Waker>>,
object: rt::Mutex,
}
impl AtomicWaker {
pub fn new() -> AtomicWaker {
AtomicWaker {
waker: Mutex::new(None),
object: rt::Mutex::new(false),
}
}
pub fn register(&self, waker: Waker) {
if dbg!(!self.object.try_acquire_lock()) {
waker.wake();
thread::yield_now();
return;
}
*self.waker.lock().unwrap() = Some(waker);
dbg!(self.object.release_lock());
}
pub fn register_by_ref(&self, waker: &Waker) {
self.register(waker.clone());
}
pub fn wake(&self) {
if let Some(waker) = self.take_waker() {
waker.wake();
}
}
pub fn take_waker(&self) -> Option<Waker> {
dbg!(self.object.acquire_lock());
let ret = self.waker.lock().unwrap().take();
dbg!(self.object.release_lock());
ret
}
}
impl Default for AtomicWaker {
fn default() -> Self {
AtomicWaker::new()
}
}