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#[expect(private_bounds)]
30pub trait Channel: internal::Channel {
31 type TxHalf<T>: ChannelHalf<Msg = T, Channel = Self>;
33 type RxHalf<T>: ChannelHalf<Msg = T, Channel = Self>;
35 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
43pub trait BoundedChannel: Channel {}
45
46#[expect(private_bounds)]
48pub trait ChannelHalf: internal::ChannelHalf<Self::Msg, Self::Channel> {
49 type Msg;
51 type Channel: Channel;
53}
54
55#[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
113pub(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
380pub 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 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
427pub 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
467pub 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#[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 pub fn channel_id(&self) -> ChannelId {
520 self.0.id()
521 }
522
523 pub fn close_on_drop(self) -> CloseGuard<'a> {
525 CloseGuard(self.0)
526 }
527
528 pub fn closed(&self) -> ClosedFuture<'_> {
530 self.0.closed()
531 }
532}
533
534#[derive(Debug, Clone)]
536pub struct CloseGuard<'a>(Arc<dyn Close + 'a>);
537
538impl<'a> CloseGuard<'a> {
539 pub fn channel_id(&self) -> ChannelId {
541 self.0.id()
542 }
543
544 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 pub fn is_closed(&self) -> bool {
593 Ch::is_closed(&self.chan)
594 }
595 pub fn close(&self) {
597 self.chan.close();
598 }
599 pub fn close_handle<'a>(&self) -> CloseHandle<'a>
602 where
603 T: 'a,
604 {
605 CloseHandle::new(self.chan.clone())
606 }
607 pub fn channel_id(&self) -> ChannelId {
609 self.chan.id()
610 }
611 pub fn closed(&self) -> ClosedFuture<'_> {
613 ClosedFuture::new(&self.chan)
614 }
615 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 #[inline]
635 pub fn send(&$($mut)? self, msg: T) -> SendFuture<'_, T, Ch> {
636 SendFuture::new(&self.chan, msg)
637 }
638 #[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 #[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 #[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 #[inline]
658 pub fn try_send(&$($mut)? self, msg: T) -> Result<(), TrySendError<T>> {
659 self.chan.try_send(msg)
660 }
661 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 #[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 #[inline]
685 pub fn recv(&$($mut)? self) -> RecvFuture<'_, T, Ch> {
686 RecvFuture::new(&self.chan)
687 }
688 #[cfg(feature = "blocking")]
690 #[inline]
691 pub fn recv_blocking(&$($mut)? self) -> Result<T, RecvError> {
692 self.chan.recv_blocking()
693 }
694 #[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 #[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 #[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 #[inline]
713 pub fn try_recv(&$($mut)? self) -> Result<T, TryRecvError> {
714 self.chan.try_recv()
715 }
716 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 pub fn downgrade(&self) -> Weak<Self> {
734 Weak::new(self)
735 }
736 }
737 };
738}
739
740pub struct Tx<T, Ch: Channel> {
742 chan: Arc<Chan<T, Ch>>,
743}
744tx_half!(Tx, mut);
745channel_half!(Tx);
746
747pub struct MTx<T, Ch: Channel> {
749 chan: Arc<Chan<T, Ch>>,
750}
751tx_half!(MTx);
752channel_half!(MTx);
753cloneable_half!(MTx);
754
755pub struct UTx<T, Ch: Channel> {
757 chan: Arc<Chan<T, Ch>>,
758}
759utx_methods!(UTx, mut);
760channel_half!(UTx);
761
762pub struct UMTx<T, Ch: Channel> {
764 chan: Arc<Chan<T, Ch>>,
765}
766utx_methods!(UMTx);
767channel_half!(UMTx);
768cloneable_half!(UMTx);
769
770pub struct Rx<T, Ch: Channel> {
772 chan: Arc<Chan<T, Ch>>,
773}
774rx_half!(Rx, mut);
775channel_half!(Rx);
776
777pub 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 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
802pub 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 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}