Skip to main content

crossbeam_channel/
channel.rs

1//! The channel interface.
2
3use std::fmt;
4use std::iter::FusedIterator;
5use std::mem;
6use std::panic::{RefUnwindSafe, UnwindSafe};
7use std::sync::Arc;
8use std::time::{Duration, Instant};
9
10use crate::context::Context;
11use crate::counter;
12use crate::err::{
13    RecvError, RecvTimeoutError, SendError, SendTimeoutError, TryRecvError, TrySendError,
14};
15use crate::flavors;
16use crate::select::{Operation, SelectHandle, Token};
17
18/// Creates a channel of unbounded capacity.
19///
20/// This channel has a growable buffer that can hold any number of messages at a time.
21///
22/// # Examples
23///
24/// ```
25/// use std::thread;
26/// use crossbeam_channel::unbounded;
27///
28/// let (s, r) = unbounded();
29///
30/// // Computes the n-th Fibonacci number.
31/// fn fib(n: i32) -> i32 {
32///     if n <= 1 {
33///         n
34///     } else {
35///         fib(n - 1) + fib(n - 2)
36///     }
37/// }
38///
39/// // Spawn an asynchronous computation.
40/// thread::spawn(move || s.send(fib(20)).unwrap());
41///
42/// // Print the result of the computation.
43/// println!("{}", r.recv().unwrap());
44/// ```
45pub fn unbounded<T>() -> (Sender<T>, Receiver<T>) {
46    let (s, r) = counter::new(flavors::list::Channel::new());
47    let s = Sender {
48        flavor: SenderFlavor::List(s),
49    };
50    let r = Receiver {
51        flavor: ReceiverFlavor::List(r),
52    };
53    (s, r)
54}
55
56/// Creates a channel of bounded capacity.
57///
58/// This channel has a buffer that can hold at most `cap` messages at a time.
59///
60/// A special case is zero-capacity channel, which cannot hold any messages. Instead, send and
61/// receive operations must appear at the same time in order to pair up and pass the message over.
62///
63/// # Examples
64///
65/// A channel of capacity 1:
66///
67/// ```
68/// use std::thread;
69/// use std::time::Duration;
70/// use crossbeam_channel::bounded;
71///
72/// let (s, r) = bounded(1);
73///
74/// // This call returns immediately because there is enough space in the channel.
75/// s.send(1).unwrap();
76///
77/// thread::spawn(move || {
78///     // This call blocks the current thread because the channel is full.
79///     // It will be able to complete only after the first message is received.
80///     s.send(2).unwrap();
81/// });
82///
83/// thread::sleep(Duration::from_secs(1));
84/// assert_eq!(r.recv(), Ok(1));
85/// assert_eq!(r.recv(), Ok(2));
86/// ```
87///
88/// A zero-capacity channel:
89///
90/// ```
91/// use std::thread;
92/// use std::time::Duration;
93/// use crossbeam_channel::bounded;
94///
95/// let (s, r) = bounded(0);
96///
97/// thread::spawn(move || {
98///     // This call blocks the current thread until a receive operation appears
99///     // on the other side of the channel.
100///     s.send(1).unwrap();
101/// });
102///
103/// thread::sleep(Duration::from_secs(1));
104/// assert_eq!(r.recv(), Ok(1));
105/// ```
106pub fn bounded<T>(cap: usize) -> (Sender<T>, Receiver<T>) {
107    if cap == 0 {
108        let (s, r) = counter::new(flavors::zero::Channel::new());
109        let s = Sender {
110            flavor: SenderFlavor::Zero(s),
111        };
112        let r = Receiver {
113            flavor: ReceiverFlavor::Zero(r),
114        };
115        (s, r)
116    } else {
117        let (s, r) = counter::new(flavors::array::Channel::with_capacity(cap));
118        let s = Sender {
119            flavor: SenderFlavor::Array(s),
120        };
121        let r = Receiver {
122            flavor: ReceiverFlavor::Array(r),
123        };
124        (s, r)
125    }
126}
127
128/// Creates a receiver that delivers a message after a certain duration of time.
129///
130/// The channel is bounded with capacity of 1 and never gets disconnected. Exactly one message will
131/// be sent into the channel after `duration` elapses. The message is the instant at which it is
132/// sent.
133///
134/// # Examples
135///
136/// Using an `after` channel for timeouts:
137///
138/// ```
139/// use std::time::Duration;
140/// use crossbeam_channel::{after, select, unbounded};
141///
142/// let (s, r) = unbounded::<i32>();
143/// let timeout = Duration::from_millis(100);
144///
145/// select! {
146///     recv(r) -> msg => println!("received {:?}", msg),
147///     recv(after(timeout)) -> _ => println!("timed out"),
148/// }
149/// ```
150///
151/// When the message gets sent:
152///
153/// ```
154/// use std::thread;
155/// use std::time::{Duration, Instant};
156/// use crossbeam_channel::after;
157///
158/// // Converts a number of milliseconds into a `Duration`.
159/// let ms = |ms| Duration::from_millis(ms);
160///
161/// // Returns `true` if `a` and `b` are very close `Instant`s.
162/// let eq = |a, b| a + ms(60) > b && b + ms(60) > a;
163///
164/// let start = Instant::now();
165/// let r = after(ms(100));
166///
167/// thread::sleep(ms(500));
168///
169/// // This message was sent 100 ms from the start and received 500 ms from the start.
170/// assert!(eq(r.recv().unwrap(), start + ms(100)));
171/// assert!(eq(Instant::now(), start + ms(500)));
172/// ```
173pub fn after(duration: Duration) -> Receiver<Instant> {
174    match Instant::now().checked_add(duration) {
175        Some(deadline) => Receiver {
176            flavor: ReceiverFlavor::At(Arc::new(flavors::at::Channel::new_deadline(deadline))),
177        },
178        None => never(),
179    }
180}
181
182/// Creates a receiver that delivers a message at a certain instant in time.
183///
184/// The channel is bounded with capacity of 1 and never gets disconnected. Exactly one message will
185/// be sent into the channel at the moment in time `when`. The message is the instant at which it
186/// is sent, which is the same as `when`. If `when` is in the past, the message will be delivered
187/// instantly to the receiver.
188///
189/// # Examples
190///
191/// Using an `at` channel for timeouts:
192///
193/// ```
194/// use std::time::{Instant, Duration};
195/// use crossbeam_channel::{at, select, unbounded};
196///
197/// let (s, r) = unbounded::<i32>();
198/// let deadline = Instant::now() + Duration::from_millis(500);
199///
200/// select! {
201///     recv(r) -> msg => println!("received {:?}", msg),
202///     recv(at(deadline)) -> _ => println!("timed out"),
203/// }
204/// ```
205///
206/// When the message gets sent:
207///
208/// ```
209/// use std::time::{Duration, Instant};
210/// use crossbeam_channel::at;
211///
212/// // Converts a number of milliseconds into a `Duration`.
213/// let ms = |ms| Duration::from_millis(ms);
214///
215/// let start = Instant::now();
216/// let end = start + ms(100);
217///
218/// let r = at(end);
219///
220/// // This message was sent 100 ms from the start
221/// assert_eq!(r.recv().unwrap(), end);
222/// assert!(Instant::now() > start + ms(100));
223/// ```
224pub fn at(when: Instant) -> Receiver<Instant> {
225    Receiver {
226        flavor: ReceiverFlavor::At(Arc::new(flavors::at::Channel::new_deadline(when))),
227    }
228}
229
230/// Creates a receiver that never delivers messages.
231///
232/// The channel is bounded with capacity of 0 and never gets disconnected.
233///
234/// # Examples
235///
236/// Using a `never` channel to optionally add a timeout to [`select!`]:
237///
238/// [`select!`]: crate::select!
239///
240/// ```
241/// use std::thread;
242/// use std::time::Duration;
243/// use crossbeam_channel::{after, select, never, unbounded};
244///
245/// let (s, r) = unbounded();
246///
247/// thread::spawn(move || {
248///     thread::sleep(Duration::from_secs(1));
249///     s.send(1).unwrap();
250/// });
251///
252/// // Suppose this duration can be a `Some` or a `None`.
253/// let duration = Some(Duration::from_millis(100));
254///
255/// // Create a channel that times out after the specified duration.
256/// let timeout = duration
257///     .map(|d| after(d))
258///     .unwrap_or(never());
259///
260/// select! {
261///     recv(r) -> msg => assert_eq!(msg, Ok(1)),
262///     recv(timeout) -> _ => println!("timed out"),
263/// }
264/// ```
265pub const fn never<T>() -> Receiver<T> {
266    Receiver {
267        flavor: ReceiverFlavor::Never(flavors::never::Channel::new()),
268    }
269}
270
271/// Creates a receiver that delivers messages periodically.
272///
273/// The channel is bounded with capacity of 1 and never gets disconnected. Messages will be
274/// sent into the channel in intervals of `duration`. Each message is the instant at which it is
275/// sent.
276///
277/// # Examples
278///
279/// Using a `tick` channel to periodically print elapsed time:
280///
281/// ```
282/// use std::time::{Duration, Instant};
283/// use crossbeam_channel::tick;
284///
285/// let start = Instant::now();
286/// let ticker = tick(Duration::from_millis(100));
287///
288/// for _ in 0..5 {
289///     ticker.recv().unwrap();
290///     println!("elapsed: {:?}", start.elapsed());
291/// }
292/// ```
293///
294/// When messages get sent:
295///
296/// ```
297/// use std::thread;
298/// use std::time::{Duration, Instant};
299/// use crossbeam_channel::tick;
300///
301/// // Converts a number of milliseconds into a `Duration`.
302/// let ms = |ms| Duration::from_millis(ms);
303///
304/// // Returns `true` if `a` and `b` are very close `Instant`s.
305/// let eq = |a, b| a + ms(65) > b && b + ms(65) > a;
306///
307/// let start = Instant::now();
308/// let r = tick(ms(100));
309///
310/// // This message was sent 100 ms from the start and received 100 ms from the start.
311/// assert!(eq(r.recv().unwrap(), start + ms(100)));
312/// assert!(eq(Instant::now(), start + ms(100)));
313///
314/// thread::sleep(ms(500));
315///
316/// // This message was sent 200 ms from the start and received 600 ms from the start.
317/// assert!(eq(r.recv().unwrap(), start + ms(200)));
318/// assert!(eq(Instant::now(), start + ms(600)));
319///
320/// // This message was sent 700 ms from the start and received 700 ms from the start.
321/// assert!(eq(r.recv().unwrap(), start + ms(700)));
322/// assert!(eq(Instant::now(), start + ms(700)));
323/// ```
324pub fn tick(duration: Duration) -> Receiver<Instant> {
325    match Instant::now().checked_add(duration) {
326        Some(delivery_time) => Receiver {
327            flavor: ReceiverFlavor::Tick(Arc::new(flavors::tick::Channel::new(
328                delivery_time,
329                duration,
330            ))),
331        },
332        None => never(),
333    }
334}
335
336/// The sending side of a channel.
337///
338/// # Examples
339///
340/// ```
341/// use std::thread;
342/// use crossbeam_channel::unbounded;
343///
344/// let (s1, r) = unbounded();
345/// let s2 = s1.clone();
346///
347/// thread::spawn(move || s1.send(1).unwrap());
348/// thread::spawn(move || s2.send(2).unwrap());
349///
350/// let msg1 = r.recv().unwrap();
351/// let msg2 = r.recv().unwrap();
352///
353/// assert_eq!(msg1 + msg2, 3);
354/// ```
355pub struct Sender<T> {
356    flavor: SenderFlavor<T>,
357}
358
359/// Sender flavors.
360enum SenderFlavor<T> {
361    /// Bounded channel based on a preallocated array.
362    Array(counter::Sender<flavors::array::Channel<T>>),
363
364    /// Unbounded channel implemented as a linked list.
365    List(counter::Sender<flavors::list::Channel<T>>),
366
367    /// Zero-capacity channel.
368    Zero(counter::Sender<flavors::zero::Channel<T>>),
369}
370
371unsafe impl<T: Send> Send for Sender<T> {}
372unsafe impl<T: Send> Sync for Sender<T> {}
373
374impl<T> UnwindSafe for Sender<T> {}
375impl<T> RefUnwindSafe for Sender<T> {}
376
377impl<T> Sender<T> {
378    /// Attempts to send a message into the channel without blocking.
379    ///
380    /// This method will either send a message into the channel immediately or return an error if
381    /// the channel is full or disconnected. The returned error contains the original message.
382    ///
383    /// If called on a zero-capacity channel, this method will send the message only if there
384    /// happens to be a receive operation on the other side of the channel at the same time.
385    ///
386    /// # Examples
387    ///
388    /// ```
389    /// use crossbeam_channel::{bounded, TrySendError};
390    ///
391    /// let (s, r) = bounded(1);
392    ///
393    /// assert_eq!(s.try_send(1), Ok(()));
394    /// assert_eq!(s.try_send(2), Err(TrySendError::Full(2)));
395    ///
396    /// drop(r);
397    /// assert_eq!(s.try_send(3), Err(TrySendError::Disconnected(3)));
398    /// ```
399    pub fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> {
400        match &self.flavor {
401            SenderFlavor::Array(chan) => chan.try_send(msg),
402            SenderFlavor::List(chan) => chan.try_send(msg),
403            SenderFlavor::Zero(chan) => chan.try_send(msg),
404        }
405    }
406
407    /// Blocks the current thread until a message is sent or the channel is disconnected.
408    ///
409    /// If the channel is full and not disconnected, this call will block until the send operation
410    /// can proceed. If the channel becomes disconnected, this call will wake up and return an
411    /// error. The returned error contains the original message.
412    ///
413    /// If called on a zero-capacity channel, this method will wait for a receive operation to
414    /// appear on the other side of the channel.
415    ///
416    /// # Examples
417    ///
418    /// ```
419    /// use std::thread;
420    /// use std::time::Duration;
421    /// use crossbeam_channel::{bounded, SendError};
422    ///
423    /// let (s, r) = bounded(1);
424    /// assert_eq!(s.send(1), Ok(()));
425    ///
426    /// thread::spawn(move || {
427    ///     assert_eq!(r.recv(), Ok(1));
428    ///     thread::sleep(Duration::from_secs(1));
429    ///     drop(r);
430    /// });
431    ///
432    /// assert_eq!(s.send(2), Ok(()));
433    /// assert_eq!(s.send(3), Err(SendError(3)));
434    /// ```
435    pub fn send(&self, msg: T) -> Result<(), SendError<T>> {
436        match &self.flavor {
437            SenderFlavor::Array(chan) => chan.send(msg, None),
438            SenderFlavor::List(chan) => chan.send(msg, None),
439            SenderFlavor::Zero(chan) => chan.send(msg, None),
440        }
441        .map_err(|err| match err {
442            SendTimeoutError::Disconnected(msg) => SendError(msg),
443            SendTimeoutError::Timeout(_) => unreachable!(),
444        })
445    }
446
447    /// Waits for a message to be sent into the channel, but only for a limited time.
448    ///
449    /// If the channel is full and not disconnected, this call will block until the send operation
450    /// can proceed or the operation times out. If the channel becomes disconnected, this call will
451    /// wake up and return an error. The returned error contains the original message.
452    ///
453    /// If called on a zero-capacity channel, this method will wait for a receive operation to
454    /// appear on the other side of the channel.
455    ///
456    /// # Examples
457    ///
458    /// ```
459    /// use std::thread;
460    /// use std::time::Duration;
461    /// use crossbeam_channel::{bounded, SendTimeoutError};
462    ///
463    /// let (s, r) = bounded(0);
464    ///
465    /// thread::spawn(move || {
466    ///     thread::sleep(Duration::from_secs(1));
467    ///     assert_eq!(r.recv(), Ok(2));
468    ///     drop(r);
469    /// });
470    ///
471    /// assert_eq!(
472    ///     s.send_timeout(1, Duration::from_millis(500)),
473    ///     Err(SendTimeoutError::Timeout(1)),
474    /// );
475    /// assert_eq!(
476    ///     s.send_timeout(2, Duration::from_secs(1)),
477    ///     Ok(()),
478    /// );
479    /// assert_eq!(
480    ///     s.send_timeout(3, Duration::from_millis(500)),
481    ///     Err(SendTimeoutError::Disconnected(3)),
482    /// );
483    /// ```
484    pub fn send_timeout(&self, msg: T, timeout: Duration) -> Result<(), SendTimeoutError<T>> {
485        match Instant::now().checked_add(timeout) {
486            Some(deadline) => self.send_deadline(msg, deadline),
487            None => self.send(msg).map_err(SendTimeoutError::from),
488        }
489    }
490
491    /// Waits for a message to be sent into the channel, but only until a given deadline.
492    ///
493    /// If the channel is full and not disconnected, this call will block until the send operation
494    /// can proceed or the operation times out. If the channel becomes disconnected, this call will
495    /// wake up and return an error. The returned error contains the original message.
496    ///
497    /// If called on a zero-capacity channel, this method will wait for a receive operation to
498    /// appear on the other side of the channel.
499    ///
500    /// # Examples
501    ///
502    /// ```
503    /// use std::thread;
504    /// use std::time::{Duration, Instant};
505    /// use crossbeam_channel::{bounded, SendTimeoutError};
506    ///
507    /// let (s, r) = bounded(0);
508    ///
509    /// thread::spawn(move || {
510    ///     thread::sleep(Duration::from_secs(1));
511    ///     assert_eq!(r.recv(), Ok(2));
512    ///     drop(r);
513    /// });
514    ///
515    /// let now = Instant::now();
516    ///
517    /// assert_eq!(
518    ///     s.send_deadline(1, now + Duration::from_millis(500)),
519    ///     Err(SendTimeoutError::Timeout(1)),
520    /// );
521    /// assert_eq!(
522    ///     s.send_deadline(2, now + Duration::from_millis(1500)),
523    ///     Ok(()),
524    /// );
525    /// assert_eq!(
526    ///     s.send_deadline(3, now + Duration::from_millis(2000)),
527    ///     Err(SendTimeoutError::Disconnected(3)),
528    /// );
529    /// ```
530    pub fn send_deadline(&self, msg: T, deadline: Instant) -> Result<(), SendTimeoutError<T>> {
531        match &self.flavor {
532            SenderFlavor::Array(chan) => chan.send(msg, Some(deadline)),
533            SenderFlavor::List(chan) => chan.send(msg, Some(deadline)),
534            SenderFlavor::Zero(chan) => chan.send(msg, Some(deadline)),
535        }
536    }
537
538    /// Returns `true` if the channel is empty.
539    ///
540    /// Note: Zero-capacity channels are always empty.
541    ///
542    /// # Examples
543    ///
544    /// ```
545    /// use crossbeam_channel::unbounded;
546    ///
547    /// let (s, r) = unbounded();
548    /// assert!(s.is_empty());
549    ///
550    /// s.send(0).unwrap();
551    /// assert!(!s.is_empty());
552    /// ```
553    pub fn is_empty(&self) -> bool {
554        match &self.flavor {
555            SenderFlavor::Array(chan) => chan.is_empty(),
556            SenderFlavor::List(chan) => chan.is_empty(),
557            SenderFlavor::Zero(chan) => chan.is_empty(),
558        }
559    }
560
561    /// Returns `true` if the channel is full.
562    ///
563    /// Note: Zero-capacity channels are always full.
564    ///
565    /// # Examples
566    ///
567    /// ```
568    /// use crossbeam_channel::bounded;
569    ///
570    /// let (s, r) = bounded(1);
571    ///
572    /// assert!(!s.is_full());
573    /// s.send(0).unwrap();
574    /// assert!(s.is_full());
575    /// ```
576    pub fn is_full(&self) -> bool {
577        match &self.flavor {
578            SenderFlavor::Array(chan) => chan.is_full(),
579            SenderFlavor::List(chan) => chan.is_full(),
580            SenderFlavor::Zero(chan) => chan.is_full(),
581        }
582    }
583
584    /// Returns the number of messages in the channel.
585    ///
586    /// # Examples
587    ///
588    /// ```
589    /// use crossbeam_channel::unbounded;
590    ///
591    /// let (s, r) = unbounded();
592    /// assert_eq!(s.len(), 0);
593    ///
594    /// s.send(1).unwrap();
595    /// s.send(2).unwrap();
596    /// assert_eq!(s.len(), 2);
597    /// ```
598    pub fn len(&self) -> usize {
599        match &self.flavor {
600            SenderFlavor::Array(chan) => chan.len(),
601            SenderFlavor::List(chan) => chan.len(),
602            SenderFlavor::Zero(chan) => chan.len(),
603        }
604    }
605
606    /// If the channel is bounded, returns its capacity.
607    ///
608    /// # Examples
609    ///
610    /// ```
611    /// use crossbeam_channel::{bounded, unbounded};
612    ///
613    /// let (s, _) = unbounded::<i32>();
614    /// assert_eq!(s.capacity(), None);
615    ///
616    /// let (s, _) = bounded::<i32>(5);
617    /// assert_eq!(s.capacity(), Some(5));
618    ///
619    /// let (s, _) = bounded::<i32>(0);
620    /// assert_eq!(s.capacity(), Some(0));
621    /// ```
622    pub fn capacity(&self) -> Option<usize> {
623        match &self.flavor {
624            SenderFlavor::Array(chan) => chan.capacity(),
625            SenderFlavor::List(chan) => chan.capacity(),
626            SenderFlavor::Zero(chan) => chan.capacity(),
627        }
628    }
629
630    /// Returns `true` if senders belong to the same channel.
631    ///
632    /// # Examples
633    ///
634    /// ```rust
635    /// use crossbeam_channel::unbounded;
636    ///
637    /// let (s, _) = unbounded::<usize>();
638    ///
639    /// let s2 = s.clone();
640    /// assert!(s.same_channel(&s2));
641    ///
642    /// let (s3, _) = unbounded();
643    /// assert!(!s.same_channel(&s3));
644    /// ```
645    pub fn same_channel(&self, other: &Sender<T>) -> bool {
646        match (&self.flavor, &other.flavor) {
647            (SenderFlavor::Array(ref a), SenderFlavor::Array(ref b)) => a == b,
648            (SenderFlavor::List(ref a), SenderFlavor::List(ref b)) => a == b,
649            (SenderFlavor::Zero(ref a), SenderFlavor::Zero(ref b)) => a == b,
650            _ => false,
651        }
652    }
653}
654
655impl<T> Drop for Sender<T> {
656    fn drop(&mut self) {
657        unsafe {
658            match &self.flavor {
659                SenderFlavor::Array(chan) => chan.release(|c| c.disconnect()),
660                SenderFlavor::List(chan) => chan.release(|c| c.disconnect_senders()),
661                SenderFlavor::Zero(chan) => chan.release(|c| c.disconnect()),
662            }
663        }
664    }
665}
666
667impl<T> Clone for Sender<T> {
668    fn clone(&self) -> Self {
669        let flavor = match &self.flavor {
670            SenderFlavor::Array(chan) => SenderFlavor::Array(chan.acquire()),
671            SenderFlavor::List(chan) => SenderFlavor::List(chan.acquire()),
672            SenderFlavor::Zero(chan) => SenderFlavor::Zero(chan.acquire()),
673        };
674
675        Sender { flavor }
676    }
677}
678
679impl<T> fmt::Debug for Sender<T> {
680    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
681        f.pad("Sender { .. }")
682    }
683}
684
685/// The receiving side of a channel.
686///
687/// # Examples
688///
689/// ```
690/// use std::thread;
691/// use std::time::Duration;
692/// use crossbeam_channel::unbounded;
693///
694/// let (s, r) = unbounded();
695///
696/// thread::spawn(move || {
697///     let _ = s.send(1);
698///     thread::sleep(Duration::from_secs(1));
699///     let _ = s.send(2);
700/// });
701///
702/// assert_eq!(r.recv(), Ok(1)); // Received immediately.
703/// assert_eq!(r.recv(), Ok(2)); // Received after 1 second.
704/// ```
705pub struct Receiver<T> {
706    flavor: ReceiverFlavor<T>,
707}
708
709/// Receiver flavors.
710enum ReceiverFlavor<T> {
711    /// Bounded channel based on a preallocated array.
712    Array(counter::Receiver<flavors::array::Channel<T>>),
713
714    /// Unbounded channel implemented as a linked list.
715    List(counter::Receiver<flavors::list::Channel<T>>),
716
717    /// Zero-capacity channel.
718    Zero(counter::Receiver<flavors::zero::Channel<T>>),
719
720    /// The after flavor.
721    At(Arc<flavors::at::Channel>),
722
723    /// The tick flavor.
724    Tick(Arc<flavors::tick::Channel>),
725
726    /// The never flavor.
727    Never(flavors::never::Channel<T>),
728}
729
730unsafe impl<T: Send> Send for Receiver<T> {}
731unsafe impl<T: Send> Sync for Receiver<T> {}
732
733impl<T> UnwindSafe for Receiver<T> {}
734impl<T> RefUnwindSafe for Receiver<T> {}
735
736impl<T> Receiver<T> {
737    /// Attempts to receive a message from the channel without blocking.
738    ///
739    /// This method will either receive a message from the channel immediately or return an error
740    /// if the channel is empty.
741    ///
742    /// If called on a zero-capacity channel, this method will receive a message only if there
743    /// happens to be a send operation on the other side of the channel at the same time.
744    ///
745    /// # Examples
746    ///
747    /// ```
748    /// use crossbeam_channel::{unbounded, TryRecvError};
749    ///
750    /// let (s, r) = unbounded();
751    /// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
752    ///
753    /// s.send(5).unwrap();
754    /// drop(s);
755    ///
756    /// assert_eq!(r.try_recv(), Ok(5));
757    /// assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected));
758    /// ```
759    pub fn try_recv(&self) -> Result<T, TryRecvError> {
760        match &self.flavor {
761            ReceiverFlavor::Array(chan) => chan.try_recv(),
762            ReceiverFlavor::List(chan) => chan.try_recv(),
763            ReceiverFlavor::Zero(chan) => chan.try_recv(),
764            ReceiverFlavor::At(chan) => {
765                let msg = chan.try_recv();
766                unsafe {
767                    mem::transmute_copy::<Result<Instant, TryRecvError>, Result<T, TryRecvError>>(
768                        &msg,
769                    )
770                }
771            }
772            ReceiverFlavor::Tick(chan) => {
773                let msg = chan.try_recv();
774                unsafe {
775                    mem::transmute_copy::<Result<Instant, TryRecvError>, Result<T, TryRecvError>>(
776                        &msg,
777                    )
778                }
779            }
780            ReceiverFlavor::Never(chan) => chan.try_recv(),
781        }
782    }
783
784    /// Blocks the current thread until a message is received or the channel is empty and
785    /// disconnected.
786    ///
787    /// If the channel is empty and not disconnected, this call will block until the receive
788    /// operation can proceed. If the channel is empty and becomes disconnected, this call will
789    /// wake up and return an error.
790    ///
791    /// If called on a zero-capacity channel, this method will wait for a send operation to appear
792    /// on the other side of the channel.
793    ///
794    /// # Examples
795    ///
796    /// ```
797    /// use std::thread;
798    /// use std::time::Duration;
799    /// use crossbeam_channel::{unbounded, RecvError};
800    ///
801    /// let (s, r) = unbounded();
802    ///
803    /// thread::spawn(move || {
804    ///     thread::sleep(Duration::from_secs(1));
805    ///     s.send(5).unwrap();
806    ///     drop(s);
807    /// });
808    ///
809    /// assert_eq!(r.recv(), Ok(5));
810    /// assert_eq!(r.recv(), Err(RecvError));
811    /// ```
812    pub fn recv(&self) -> Result<T, RecvError> {
813        match &self.flavor {
814            ReceiverFlavor::Array(chan) => chan.recv(None),
815            ReceiverFlavor::List(chan) => chan.recv(None),
816            ReceiverFlavor::Zero(chan) => chan.recv(None),
817            ReceiverFlavor::At(chan) => {
818                let msg = chan.recv(None);
819                unsafe {
820                    mem::transmute_copy::<
821                        Result<Instant, RecvTimeoutError>,
822                        Result<T, RecvTimeoutError>,
823                    >(&msg)
824                }
825            }
826            ReceiverFlavor::Tick(chan) => {
827                let msg = chan.recv(None);
828                unsafe {
829                    mem::transmute_copy::<
830                        Result<Instant, RecvTimeoutError>,
831                        Result<T, RecvTimeoutError>,
832                    >(&msg)
833                }
834            }
835            ReceiverFlavor::Never(chan) => chan.recv(None),
836        }
837        .map_err(|_| RecvError)
838    }
839
840    /// Waits for a message to be received from the channel, but only for a limited time.
841    ///
842    /// If the channel is empty and not disconnected, this call will block until the receive
843    /// operation can proceed or the operation times out. If the channel is empty and becomes
844    /// disconnected, this call will wake up and return an error.
845    ///
846    /// If called on a zero-capacity channel, this method will wait for a send operation to appear
847    /// on the other side of the channel.
848    ///
849    /// # Examples
850    ///
851    /// ```
852    /// use std::thread;
853    /// use std::time::Duration;
854    /// use crossbeam_channel::{unbounded, RecvTimeoutError};
855    ///
856    /// let (s, r) = unbounded();
857    ///
858    /// thread::spawn(move || {
859    ///     thread::sleep(Duration::from_secs(1));
860    ///     s.send(5).unwrap();
861    ///     drop(s);
862    /// });
863    ///
864    /// assert_eq!(
865    ///     r.recv_timeout(Duration::from_millis(500)),
866    ///     Err(RecvTimeoutError::Timeout),
867    /// );
868    /// assert_eq!(
869    ///     r.recv_timeout(Duration::from_secs(1)),
870    ///     Ok(5),
871    /// );
872    /// assert_eq!(
873    ///     r.recv_timeout(Duration::from_secs(1)),
874    ///     Err(RecvTimeoutError::Disconnected),
875    /// );
876    /// ```
877    pub fn recv_timeout(&self, timeout: Duration) -> Result<T, RecvTimeoutError> {
878        match Instant::now().checked_add(timeout) {
879            Some(deadline) => self.recv_deadline(deadline),
880            None => self.recv().map_err(RecvTimeoutError::from),
881        }
882    }
883
884    /// Waits for a message to be received from the channel, but only before a given deadline.
885    ///
886    /// If the channel is empty and not disconnected, this call will block until the receive
887    /// operation can proceed or the operation times out. If the channel is empty and becomes
888    /// disconnected, this call will wake up and return an error. If the channel is non-empty
889    /// and the deadline has already been reached, the next message in the channel will be
890    /// returned.
891    ///
892    /// If called on a zero-capacity channel, this method will wait for a send operation to appear
893    /// on the other side of the channel.
894    ///
895    /// # Examples
896    ///
897    /// ```
898    /// use std::thread;
899    /// use std::time::{Instant, Duration};
900    /// use crossbeam_channel::{unbounded, RecvTimeoutError};
901    ///
902    /// let (s, r) = unbounded();
903    ///
904    /// thread::spawn(move || {
905    ///     thread::sleep(Duration::from_secs(1));
906    ///     s.send(5).unwrap();
907    ///     drop(s);
908    /// });
909    ///
910    /// let now = Instant::now();
911    ///
912    /// assert_eq!(
913    ///     r.recv_deadline(now + Duration::from_millis(500)),
914    ///     Err(RecvTimeoutError::Timeout),
915    /// );
916    /// assert_eq!(
917    ///     r.recv_deadline(now + Duration::from_millis(1500)),
918    ///     Ok(5),
919    /// );
920    /// assert_eq!(
921    ///     r.recv_deadline(now + Duration::from_secs(5)),
922    ///     Err(RecvTimeoutError::Disconnected),
923    /// );
924    /// ```
925    pub fn recv_deadline(&self, deadline: Instant) -> Result<T, RecvTimeoutError> {
926        match &self.flavor {
927            ReceiverFlavor::Array(chan) => chan.recv(Some(deadline)),
928            ReceiverFlavor::List(chan) => chan.recv(Some(deadline)),
929            ReceiverFlavor::Zero(chan) => chan.recv(Some(deadline)),
930            ReceiverFlavor::At(chan) => {
931                let msg = chan.recv(Some(deadline));
932                unsafe {
933                    mem::transmute_copy::<
934                        Result<Instant, RecvTimeoutError>,
935                        Result<T, RecvTimeoutError>,
936                    >(&msg)
937                }
938            }
939            ReceiverFlavor::Tick(chan) => {
940                let msg = chan.recv(Some(deadline));
941                unsafe {
942                    mem::transmute_copy::<
943                        Result<Instant, RecvTimeoutError>,
944                        Result<T, RecvTimeoutError>,
945                    >(&msg)
946                }
947            }
948            ReceiverFlavor::Never(chan) => chan.recv(Some(deadline)),
949        }
950    }
951
952    /// Returns `true` if the channel is empty.
953    ///
954    /// Note: Zero-capacity channels are always empty.
955    ///
956    /// # Examples
957    ///
958    /// ```
959    /// use crossbeam_channel::unbounded;
960    ///
961    /// let (s, r) = unbounded();
962    ///
963    /// assert!(r.is_empty());
964    /// s.send(0).unwrap();
965    /// assert!(!r.is_empty());
966    /// ```
967    pub fn is_empty(&self) -> bool {
968        match &self.flavor {
969            ReceiverFlavor::Array(chan) => chan.is_empty(),
970            ReceiverFlavor::List(chan) => chan.is_empty(),
971            ReceiverFlavor::Zero(chan) => chan.is_empty(),
972            ReceiverFlavor::At(chan) => chan.is_empty(),
973            ReceiverFlavor::Tick(chan) => chan.is_empty(),
974            ReceiverFlavor::Never(chan) => chan.is_empty(),
975        }
976    }
977
978    /// Returns `true` if the channel is full.
979    ///
980    /// Note: Zero-capacity channels are always full.
981    ///
982    /// # Examples
983    ///
984    /// ```
985    /// use crossbeam_channel::bounded;
986    ///
987    /// let (s, r) = bounded(1);
988    ///
989    /// assert!(!r.is_full());
990    /// s.send(0).unwrap();
991    /// assert!(r.is_full());
992    /// ```
993    pub fn is_full(&self) -> bool {
994        match &self.flavor {
995            ReceiverFlavor::Array(chan) => chan.is_full(),
996            ReceiverFlavor::List(chan) => chan.is_full(),
997            ReceiverFlavor::Zero(chan) => chan.is_full(),
998            ReceiverFlavor::At(chan) => chan.is_full(),
999            ReceiverFlavor::Tick(chan) => chan.is_full(),
1000            ReceiverFlavor::Never(chan) => chan.is_full(),
1001        }
1002    }
1003
1004    /// Returns the number of messages in the channel.
1005    ///
1006    /// # Examples
1007    ///
1008    /// ```
1009    /// use crossbeam_channel::unbounded;
1010    ///
1011    /// let (s, r) = unbounded();
1012    /// assert_eq!(r.len(), 0);
1013    ///
1014    /// s.send(1).unwrap();
1015    /// s.send(2).unwrap();
1016    /// assert_eq!(r.len(), 2);
1017    /// ```
1018    pub fn len(&self) -> usize {
1019        match &self.flavor {
1020            ReceiverFlavor::Array(chan) => chan.len(),
1021            ReceiverFlavor::List(chan) => chan.len(),
1022            ReceiverFlavor::Zero(chan) => chan.len(),
1023            ReceiverFlavor::At(chan) => chan.len(),
1024            ReceiverFlavor::Tick(chan) => chan.len(),
1025            ReceiverFlavor::Never(chan) => chan.len(),
1026        }
1027    }
1028
1029    /// If the channel is bounded, returns its capacity.
1030    ///
1031    /// # Examples
1032    ///
1033    /// ```
1034    /// use crossbeam_channel::{bounded, unbounded};
1035    ///
1036    /// let (_, r) = unbounded::<i32>();
1037    /// assert_eq!(r.capacity(), None);
1038    ///
1039    /// let (_, r) = bounded::<i32>(5);
1040    /// assert_eq!(r.capacity(), Some(5));
1041    ///
1042    /// let (_, r) = bounded::<i32>(0);
1043    /// assert_eq!(r.capacity(), Some(0));
1044    /// ```
1045    pub fn capacity(&self) -> Option<usize> {
1046        match &self.flavor {
1047            ReceiverFlavor::Array(chan) => chan.capacity(),
1048            ReceiverFlavor::List(chan) => chan.capacity(),
1049            ReceiverFlavor::Zero(chan) => chan.capacity(),
1050            ReceiverFlavor::At(chan) => chan.capacity(),
1051            ReceiverFlavor::Tick(chan) => chan.capacity(),
1052            ReceiverFlavor::Never(chan) => chan.capacity(),
1053        }
1054    }
1055
1056    /// A blocking iterator over messages in the channel.
1057    ///
1058    /// Each call to [`next`] blocks waiting for the next message and then returns it. However, if
1059    /// the channel becomes empty and disconnected, it returns [`None`] without blocking.
1060    ///
1061    /// [`next`]: Iterator::next
1062    ///
1063    /// # Examples
1064    ///
1065    /// ```
1066    /// use std::thread;
1067    /// use crossbeam_channel::unbounded;
1068    ///
1069    /// let (s, r) = unbounded();
1070    ///
1071    /// thread::spawn(move || {
1072    ///     s.send(1).unwrap();
1073    ///     s.send(2).unwrap();
1074    ///     s.send(3).unwrap();
1075    ///     drop(s); // Disconnect the channel.
1076    /// });
1077    ///
1078    /// // Collect all messages from the channel.
1079    /// // Note that the call to `collect` blocks until the sender is dropped.
1080    /// let v: Vec<_> = r.iter().collect();
1081    ///
1082    /// assert_eq!(v, [1, 2, 3]);
1083    /// ```
1084    pub fn iter(&self) -> Iter<'_, T> {
1085        Iter { receiver: self }
1086    }
1087
1088    /// A non-blocking iterator over messages in the channel.
1089    ///
1090    /// Each call to [`next`] returns a message if there is one ready to be received. The iterator
1091    /// never blocks waiting for the next message.
1092    ///
1093    /// [`next`]: Iterator::next
1094    ///
1095    /// # Examples
1096    ///
1097    /// ```
1098    /// use std::thread;
1099    /// use std::time::Duration;
1100    /// use crossbeam_channel::unbounded;
1101    ///
1102    /// let (s, r) = unbounded::<i32>();
1103    ///
1104    /// thread::spawn(move || {
1105    ///     s.send(1).unwrap();
1106    ///     thread::sleep(Duration::from_secs(1));
1107    ///     s.send(2).unwrap();
1108    ///     thread::sleep(Duration::from_secs(2));
1109    ///     s.send(3).unwrap();
1110    /// });
1111    ///
1112    /// thread::sleep(Duration::from_secs(2));
1113    ///
1114    /// // Collect all messages from the channel without blocking.
1115    /// // The third message hasn't been sent yet so we'll collect only the first two.
1116    /// let v: Vec<_> = r.try_iter().collect();
1117    ///
1118    /// assert_eq!(v, [1, 2]);
1119    /// ```
1120    pub fn try_iter(&self) -> TryIter<'_, T> {
1121        TryIter { receiver: self }
1122    }
1123
1124    /// Returns `true` if receivers belong to the same channel.
1125    ///
1126    /// # Examples
1127    ///
1128    /// ```rust
1129    /// use crossbeam_channel::unbounded;
1130    ///
1131    /// let (_, r) = unbounded::<usize>();
1132    ///
1133    /// let r2 = r.clone();
1134    /// assert!(r.same_channel(&r2));
1135    ///
1136    /// let (_, r3) = unbounded();
1137    /// assert!(!r.same_channel(&r3));
1138    /// ```
1139    pub fn same_channel(&self, other: &Receiver<T>) -> bool {
1140        match (&self.flavor, &other.flavor) {
1141            (ReceiverFlavor::Array(a), ReceiverFlavor::Array(b)) => a == b,
1142            (ReceiverFlavor::List(a), ReceiverFlavor::List(b)) => a == b,
1143            (ReceiverFlavor::Zero(a), ReceiverFlavor::Zero(b)) => a == b,
1144            (ReceiverFlavor::At(a), ReceiverFlavor::At(b)) => Arc::ptr_eq(a, b),
1145            (ReceiverFlavor::Tick(a), ReceiverFlavor::Tick(b)) => Arc::ptr_eq(a, b),
1146            (ReceiverFlavor::Never(_), ReceiverFlavor::Never(_)) => true,
1147            _ => false,
1148        }
1149    }
1150}
1151
1152impl<T> Drop for Receiver<T> {
1153    fn drop(&mut self) {
1154        unsafe {
1155            match &self.flavor {
1156                ReceiverFlavor::Array(chan) => chan.release(|c| c.disconnect()),
1157                ReceiverFlavor::List(chan) => chan.release(|c| c.disconnect_receivers()),
1158                ReceiverFlavor::Zero(chan) => chan.release(|c| c.disconnect()),
1159                ReceiverFlavor::At(_) => {}
1160                ReceiverFlavor::Tick(_) => {}
1161                ReceiverFlavor::Never(_) => {}
1162            }
1163        }
1164    }
1165}
1166
1167impl<T> Clone for Receiver<T> {
1168    fn clone(&self) -> Self {
1169        let flavor = match &self.flavor {
1170            ReceiverFlavor::Array(chan) => ReceiverFlavor::Array(chan.acquire()),
1171            ReceiverFlavor::List(chan) => ReceiverFlavor::List(chan.acquire()),
1172            ReceiverFlavor::Zero(chan) => ReceiverFlavor::Zero(chan.acquire()),
1173            ReceiverFlavor::At(chan) => ReceiverFlavor::At(chan.clone()),
1174            ReceiverFlavor::Tick(chan) => ReceiverFlavor::Tick(chan.clone()),
1175            ReceiverFlavor::Never(_) => ReceiverFlavor::Never(flavors::never::Channel::new()),
1176        };
1177
1178        Receiver { flavor }
1179    }
1180}
1181
1182impl<T> fmt::Debug for Receiver<T> {
1183    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1184        f.pad("Receiver { .. }")
1185    }
1186}
1187
1188impl<'a, T> IntoIterator for &'a Receiver<T> {
1189    type Item = T;
1190    type IntoIter = Iter<'a, T>;
1191
1192    fn into_iter(self) -> Self::IntoIter {
1193        self.iter()
1194    }
1195}
1196
1197impl<T> IntoIterator for Receiver<T> {
1198    type Item = T;
1199    type IntoIter = IntoIter<T>;
1200
1201    fn into_iter(self) -> Self::IntoIter {
1202        IntoIter { receiver: self }
1203    }
1204}
1205
1206/// A blocking iterator over messages in a channel.
1207///
1208/// Each call to [`next`] blocks waiting for the next message and then returns it. However, if the
1209/// channel becomes empty and disconnected, it returns [`None`] without blocking.
1210///
1211/// [`next`]: Iterator::next
1212///
1213/// # Examples
1214///
1215/// ```
1216/// use std::thread;
1217/// use crossbeam_channel::unbounded;
1218///
1219/// let (s, r) = unbounded();
1220///
1221/// thread::spawn(move || {
1222///     s.send(1).unwrap();
1223///     s.send(2).unwrap();
1224///     s.send(3).unwrap();
1225///     drop(s); // Disconnect the channel.
1226/// });
1227///
1228/// // Collect all messages from the channel.
1229/// // Note that the call to `collect` blocks until the sender is dropped.
1230/// let v: Vec<_> = r.iter().collect();
1231///
1232/// assert_eq!(v, [1, 2, 3]);
1233/// ```
1234pub struct Iter<'a, T> {
1235    receiver: &'a Receiver<T>,
1236}
1237
1238impl<T> FusedIterator for Iter<'_, T> {}
1239
1240impl<T> Iterator for Iter<'_, T> {
1241    type Item = T;
1242
1243    fn next(&mut self) -> Option<Self::Item> {
1244        self.receiver.recv().ok()
1245    }
1246}
1247
1248impl<T> fmt::Debug for Iter<'_, T> {
1249    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1250        f.pad("Iter { .. }")
1251    }
1252}
1253
1254/// A non-blocking iterator over messages in a channel.
1255///
1256/// Each call to [`next`] returns a message if there is one ready to be received. The iterator
1257/// never blocks waiting for the next message.
1258///
1259/// [`next`]: Iterator::next
1260///
1261/// # Examples
1262///
1263/// ```
1264/// use std::thread;
1265/// use std::time::Duration;
1266/// use crossbeam_channel::unbounded;
1267///
1268/// let (s, r) = unbounded::<i32>();
1269///
1270/// thread::spawn(move || {
1271///     s.send(1).unwrap();
1272///     thread::sleep(Duration::from_secs(1));
1273///     s.send(2).unwrap();
1274///     thread::sleep(Duration::from_secs(2));
1275///     s.send(3).unwrap();
1276/// });
1277///
1278/// thread::sleep(Duration::from_secs(2));
1279///
1280/// // Collect all messages from the channel without blocking.
1281/// // The third message hasn't been sent yet so we'll collect only the first two.
1282/// let v: Vec<_> = r.try_iter().collect();
1283///
1284/// assert_eq!(v, [1, 2]);
1285/// ```
1286pub struct TryIter<'a, T> {
1287    receiver: &'a Receiver<T>,
1288}
1289
1290impl<T> Iterator for TryIter<'_, T> {
1291    type Item = T;
1292
1293    fn next(&mut self) -> Option<Self::Item> {
1294        self.receiver.try_recv().ok()
1295    }
1296}
1297
1298impl<T> fmt::Debug for TryIter<'_, T> {
1299    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1300        f.pad("TryIter { .. }")
1301    }
1302}
1303
1304/// A blocking iterator over messages in a channel.
1305///
1306/// Each call to [`next`] blocks waiting for the next message and then returns it. However, if the
1307/// channel becomes empty and disconnected, it returns [`None`] without blocking.
1308///
1309/// [`next`]: Iterator::next
1310///
1311/// # Examples
1312///
1313/// ```
1314/// use std::thread;
1315/// use crossbeam_channel::unbounded;
1316///
1317/// let (s, r) = unbounded();
1318///
1319/// thread::spawn(move || {
1320///     s.send(1).unwrap();
1321///     s.send(2).unwrap();
1322///     s.send(3).unwrap();
1323///     drop(s); // Disconnect the channel.
1324/// });
1325///
1326/// // Collect all messages from the channel.
1327/// // Note that the call to `collect` blocks until the sender is dropped.
1328/// let v: Vec<_> = r.into_iter().collect();
1329///
1330/// assert_eq!(v, [1, 2, 3]);
1331/// ```
1332pub struct IntoIter<T> {
1333    receiver: Receiver<T>,
1334}
1335
1336impl<T> FusedIterator for IntoIter<T> {}
1337
1338impl<T> Iterator for IntoIter<T> {
1339    type Item = T;
1340
1341    fn next(&mut self) -> Option<Self::Item> {
1342        self.receiver.recv().ok()
1343    }
1344}
1345
1346impl<T> fmt::Debug for IntoIter<T> {
1347    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1348        f.pad("IntoIter { .. }")
1349    }
1350}
1351
1352impl<T> SelectHandle for Sender<T> {
1353    fn try_select(&self, token: &mut Token) -> bool {
1354        match &self.flavor {
1355            SenderFlavor::Array(chan) => chan.sender().try_select(token),
1356            SenderFlavor::List(chan) => chan.sender().try_select(token),
1357            SenderFlavor::Zero(chan) => chan.sender().try_select(token),
1358        }
1359    }
1360
1361    fn deadline(&self) -> Option<Instant> {
1362        None
1363    }
1364
1365    fn register(&self, oper: Operation, cx: &Context) -> bool {
1366        match &self.flavor {
1367            SenderFlavor::Array(chan) => chan.sender().register(oper, cx),
1368            SenderFlavor::List(chan) => chan.sender().register(oper, cx),
1369            SenderFlavor::Zero(chan) => chan.sender().register(oper, cx),
1370        }
1371    }
1372
1373    fn unregister(&self, oper: Operation) {
1374        match &self.flavor {
1375            SenderFlavor::Array(chan) => chan.sender().unregister(oper),
1376            SenderFlavor::List(chan) => chan.sender().unregister(oper),
1377            SenderFlavor::Zero(chan) => chan.sender().unregister(oper),
1378        }
1379    }
1380
1381    fn accept(&self, token: &mut Token, cx: &Context) -> bool {
1382        match &self.flavor {
1383            SenderFlavor::Array(chan) => chan.sender().accept(token, cx),
1384            SenderFlavor::List(chan) => chan.sender().accept(token, cx),
1385            SenderFlavor::Zero(chan) => chan.sender().accept(token, cx),
1386        }
1387    }
1388
1389    fn is_ready(&self) -> bool {
1390        match &self.flavor {
1391            SenderFlavor::Array(chan) => chan.sender().is_ready(),
1392            SenderFlavor::List(chan) => chan.sender().is_ready(),
1393            SenderFlavor::Zero(chan) => chan.sender().is_ready(),
1394        }
1395    }
1396
1397    fn watch(&self, oper: Operation, cx: &Context) -> bool {
1398        match &self.flavor {
1399            SenderFlavor::Array(chan) => chan.sender().watch(oper, cx),
1400            SenderFlavor::List(chan) => chan.sender().watch(oper, cx),
1401            SenderFlavor::Zero(chan) => chan.sender().watch(oper, cx),
1402        }
1403    }
1404
1405    fn unwatch(&self, oper: Operation) {
1406        match &self.flavor {
1407            SenderFlavor::Array(chan) => chan.sender().unwatch(oper),
1408            SenderFlavor::List(chan) => chan.sender().unwatch(oper),
1409            SenderFlavor::Zero(chan) => chan.sender().unwatch(oper),
1410        }
1411    }
1412}
1413
1414impl<T> SelectHandle for Receiver<T> {
1415    fn try_select(&self, token: &mut Token) -> bool {
1416        match &self.flavor {
1417            ReceiverFlavor::Array(chan) => chan.receiver().try_select(token),
1418            ReceiverFlavor::List(chan) => chan.receiver().try_select(token),
1419            ReceiverFlavor::Zero(chan) => chan.receiver().try_select(token),
1420            ReceiverFlavor::At(chan) => chan.try_select(token),
1421            ReceiverFlavor::Tick(chan) => chan.try_select(token),
1422            ReceiverFlavor::Never(chan) => chan.try_select(token),
1423        }
1424    }
1425
1426    fn deadline(&self) -> Option<Instant> {
1427        match &self.flavor {
1428            ReceiverFlavor::Array(_) => None,
1429            ReceiverFlavor::List(_) => None,
1430            ReceiverFlavor::Zero(_) => None,
1431            ReceiverFlavor::At(chan) => chan.deadline(),
1432            ReceiverFlavor::Tick(chan) => chan.deadline(),
1433            ReceiverFlavor::Never(chan) => chan.deadline(),
1434        }
1435    }
1436
1437    fn register(&self, oper: Operation, cx: &Context) -> bool {
1438        match &self.flavor {
1439            ReceiverFlavor::Array(chan) => chan.receiver().register(oper, cx),
1440            ReceiverFlavor::List(chan) => chan.receiver().register(oper, cx),
1441            ReceiverFlavor::Zero(chan) => chan.receiver().register(oper, cx),
1442            ReceiverFlavor::At(chan) => chan.register(oper, cx),
1443            ReceiverFlavor::Tick(chan) => chan.register(oper, cx),
1444            ReceiverFlavor::Never(chan) => chan.register(oper, cx),
1445        }
1446    }
1447
1448    fn unregister(&self, oper: Operation) {
1449        match &self.flavor {
1450            ReceiverFlavor::Array(chan) => chan.receiver().unregister(oper),
1451            ReceiverFlavor::List(chan) => chan.receiver().unregister(oper),
1452            ReceiverFlavor::Zero(chan) => chan.receiver().unregister(oper),
1453            ReceiverFlavor::At(chan) => chan.unregister(oper),
1454            ReceiverFlavor::Tick(chan) => chan.unregister(oper),
1455            ReceiverFlavor::Never(chan) => chan.unregister(oper),
1456        }
1457    }
1458
1459    fn accept(&self, token: &mut Token, cx: &Context) -> bool {
1460        match &self.flavor {
1461            ReceiverFlavor::Array(chan) => chan.receiver().accept(token, cx),
1462            ReceiverFlavor::List(chan) => chan.receiver().accept(token, cx),
1463            ReceiverFlavor::Zero(chan) => chan.receiver().accept(token, cx),
1464            ReceiverFlavor::At(chan) => chan.accept(token, cx),
1465            ReceiverFlavor::Tick(chan) => chan.accept(token, cx),
1466            ReceiverFlavor::Never(chan) => chan.accept(token, cx),
1467        }
1468    }
1469
1470    fn is_ready(&self) -> bool {
1471        match &self.flavor {
1472            ReceiverFlavor::Array(chan) => chan.receiver().is_ready(),
1473            ReceiverFlavor::List(chan) => chan.receiver().is_ready(),
1474            ReceiverFlavor::Zero(chan) => chan.receiver().is_ready(),
1475            ReceiverFlavor::At(chan) => chan.is_ready(),
1476            ReceiverFlavor::Tick(chan) => chan.is_ready(),
1477            ReceiverFlavor::Never(chan) => chan.is_ready(),
1478        }
1479    }
1480
1481    fn watch(&self, oper: Operation, cx: &Context) -> bool {
1482        match &self.flavor {
1483            ReceiverFlavor::Array(chan) => chan.receiver().watch(oper, cx),
1484            ReceiverFlavor::List(chan) => chan.receiver().watch(oper, cx),
1485            ReceiverFlavor::Zero(chan) => chan.receiver().watch(oper, cx),
1486            ReceiverFlavor::At(chan) => chan.watch(oper, cx),
1487            ReceiverFlavor::Tick(chan) => chan.watch(oper, cx),
1488            ReceiverFlavor::Never(chan) => chan.watch(oper, cx),
1489        }
1490    }
1491
1492    fn unwatch(&self, oper: Operation) {
1493        match &self.flavor {
1494            ReceiverFlavor::Array(chan) => chan.receiver().unwatch(oper),
1495            ReceiverFlavor::List(chan) => chan.receiver().unwatch(oper),
1496            ReceiverFlavor::Zero(chan) => chan.receiver().unwatch(oper),
1497            ReceiverFlavor::At(chan) => chan.unwatch(oper),
1498            ReceiverFlavor::Tick(chan) => chan.unwatch(oper),
1499            ReceiverFlavor::Never(chan) => chan.unwatch(oper),
1500        }
1501    }
1502}
1503
1504/// Writes a message into the channel.
1505pub(crate) unsafe fn write<T>(s: &Sender<T>, token: &mut Token, msg: T) -> Result<(), T> {
1506    match &s.flavor {
1507        SenderFlavor::Array(chan) => chan.write(token, msg),
1508        SenderFlavor::List(chan) => chan.write(token, msg),
1509        SenderFlavor::Zero(chan) => chan.write(token, msg),
1510    }
1511}
1512
1513/// Reads a message from the channel.
1514pub(crate) unsafe fn read<T>(r: &Receiver<T>, token: &mut Token) -> Result<T, ()> {
1515    match &r.flavor {
1516        ReceiverFlavor::Array(chan) => chan.read(token),
1517        ReceiverFlavor::List(chan) => chan.read(token),
1518        ReceiverFlavor::Zero(chan) => chan.read(token),
1519        ReceiverFlavor::At(chan) => {
1520            mem::transmute_copy::<Result<Instant, ()>, Result<T, ()>>(&chan.read(token))
1521        }
1522        ReceiverFlavor::Tick(chan) => {
1523            mem::transmute_copy::<Result<Instant, ()>, Result<T, ()>>(&chan.read(token))
1524        }
1525        ReceiverFlavor::Never(chan) => chan.read(token),
1526    }
1527}