use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::task::Waker;
use std::{fmt, rc};
#[derive(Default)]
pub struct LocalWaker {
pub(crate) waker: UnsafeCell<Option<Waker>>,
_t: PhantomData<rc::Rc<()>>,
}
impl LocalWaker {
pub fn new() -> Self {
LocalWaker {
waker: UnsafeCell::new(None),
_t: PhantomData,
}
}
#[inline]
pub fn is_registed(&self) -> bool {
unsafe { (*self.waker.get()).is_some() }
}
#[inline]
pub fn register(&self, waker: &Waker) -> bool {
unsafe {
let w = self.waker.get();
let is_registered = (*w).is_some();
*w = Some(waker.clone());
is_registered
}
}
#[inline]
pub fn wake(&self) {
if let Some(waker) = self.take() {
waker.wake();
}
}
pub fn take(&self) -> Option<Waker> {
unsafe { (*self.waker.get()).take() }
}
}
impl fmt::Debug for LocalWaker {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "LocalWaker")
}
}