use crate::{Pub, Sub, TryPopError};
use log::trace;
use std::{sync::Arc, task::Waker};
impl<T> Pub<T> {
pub(crate) fn notify(&mut self) {
loop {
match self.wakers.try_pop() {
Ok(waker) => {
trace!("waking");
waker.wake_by_ref();
}
Err(TryPopError::Empty) => {
trace!("no more wakers");
break;
}
Err(TryPopError::Finished) => {
trace!("no more subs");
break;
}
}
}
}
}
impl<T> Sub<T> {
pub(crate) fn add_waker(&mut self, waker: &Waker) -> bool {
self.wakers.push(Notify::from(waker.clone()))
}
}
#[derive(Debug, Clone)]
pub struct Notify(Arc<Waker>);
impl std::ops::Deref for Notify {
type Target = Waker;
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
impl From<Waker> for Notify {
fn from(value: Waker) -> Self {
Self(value.into())
}
}
impl Drop for Notify {
fn drop(&mut self) {
if let Some(waker) = Arc::get_mut(&mut self.0) {
waker.wake_by_ref();
}
}
}