use super::Inner;
use crate::sync::spsc::SpscInner;
use alloc::sync::Arc;
use core::{
sync::atomic::Ordering,
task::{Context, Poll},
};
const IS_TX_HALF: bool = true;
pub struct Sender<T> {
inner: Arc<Inner<T>>,
}
impl<T> Sender<T> {
pub(super) fn new(inner: Arc<Inner<T>>) -> Self {
Self { inner }
}
#[inline]
pub fn send(self, data: T) -> Result<(), T> {
self.inner.send(data)
}
#[inline]
pub fn poll_canceled(&mut self, cx: &mut Context<'_>) -> Poll<()> {
self.inner.poll_half(
cx,
IS_TX_HALF,
Ordering::Relaxed,
Ordering::Release,
Inner::take_cancel,
)
}
#[inline]
pub fn is_canceled(&self) -> bool {
self.inner.is_canceled(Ordering::Relaxed)
}
}
impl<T> Drop for Sender<T> {
#[inline]
fn drop(&mut self) {
self.inner.close_half(IS_TX_HALF);
}
}
impl<T> Inner<T> {
fn send(&self, data: T) -> Result<(), T> {
if self.is_canceled(Ordering::Relaxed) {
Err(data)
} else {
unsafe { *self.data.get() = Some(data) };
Ok(())
}
}
}