use crate::error::{TryRecvError, TrySendError};
use crossbeam_utils::Backoff;
#[inline(always)]
pub fn async_recv<T>(rx: &crossbeam_channel::Receiver<T>) -> Result<T, TryRecvError> {
let backoff = Backoff::new();
loop {
match rx.try_recv() {
Ok(value) => return Ok(value),
Err(crossbeam_channel::TryRecvError::Empty) => {}
Err(crossbeam_channel::TryRecvError::Disconnected) => {
return Err(TryRecvError::Disconnected);
}
}
if backoff.is_completed() {
break;
} else {
backoff.snooze();
}
}
Err(TryRecvError::Empty)
}
#[inline(always)]
pub fn async_send<T>(tx: &crossbeam_channel::Sender<T>, value: T) -> Result<(), TrySendError<T>> {
let backoff = Backoff::new();
let mut value = value;
loop {
match tx.try_send(value) {
Ok(()) => return Ok(()),
Err(crossbeam_channel::TrySendError::Full(v)) => {
value = v;
}
Err(crossbeam_channel::TrySendError::Disconnected(v)) => {
return Err(TrySendError::Disconnected(v));
}
}
if backoff.is_completed() {
break;
} else {
backoff.snooze();
}
}
Err(TrySendError::Full(value))
}