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