Skip to main content

chenal/
channel.rs

1use core::{
2    fmt, mem,
3    mem::ManuallyDrop,
4    ops::{Deref, DerefMut},
5    panic::{RefUnwindSafe, UnwindSafe},
6    pin::{Pin, pin},
7    ptr::NonNull,
8    sync::atomic::{
9        AtomicUsize,
10        Ordering::{AcqRel, Acquire, Relaxed},
11    },
12    task::{Context, Poll, ready},
13};
14
15use aiq::wait_queue::Wait;
16use crossbeam_utils::CachePadded;
17
18#[cfg(feature = "blocking")]
19use crate::blocking::*;
20use crate::{
21    errors::{AcquireError, RecvError, SendError, TryAcquireError, TryRecvError, TrySendError},
22    internal,
23    loom::sync::Arc,
24    rc::RefCount,
25    waiter::Waiter,
26};
27
28/// A channel implementation.
29#[expect(private_bounds)]
30pub trait Channel: internal::Channel {
31    /// Sender half of the channel.
32    type TxHalf<T>: ChannelHalf<Msg = T, Channel = Self>;
33    /// Receiver half of the channel.
34    type RxHalf<T>: ChannelHalf<Msg = T, Channel = Self>;
35    /// Creates a sender/receiver pair using this implementation.
36    fn channel<T>(self) -> (Self::TxHalf<T>, Self::RxHalf<T>) {
37        use internal::ChannelHalf;
38        let chan = Arc::new(Chan::new(self));
39        (Self::TxHalf::new(chan.clone()), Self::RxHalf::new(chan))
40    }
41}
42
43/// A bounded channel.
44pub trait BoundedChannel: Channel {}
45
46/// A sender or receiver half of a channel.
47#[expect(private_bounds)]
48pub trait ChannelHalf: internal::ChannelHalf<Self::Msg, Self::Channel> {
49    /// The message type of the channel.
50    type Msg;
51    /// The implementation of the channel.
52    type Channel: Channel;
53}
54
55/// Opaque unique identifier for a channel instance. Two halves sharing the same `ChannelId`
56/// belong to the same channel.
57#[derive(Debug, Clone, Eq, PartialEq, Hash)]
58pub struct ChannelId(NonNull<()>);
59
60trait Operation<T, Ch: internal::Channel>: 'static {
61    type State;
62    type Slot;
63    type Waiter: Waiter;
64    fn acquire_slot(chan: &Chan<T, Ch>) -> Result<Self::Slot, Self::State>;
65    fn acquire_slot_cold(
66        chan: &Chan<T, Ch>,
67        state: &mut Self::State,
68        first_call: bool,
69    ) -> Result<Self::Slot, TryAcquireError>;
70    fn waiter(chan: &Chan<T, Ch>) -> &Self::Waiter;
71}
72
73struct SendMsg;
74impl<T, Ch: internal::Channel> Operation<T, Ch> for SendMsg {
75    type State = Ch::TxState<T>;
76    type Slot = Ch::TxSlot<T>;
77    type Waiter = Ch::TxWaiter;
78    fn acquire_slot(chan: &Chan<T, Ch>) -> Result<Self::Slot, Self::State> {
79        Ch::tx_acquire_slot(chan)
80    }
81    fn acquire_slot_cold(
82        chan: &Chan<T, Ch>,
83        state: &mut Self::State,
84        first_call: bool,
85    ) -> Result<Self::Slot, TryAcquireError> {
86        Ch::tx_acquire_slot_cold(chan, state, first_call)
87    }
88    fn waiter(chan: &Chan<T, Ch>) -> &Self::Waiter {
89        &chan.tx_waiter
90    }
91}
92
93struct RecvMsg;
94impl<T, Ch: internal::Channel> Operation<T, Ch> for RecvMsg {
95    type State = Ch::RxState<T>;
96    type Slot = Ch::RxSlot<T>;
97    type Waiter = Ch::RxWaiter;
98    fn acquire_slot(chan: &Chan<T, Ch>) -> Result<Self::Slot, Self::State> {
99        Ch::rx_acquire_slot(chan)
100    }
101    fn acquire_slot_cold(
102        chan: &Chan<T, Ch>,
103        state: &mut Self::State,
104        first_call: bool,
105    ) -> Result<Self::Slot, TryAcquireError> {
106        Ch::rx_acquire_slot_cold(chan, state, first_call)
107    }
108    fn waiter(chan: &Chan<T, Ch>) -> &Self::Waiter {
109        &chan.rx_waiter
110    }
111}
112
113// fields are duplicated instead of using an intermediate struct
114// to keep them packed on the same cache line
115pub(crate) struct Chan<T, Ch: internal::Channel> {
116    pub(crate) tx_shared_state: CachePadded<Ch::TxAtomicState<T>>,
117    pub(crate) rx_shared_state: CachePadded<Ch::RxAtomicState<T>>,
118    pub(crate) storage: Ch::Storage<T>,
119    pub(crate) tx_waiter: Ch::TxWaiter,
120    pub(crate) rx_waiter: Ch::RxWaiter,
121    tx_cnt: Ch::TxRefCount,
122    rx_cnt: Ch::RxRefCount,
123    close_waiter: aiq::WaitQueue,
124}
125
126unsafe impl<T: Send, Ch: internal::Channel> Send for Chan<T, Ch> {}
127unsafe impl<T: Send, Ch: internal::Channel> Sync for Chan<T, Ch> {}
128impl<T, Ch: internal::Channel> UnwindSafe for Chan<T, Ch> {}
129impl<T, Ch: internal::Channel> RefUnwindSafe for Chan<T, Ch> {}
130
131impl<T, Ch: internal::Channel> Chan<T, Ch> {
132    pub(crate) fn new(channel: Ch) -> Self {
133        let storage = channel.storage();
134        Self {
135            tx_shared_state: Ch::tx_init_state(&storage).into(),
136            rx_shared_state: Ch::rx_init_state(&storage).into(),
137            storage,
138            tx_waiter: Default::default(),
139            rx_waiter: Default::default(),
140            tx_cnt: RefCount::one(),
141            rx_cnt: RefCount::one(),
142            close_waiter: Default::default(),
143        }
144    }
145
146    fn id(&self) -> ChannelId {
147        ChannelId(NonNull::from(self).cast())
148    }
149
150    fn close(&self) {
151        Ch::close(self);
152        self.tx_waiter.close();
153        self.rx_waiter.close();
154        self.close_waiter.close();
155    }
156
157    #[inline(always)]
158    fn write_slot<E, F: From<(E, T)> + From<SendError<T>>>(
159        &self,
160        slot: Result<Ch::TxSlot<T>, E>,
161        msg: T,
162    ) -> Result<(), F> {
163        match slot {
164            Ok(slot) => Ch::write_slot(self, slot, msg)?,
165            Err(err) => return Err((err, msg).into()),
166        }
167        self.rx_waiter.wake();
168        Ok(())
169    }
170
171    #[inline(always)]
172    fn read_slot<E>(&self, slot: Ch::RxSlot<T>) -> Result<T, E> {
173        let msg = Ch::read_slot(self, slot);
174        if Ch::WAKE_TX_AFTER_READ {
175            self.tx_waiter.wake();
176        }
177        Ok(msg)
178    }
179
180    #[inline(always)]
181    fn try_acquire_slot<O: Operation<T, Ch>>(&self) -> Result<O::Slot, TryAcquireError> {
182        O::acquire_slot(self).or_else(|state| self.try_acquire_slot_cold::<O>(state))
183    }
184
185    #[cold]
186    fn try_acquire_slot_cold<O: Operation<T, Ch>>(
187        &self,
188        mut state: O::State,
189    ) -> Result<O::Slot, TryAcquireError> {
190        O::acquire_slot_cold(self, &mut state, true)
191    }
192
193    #[inline(always)]
194    fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> {
195        self.write_slot(self.try_acquire_slot::<SendMsg>(), msg)
196    }
197
198    #[inline(always)]
199    fn send_unbounded(&self, msg: T) -> Result<(), SendError<T>> {
200        match self.try_send(msg) {
201            Ok(()) => Ok(()),
202            Err(TrySendError::Closed(msg)) => Err(SendError(msg)),
203            Err(TrySendError::Full(_)) => unsafe { core::hint::unreachable_unchecked() },
204        }
205    }
206
207    #[inline(always)]
208    fn try_recv(&self) -> Result<T, TryRecvError> {
209        self.read_slot(self.try_acquire_slot::<RecvMsg>()?)
210    }
211
212    #[inline(always)]
213    fn poll_acquire_slot<'a, O: Operation<T, Ch>>(
214        &'a self,
215        cx: &mut Context<'_>,
216        wait: Pin<&mut <O::Waiter as Waiter>::Wait<'a>>,
217    ) -> Poll<Result<O::Slot, AcquireError>> {
218        match O::acquire_slot(self) {
219            Ok(slot) => Poll::Ready(Ok(slot)),
220            Err(state) => self.poll_acquire_slot_cold::<O>(cx, wait, state),
221        }
222    }
223
224    #[cold]
225    fn poll_acquire_slot_cold<'a, O: Operation<T, Ch>>(
226        &'a self,
227        cx: &mut Context<'_>,
228        mut wait: Pin<&mut <O::Waiter as Waiter>::Wait<'a>>,
229        mut state: O::State,
230    ) -> Poll<Result<O::Slot, AcquireError>> {
231        let mut first_call = true;
232        let mut waker_registered = false;
233        loop {
234            match O::acquire_slot_cold(self, &mut state, first_call) {
235                Ok(slot) => {
236                    if waker_registered {
237                        unsafe { O::waiter(self).unregister() };
238                    }
239                    return Poll::Ready(Ok(slot));
240                }
241                Err(TryAcquireError::Closed) => return Poll::Ready(Err(AcquireError)),
242                Err(TryAcquireError::Unavailable) if waker_registered => return Poll::Pending,
243                Err(TryAcquireError::Unavailable) => {}
244            }
245            waker_registered = unsafe { O::waiter(self).register(wait.as_mut(), cx.waker()) };
246            first_call = false;
247        }
248    }
249
250    #[cfg(feature = "blocking")]
251    fn acquire_slot_blocking<O: Operation<T, Ch>>(
252        &self,
253        parker: impl Into<Parker>,
254    ) -> Result<O::Slot, TryAcquireError> {
255        O::acquire_slot(self)
256            .or_else(|state| self.acquire_slot_blocking_cold::<O>(state, parker.into()))
257    }
258
259    #[cfg(feature = "blocking")]
260    #[cold]
261    fn acquire_slot_blocking_cold<O: Operation<T, Ch>>(
262        &self,
263        mut state: O::State,
264        mut parker: Parker,
265    ) -> Result<O::Slot, TryAcquireError> {
266        let mut wait = core::pin::pin!(<O::Waiter as Waiter>::Wait::default());
267        let mut first_call = true;
268        let mut waker_registered = false;
269        loop {
270            match O::acquire_slot_cold(self, &mut state, first_call) {
271                Ok(slot) => {
272                    if waker_registered {
273                        unsafe { O::waiter(self).unregister() };
274                    }
275                    return Ok(slot);
276                }
277                Err(TryAcquireError::Closed) => return Err(TryAcquireError::Closed),
278                Err(TryAcquireError::Unavailable) => {}
279            }
280            waker_registered = if waker_registered {
281                parker.park()?;
282                false
283            } else {
284                unsafe { O::waiter(self).register(wait.as_mut(), &PARK_WAKER) }
285            };
286            first_call = false;
287        }
288    }
289
290    #[cfg(feature = "blocking")]
291    #[inline(always)]
292    fn send_blocking(&self, msg: T) -> Result<(), SendError<T>> {
293        let slot = self.acquire_slot_blocking::<SendMsg>(());
294        self.write_slot(slot, msg)
295    }
296
297    #[cfg(feature = "blocking")]
298    #[inline(always)]
299    fn send_deadline(&self, msg: T, deadline: Instant) -> Result<(), SendTimeoutError<T>> {
300        let slot = self.acquire_slot_blocking::<SendMsg>(deadline);
301        self.write_slot(slot, msg)
302    }
303
304    #[cfg(feature = "blocking")]
305    #[inline(always)]
306    fn send_timeout(&self, msg: T, timeout: Duration) -> Result<(), SendTimeoutError<T>> {
307        let slot = self.acquire_slot_blocking::<SendMsg>(timeout);
308        self.write_slot(slot, msg)
309    }
310
311    #[cfg(feature = "blocking")]
312    #[inline(always)]
313    fn recv_blocking(&self) -> Result<T, RecvError> {
314        let slot = self.acquire_slot_blocking::<RecvMsg>(())?;
315        self.read_slot(slot)
316    }
317
318    #[cfg(feature = "blocking")]
319    #[inline(always)]
320    fn recv_deadline(&self, deadline: Instant) -> Result<T, RecvTimeoutError> {
321        let slot = self.acquire_slot_blocking::<RecvMsg>(deadline)?;
322        self.read_slot(slot)
323    }
324
325    #[cfg(feature = "blocking")]
326    #[inline(always)]
327    fn recv_timeout(&self, timeout: Duration) -> Result<T, RecvTimeoutError> {
328        let slot = self.acquire_slot_blocking::<RecvMsg>(timeout)?;
329        self.read_slot(slot)
330    }
331
332    fn ref_cnt(&self, half: Half) -> Option<&AtomicUsize> {
333        match half {
334            Half::Tx | Half::MTx | Half::UTx | Half::UMTx => self.tx_cnt.atomic(),
335            Half::Rx | Half::MRx => self.rx_cnt.atomic(),
336        }
337    }
338
339    fn drop_half(&self, half: Half) {
340        if (self.ref_cnt(half)).is_none_or(|rc| rc.fetch_sub(1, AcqRel) == 1) {
341            self.close();
342        }
343    }
344
345    fn clone_half(&self, half: Half) {
346        self.ref_cnt(half).unwrap().fetch_add(1, Relaxed);
347    }
348}
349
350impl<T, Ch: internal::Channel> Drop for Chan<T, Ch> {
351    fn drop(&mut self) {
352        Ch::drop_storage(self);
353    }
354}
355
356impl<T, Ch: internal::Channel> Deref for Chan<T, Ch> {
357    type Target = Ch::Storage<T>;
358
359    fn deref(&self) -> &Self::Target {
360        &self.storage
361    }
362}
363
364impl<T, Ch: internal::Channel> fmt::Debug for Chan<T, Ch> {
365    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
366        let half_kind = |rc_size| if rc_size > 0 { "M" } else { "S" };
367        let tx_kind = half_kind(size_of_val(&self.tx_cnt));
368        let rx_kind = half_kind(size_of_val(&self.rx_cnt));
369        let mut builder = f.debug_struct("Chan");
370        builder
371            .field("id", &self.id())
372            .field("kind", &alloc::format!("{tx_kind}P{rx_kind}C",));
373        if let Some(capacity) = Ch::capacity(&self.storage) {
374            builder.field("capacity", &capacity);
375        }
376        builder.finish_non_exhaustive()
377    }
378}
379
380/// Future returned by [`Tx::send`]/[`MTx::send`].
381///
382/// Resolves once the message has been written in the channel, or the channel is closed.
383///
384/// Message being sent can be retrieved with [`cancel`](Self::cancel), cancelling the future.
385pub struct SendFuture<'a, T, Ch: Channel> {
386    chan: &'a Chan<T, Ch>,
387    msg: Option<T>,
388    wait: <Ch::TxWaiter as Waiter>::Wait<'a>,
389}
390
391impl<'a, T, Ch: Channel> SendFuture<'a, T, Ch> {
392    #[inline(always)]
393    fn new(chan: &'a Chan<T, Ch>, msg: T) -> Self {
394        Self {
395            chan,
396            msg: Some(msg),
397            wait: Default::default(),
398        }
399    }
400
401    /// Cancels the send, returning the message if it has not yet been sent.
402    pub fn cancel(self: Pin<&mut Self>) -> Option<T> {
403        unsafe { self.get_unchecked_mut() }.msg.take()
404    }
405}
406
407impl<T, Ch: Channel> Future for SendFuture<'_, T, Ch> {
408    type Output = Result<(), SendError<T>>;
409
410    #[inline(always)]
411    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
412        let this = unsafe { self.get_unchecked_mut() };
413        let wait = unsafe { Pin::new_unchecked(&mut this.wait) };
414        let slot = ready!(this.chan.poll_acquire_slot::<SendMsg>(cx, wait));
415        let Some(msg) = this.msg.take() else {
416            #[cold]
417            #[inline(never)]
418            fn polled_after_completion() -> ! {
419                panic!("future polled after completion; channel will be blocked");
420            }
421            polled_after_completion();
422        };
423        Poll::Ready(this.chan.write_slot(slot, msg))
424    }
425}
426
427/// Future returned by [`Rx::recv`]/[`MRx::recv`].
428///
429/// Resolves once a message is available, or the channel is closed.
430///
431/// The future can be reused to receive subsequent messages, as a [`Stream`](futures_core::stream::Stream).
432pub struct RecvFuture<'a, T, Ch: Channel> {
433    chan: &'a Chan<T, Ch>,
434    wait: <Ch::RxWaiter as Waiter>::Wait<'a>,
435}
436
437impl<'a, T, Ch: Channel> RecvFuture<'a, T, Ch> {
438    #[inline(always)]
439    fn new(chan: &'a Chan<T, Ch>) -> Self {
440        Self {
441            chan,
442            wait: Default::default(),
443        }
444    }
445}
446
447impl<T, Ch: Channel> Future for RecvFuture<'_, T, Ch> {
448    type Output = Result<T, RecvError>;
449
450    #[inline(always)]
451    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
452        let this = unsafe { self.get_unchecked_mut() };
453        let wait = unsafe { Pin::new_unchecked(&mut this.wait) };
454        let slot = ready!(this.chan.poll_acquire_slot::<RecvMsg>(cx, wait))?;
455        Poll::Ready(this.chan.read_slot(slot))
456    }
457}
458
459#[cfg(feature = "stream")]
460impl<T, Ch: Channel> futures_core::Stream for RecvFuture<'_, T, Ch> {
461    type Item = T;
462    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
463        self.poll(cx).map(Result::ok)
464    }
465}
466
467/// Future returned by [`CloseHandle::closed`] and similar methods.
468///
469/// Resolves once the channel is closed.
470pub struct ClosedFuture<'a>(Wait<&'a aiq::WaitQueue>);
471
472impl<'a> ClosedFuture<'a> {
473    fn new<T, Ch: internal::Channel>(chan: &'a Chan<T, Ch>) -> Self {
474        Self(chan.close_waiter.wait())
475    }
476}
477
478impl Future for ClosedFuture<'_> {
479    type Output = ();
480
481    #[inline(always)]
482    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
483        unsafe { self.map_unchecked_mut(|this| &mut this.0) }.poll(cx)
484    }
485}
486
487trait Close: fmt::Debug {
488    fn id(&self) -> ChannelId;
489    fn close(&self);
490    fn closed(&self) -> ClosedFuture<'_>;
491}
492
493impl<T, Ch: internal::Channel> Close for Chan<T, Ch> {
494    fn id(&self) -> ChannelId {
495        self.id()
496    }
497    fn close(&self) {
498        self.close();
499    }
500    fn closed(&self) -> ClosedFuture<'_> {
501        ClosedFuture::new(self)
502    }
503}
504
505/// A cloneable handle for closing a channel or observing its closure, without holding a sender
506/// or receiver half.
507#[derive(Debug, Clone)]
508pub struct CloseHandle<'a>(Arc<dyn Close + 'a>);
509
510impl<'a> CloseHandle<'a> {
511    pub(crate) fn new<T: 'a, Ch: Channel>(chan: Arc<Chan<T, Ch>>) -> Self {
512        #[cfg(not(loom))]
513        return Self(chan as _);
514        #[cfg(loom)]
515        unimplemented!("{chan:?}");
516    }
517
518    /// Returns the channel's unique identifier.
519    pub fn channel_id(&self) -> ChannelId {
520        self.0.id()
521    }
522
523    /// Converts this handle into a [`CloseGuard`] that closes the channel when dropped.
524    pub fn close_on_drop(self) -> CloseGuard<'a> {
525        CloseGuard(self.0)
526    }
527
528    /// Returns a future that resolves once the channel is closed.
529    pub fn closed(&self) -> ClosedFuture<'_> {
530        self.0.closed()
531    }
532}
533
534/// A RAII guard that closes the channel when dropped. Obtained via [`CloseHandle::close_on_drop`].
535#[derive(Debug, Clone)]
536pub struct CloseGuard<'a>(Arc<dyn Close + 'a>);
537
538impl<'a> CloseGuard<'a> {
539    /// Returns the channel's unique identifier.
540    pub fn channel_id(&self) -> ChannelId {
541        self.0.id()
542    }
543
544    /// Disarms the guard without closing the channel.
545    pub fn forget(self) {
546        mem::forget(self);
547    }
548}
549
550impl Drop for CloseGuard<'_> {
551    fn drop(&mut self) {
552        self.0.close();
553    }
554}
555
556#[derive(Copy, Clone)]
557pub(crate) enum Half {
558    Tx,
559    MTx,
560    UTx,
561    UMTx,
562    Rx,
563    MRx,
564}
565
566macro_rules! channel_half {
567    ($ty:ident) => {
568        impl<T, Ch: Channel> Drop for $ty<T, Ch> {
569            fn drop(&mut self) {
570                self.chan.drop_half(Half::$ty);
571            }
572        }
573        impl<T, Ch: Channel> internal::ChannelHalf<T, Ch> for $ty<T, Ch> {
574            const HALF: Half = Half::$ty;
575            fn new(chan: Arc<Chan<T, Ch>>) -> Self {
576                Self { chan }
577            }
578            fn chan(&self) -> &Arc<Chan<T, Ch>> {
579                &self.chan
580            }
581        }
582        impl<T, Ch: Channel> ChannelHalf for $ty<T, Ch> {
583            type Msg = T;
584            type Channel = Ch;
585        }
586        unsafe impl<T: Send, Ch: Channel> Send for $ty<T, Ch> {}
587        unsafe impl<T: Send, Ch: Channel> Sync for $ty<T, Ch> {}
588        impl<T, Ch: Channel> UnwindSafe for $ty<T, Ch> {}
589        impl<T, Ch: Channel> RefUnwindSafe for $ty<T, Ch> {}
590        impl<T, Ch: Channel> $ty<T, Ch> {
591            /// Returns `true` if the channel is closed.
592            pub fn is_closed(&self) -> bool {
593                Ch::is_closed(&self.chan)
594            }
595            /// Closes the channel, waking all waiting senders and receivers.
596            pub fn close(&self) {
597                self.chan.close();
598            }
599            /// Returns a [`CloseHandle`] that can close the channel or observe its closure
600            /// without holding this half.
601            pub fn close_handle<'a>(&self) -> CloseHandle<'a>
602            where
603                T: 'a,
604            {
605                CloseHandle::new(self.chan.clone())
606            }
607            /// Returns a unique identifier for the underlying channel.
608            pub fn channel_id(&self) -> ChannelId {
609                self.chan.id()
610            }
611            /// Returns a future that resolves once the channel is closed.
612            pub fn closed(&self) -> ClosedFuture<'_> {
613                ClosedFuture::new(&self.chan)
614            }
615            /// Returns the capacity of the bounded channel.
616            pub fn capacity(&self) -> usize
617            where
618                Ch: BoundedChannel,
619            {
620                Ch::capacity(&self.chan).unwrap()
621            }
622        }
623        impl<T, Ch: Channel> core::fmt::Debug for $ty<T, Ch> {
624            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
625                f.debug_tuple(stringify!($ty)).field(&self.chan).finish()
626            }
627        }
628    };
629}
630macro_rules! tx_half {
631    ($ty:ident $(, $mut:tt)?) => {
632        impl<T, Ch: Channel> $ty<T, Ch> {
633            /// Sends a message, waiting asynchronously if the channel is full.
634            #[inline]
635            pub fn send(&$($mut)? self, msg: T) -> SendFuture<'_, T, Ch> {
636                SendFuture::new(&self.chan, msg)
637            }
638            /// Sends a message, blocking the current thread if the channel is full.
639            #[cfg(feature = "blocking")]
640            #[inline]
641            pub fn send_blocking(&$($mut)? self, msg: T) -> Result<(), SendError<T>> {
642                self.chan.send_blocking(msg)
643            }
644            /// Sends a message, blocking until `deadline` if the channel is full.
645            #[cfg(feature = "blocking")]
646            #[inline]
647            pub fn send_deadline(&$($mut)? self, msg: T, deadline: Instant) -> Result<(), SendTimeoutError<T>> {
648                self.chan.send_deadline(msg, deadline)
649            }
650            /// Sends a message, blocking for up to `timeout` if the channel is full.
651            #[cfg(feature = "blocking")]
652            #[inline]
653            pub fn send_timeout(&$($mut)? self, msg: T, timeout: Duration) -> Result<(), SendTimeoutError<T>> {
654                self.chan.send_timeout(msg, timeout)
655            }
656            /// Attempts to send a message without waiting.
657            #[inline]
658            pub fn try_send(&$($mut)? self, msg: T) -> Result<(), TrySendError<T>> {
659                self.chan.try_send(msg)
660            }
661            /// Returns `true` if the channel is full.
662            pub fn is_full(&self) -> bool {
663                Ch::is_full(&self.chan)
664            }
665        }
666    };
667}
668macro_rules! utx_methods {
669    ($ty:ident $(, $mut:tt)?) => {
670        impl<T, Ch: Channel> $ty<T, Ch> {
671            /// Sends a message. Never blocks or returns [`TrySendError::Full`] since the channel
672            /// is unbounded.
673            #[inline]
674            pub fn send_unbounded(&$($mut)? self, msg: T) -> Result<(), SendError<T>> {
675                self.chan.send_unbounded(msg)
676            }
677        }
678    };
679}
680macro_rules! rx_half {
681    ($ty:ident $(, $mut:tt)?) => {
682        impl<T, Ch: Channel> $ty<T, Ch> {
683            /// Receives a message, waiting asynchronously if the channel is empty.
684            #[inline]
685            pub fn recv(&$($mut)? self) -> RecvFuture<'_, T, Ch> {
686                RecvFuture::new(&self.chan)
687            }
688            /// Receives a message, blocking the current thread if the channel is empty.
689            #[cfg(feature = "blocking")]
690            #[inline]
691            pub fn recv_blocking(&$($mut)? self) -> Result<T, RecvError> {
692                self.chan.recv_blocking()
693            }
694            /// Receives a message, blocking until `deadline` if the channel is empty.
695            #[cfg(feature = "blocking")]
696            #[inline]
697            pub fn recv_deadline(&$($mut)? self, deadline: Instant) -> Result<T, RecvTimeoutError> {
698                self.chan.recv_deadline(deadline)
699            }
700            /// Receives a message, blocking for up to `timeout` if the channel is empty.
701            #[cfg(feature = "blocking")]
702            #[inline]
703            pub fn recv_timeout(&$($mut)? self, timeout: Duration) -> Result<T, RecvTimeoutError> {
704                self.chan.recv_timeout(timeout)
705            }
706            /// Returns a blocking iterator that yields messages until the channel is closed.
707            #[cfg(feature = "blocking")]
708            pub fn iter_blocking(&$($mut)? self) -> impl Iterator<Item = T> {
709                core::iter::from_fn(|| self.recv_blocking().ok())
710            }
711            /// Attempts to receive a message without waiting.
712            #[inline]
713            pub fn try_recv(&$($mut)? self) -> Result<T, TryRecvError> {
714                self.chan.try_recv()
715            }
716            /// Returns `true` if the channel is empty.
717            pub fn is_empty(&self) -> bool {
718                Ch::is_empty(&self.chan)
719            }
720        }
721    };
722}
723macro_rules! cloneable_half {
724    ($ty:ident) => {
725        impl<T, Ch: Channel> Clone for $ty<T, Ch> {
726            fn clone(&self) -> Self {
727                self.chan.clone_half(Half::$ty);
728                internal::ChannelHalf::raw_clone(self)
729            }
730        }
731        impl<T, Ch: Channel> $ty<T, Ch> {
732            /// Returns a [`Weak`] reference that does not prevent the channel from being closed.
733            pub fn downgrade(&self) -> Weak<Self> {
734                Weak::new(self)
735            }
736        }
737    };
738}
739
740/// Single-producer sending half. Requires exclusive access (`&mut self`) to send.
741pub struct Tx<T, Ch: Channel> {
742    chan: Arc<Chan<T, Ch>>,
743}
744tx_half!(Tx, mut);
745channel_half!(Tx);
746
747/// Multi-producer cloneable sending half.
748pub struct MTx<T, Ch: Channel> {
749    chan: Arc<Chan<T, Ch>>,
750}
751tx_half!(MTx);
752channel_half!(MTx);
753cloneable_half!(MTx);
754
755/// Single-producer unbounded sending half, which never blocks. Requires exclusive access (`&mut self`) to send.
756pub struct UTx<T, Ch: Channel> {
757    chan: Arc<Chan<T, Ch>>,
758}
759utx_methods!(UTx, mut);
760channel_half!(UTx);
761
762/// Multi-producer cloneable unbounded sending half, which never blocks.
763pub struct UMTx<T, Ch: Channel> {
764    chan: Arc<Chan<T, Ch>>,
765}
766utx_methods!(UMTx);
767channel_half!(UMTx);
768cloneable_half!(UMTx);
769
770/// Single-consumer receiving half. Requires exclusive access (`&mut self`) to receive.
771pub struct Rx<T, Ch: Channel> {
772    chan: Arc<Chan<T, Ch>>,
773}
774rx_half!(Rx, mut);
775channel_half!(Rx);
776
777/// Multi-consumer cloneable receiving half.
778pub struct MRx<T, Ch: Channel> {
779    chan: Arc<Chan<T, Ch>>,
780}
781rx_half!(MRx);
782channel_half!(MRx);
783cloneable_half!(MRx);
784
785impl<T, Ch: Channel> Rx<T, Ch> {
786    /// Poll-based receive for use in manual [`Future`] or
787    /// [`Stream`](futures_core::stream::Stream) implementations.
788    pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Result<T, RecvError>> {
789        const { assert!(size_of::<<Ch::RxWaiter as Waiter>::Wait<'static>>() == 0) };
790        pin!(self.recv()).poll(cx)
791    }
792}
793
794#[cfg(feature = "stream")]
795impl<T, Ch: Channel> futures_core::Stream for Rx<T, Ch> {
796    type Item = T;
797    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
798        self.poll_recv(cx).map(Result::ok)
799    }
800}
801
802/// A non-owning reference to a cloneable channel half. Does not prevent the channel from closing.
803pub struct Weak<H: ChannelHalf + Clone>(pub(crate) ManuallyDrop<H>);
804
805impl<H: ChannelHalf + Clone> Deref for Weak<H> {
806    type Target = H;
807
808    fn deref(&self) -> &H {
809        &self.0
810    }
811}
812
813impl<H: ChannelHalf + Clone> DerefMut for Weak<H> {
814    fn deref_mut(&mut self) -> &mut Self::Target {
815        &mut self.0
816    }
817}
818
819impl<H: ChannelHalf + Clone> Weak<H> {
820    pub(crate) fn new(end: &H) -> Self {
821        Weak(ManuallyDrop::new(end.raw_clone()))
822    }
823
824    /// Attempts to obtain a strong reference. Returns `None` if all strong handles have been
825    /// dropped and the channel is closed.
826    pub fn upgrade(&self) -> Option<H> {
827        let incr = |c| (c != 0).then(|| c + 1);
828        let strong = self.0.chan().ref_cnt(H::HALF).unwrap();
829        #[allow(deprecated)]
830        strong.fetch_update(Relaxed, Acquire, incr).ok()?;
831        Some(self.0.raw_clone())
832    }
833}
834
835impl<H: ChannelHalf + Clone> Clone for Weak<H> {
836    fn clone(&self) -> Self {
837        Self(ManuallyDrop::new(self.0.raw_clone()))
838    }
839}
840
841impl<H: ChannelHalf + fmt::Debug + Clone> fmt::Debug for Weak<H> {
842    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
843        f.debug_tuple("Weak").field(&self.0).finish()
844    }
845}