Skip to main content

std/sync/mpmc/
mod.rs

1//! Multi-producer, multi-consumer FIFO queue communication primitives.
2//!
3//! This module provides message-based communication over channels, concretely
4//! defined by two types:
5//!
6//! * [`Sender`]
7//! * [`Receiver`]
8//!
9//! [`Sender`]s are used to send data to a set of [`Receiver`]s where each item
10//! sent is delivered to (at most) one receiver. Both sender and receiver are
11//! cloneable (multi-producer) such that many threads can send simultaneously
12//! to receivers (multi-consumer).
13//!
14//! These channels come in two flavors:
15//!
16//! 1. An asynchronous, infinitely buffered channel. The [`channel`] function
17//!    will return a `(Sender, Receiver)` tuple where all sends will be
18//!    **asynchronous** (they never block for space to become available; see
19//!    [`std::sync`] for precise guarantees on blocking.) The channel
20//!    conceptually has an infinite buffer.
21//!
22//! 2. A synchronous, bounded channel. The [`sync_channel`] function will
23//!    return a `(Sender, Receiver)` tuple where the storage for pending
24//!    messages is a pre-allocated buffer of a fixed size. All sends will be
25//!    **synchronous** by blocking until there is buffer space available. Note
26//!    that a bound of 0 is allowed, causing the channel to become a "rendezvous"
27//!    channel where each sender atomically hands off a message to a receiver.
28//!
29//! [`send`]: Sender::send
30//! [`std::sync`]: ../index.html#blocking-guarantees
31//!
32//! ## Disconnection
33//!
34//! The send and receive operations on channels will all return a [`Result`]
35//! indicating whether the operation succeeded or not. An unsuccessful operation
36//! is normally indicative of the other half of a channel having "hung up" by
37//! being dropped in its corresponding thread.
38//!
39//! Once half of a channel has been deallocated, most operations can no longer
40//! continue to make progress, so [`Err`] will be returned. Many applications
41//! will continue to [`unwrap`] the results returned from this module,
42//! instigating a propagation of failure among threads if one unexpectedly dies.
43//!
44//! [`unwrap`]: Result::unwrap
45//!
46//! # Examples
47//!
48//! Simple usage:
49//!
50//! ```
51//! #![feature(mpmc_channel)]
52//!
53//! use std::thread;
54//! use std::sync::mpmc::channel;
55//!
56//! // Create a simple streaming channel
57//! let (tx, rx) = channel();
58//! thread::spawn(move || {
59//!     tx.send(10).unwrap();
60//! });
61//! assert_eq!(rx.recv().unwrap(), 10);
62//! ```
63//!
64//! Shared usage:
65//!
66//! ```
67//! #![feature(mpmc_channel)]
68//!
69//! use std::thread;
70//! use std::sync::mpmc::channel;
71//!
72//! thread::scope(|s| {
73//!     // Create a shared channel that can be sent along from many threads
74//!     // where tx is the sending half (tx for transmission), and rx is the receiving
75//!     // half (rx for receiving).
76//!     let (tx, rx) = channel();
77//!     for i in 0..10 {
78//!         let tx = tx.clone();
79//!         s.spawn(move || {
80//!             tx.send(i).unwrap();
81//!         });
82//!     }
83//!
84//!     for _ in 0..5 {
85//!         let rx1 = rx.clone();
86//!         let rx2 = rx.clone();
87//!         s.spawn(move || {
88//!             let j = rx1.recv().unwrap();
89//!             assert!(0 <= j && j < 10);
90//!         });
91//!         s.spawn(move || {
92//!             let j = rx2.recv().unwrap();
93//!             assert!(0 <= j && j < 10);
94//!         });
95//!     }
96//! })
97//! ```
98//!
99//! Propagating panics:
100//!
101//! ```
102//! #![feature(mpmc_channel)]
103//!
104//! use std::sync::mpmc::channel;
105//!
106//! // The call to recv() will return an error because the channel has already
107//! // hung up (or been deallocated)
108//! let (tx, rx) = channel::<i32>();
109//! drop(tx);
110//! assert!(rx.recv().is_err());
111//! ```
112
113// This module is used as the implementation for the channels in `sync::mpsc`.
114// The implementation comes from the crossbeam-channel crate:
115//
116// Copyright (c) 2019 The Crossbeam Project Developers
117//
118// Permission is hereby granted, free of charge, to any
119// person obtaining a copy of this software and associated
120// documentation files (the "Software"), to deal in the
121// Software without restriction, including without
122// limitation the rights to use, copy, modify, merge,
123// publish, distribute, sublicense, and/or sell copies of
124// the Software, and to permit persons to whom the Software
125// is furnished to do so, subject to the following
126// conditions:
127//
128// The above copyright notice and this permission notice
129// shall be included in all copies or substantial portions
130// of the Software.
131//
132// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
133// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
134// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
135// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
136// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
137// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
138// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
139// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
140// DEALINGS IN THE SOFTWARE.
141
142mod array;
143mod context;
144mod counter;
145mod error;
146mod list;
147mod select;
148mod utils;
149mod waker;
150mod zero;
151
152pub use error::*;
153
154use crate::fmt;
155use crate::panic::{RefUnwindSafe, UnwindSafe};
156use crate::time::{Duration, Instant};
157
158/// Creates a new asynchronous channel, returning the sender/receiver halves.
159///
160/// All data sent on the [`Sender`] will become available on the [`Receiver`] in
161/// the same order as it was sent, and no [`send`] will block the calling thread
162/// (this channel has an "infinite buffer", unlike [`sync_channel`], which will
163/// block after its buffer limit is reached). [`recv`] will block until a message
164/// is available while there is at least one [`Sender`] alive (including clones).
165///
166/// The [`Sender`] can be cloned to [`send`] to the same channel multiple times.
167/// The [`Receiver`] also can be cloned to have multi receivers.
168///
169/// If the [`Receiver`] is disconnected while trying to [`send`] with the
170/// [`Sender`], the [`send`] method will return a [`SendError`]. Similarly, if the
171/// [`Sender`] is disconnected while trying to [`recv`], the [`recv`] method will
172/// return a [`RecvError`].
173///
174/// [`send`]: Sender::send
175/// [`recv`]: Receiver::recv
176///
177/// # Examples
178///
179/// ```
180/// #![feature(mpmc_channel)]
181///
182/// use std::sync::mpmc::channel;
183/// use std::thread;
184///
185/// let (sender, receiver) = channel();
186///
187/// // Spawn off an expensive computation
188/// thread::spawn(move || {
189/// #   fn expensive_computation() {}
190///     sender.send(expensive_computation()).unwrap();
191/// });
192///
193/// // Do some useful work for a while
194///
195/// // Let's see what that answer was
196/// println!("{:?}", receiver.recv().unwrap());
197/// ```
198#[must_use]
199#[unstable(feature = "mpmc_channel", issue = "126840")]
200pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
201    let (s, r) = counter::new(list::Channel::new());
202    let s = Sender { flavor: SenderFlavor::List(s) };
203    let r = Receiver { flavor: ReceiverFlavor::List(r) };
204    (s, r)
205}
206
207/// Creates a new synchronous, bounded channel.
208///
209/// All data sent on the [`Sender`] will become available on the [`Receiver`]
210/// in the same order as it was sent. Like asynchronous [`channel`]s, the
211/// [`Receiver`] will block until a message becomes available. `sync_channel`
212/// differs greatly in the semantics of the sender, however.
213///
214/// This channel has an internal buffer on which messages will be queued.
215/// `bound` specifies the buffer size. When the internal buffer becomes full,
216/// future sends will *block* waiting for the buffer to open up. Note that a
217/// buffer size of 0 is valid, in which case this becomes "rendezvous channel"
218/// where each [`send`] will not return until a [`recv`] is paired with it.
219///
220/// The [`Sender`] can be cloned to [`send`] to the same channel multiple
221/// times. The [`Receiver`] also can be cloned to have multi receivers.
222///
223/// Like asynchronous channels, if the [`Receiver`] is disconnected while trying
224/// to [`send`] with the [`Sender`], the [`send`] method will return a
225/// [`SendError`]. Similarly, If the [`Sender`] is disconnected while trying
226/// to [`recv`], the [`recv`] method will return a [`RecvError`].
227///
228/// [`send`]: Sender::send
229/// [`recv`]: Receiver::recv
230///
231/// # Examples
232///
233/// ```
234/// use std::sync::mpsc::sync_channel;
235/// use std::thread;
236///
237/// let (sender, receiver) = sync_channel(1);
238///
239/// // this returns immediately
240/// sender.send(1).unwrap();
241///
242/// thread::spawn(move || {
243///     // this will block until the previous message has been received
244///     sender.send(2).unwrap();
245/// });
246///
247/// assert_eq!(receiver.recv().unwrap(), 1);
248/// assert_eq!(receiver.recv().unwrap(), 2);
249/// ```
250#[must_use]
251#[unstable(feature = "mpmc_channel", issue = "126840")]
252pub fn sync_channel<T>(cap: usize) -> (Sender<T>, Receiver<T>) {
253    if cap == 0 {
254        let (s, r) = counter::new(zero::Channel::new());
255        let s = Sender { flavor: SenderFlavor::Zero(s) };
256        let r = Receiver { flavor: ReceiverFlavor::Zero(r) };
257        (s, r)
258    } else {
259        let (s, r) = counter::new(array::Channel::with_capacity(cap));
260        let s = Sender { flavor: SenderFlavor::Array(s) };
261        let r = Receiver { flavor: ReceiverFlavor::Array(r) };
262        (s, r)
263    }
264}
265
266/// The sending-half of Rust's synchronous [`channel`] type.
267///
268/// Messages can be sent through this channel with [`send`].
269///
270/// Note: all senders (the original and its clones) need to be dropped for the receiver
271/// to stop blocking to receive messages with [`Receiver::recv`].
272///
273/// [`send`]: Sender::send
274///
275/// # Examples
276///
277/// ```rust
278/// #![feature(mpmc_channel)]
279///
280/// use std::sync::mpmc::channel;
281/// use std::thread;
282///
283/// let (sender, receiver) = channel();
284/// let sender2 = sender.clone();
285///
286/// // First thread owns sender
287/// thread::spawn(move || {
288///     sender.send(1).unwrap();
289/// });
290///
291/// // Second thread owns sender2
292/// thread::spawn(move || {
293///     sender2.send(2).unwrap();
294/// });
295///
296/// let msg = receiver.recv().unwrap();
297/// let msg2 = receiver.recv().unwrap();
298///
299/// assert_eq!(3, msg + msg2);
300/// ```
301#[unstable(feature = "mpmc_channel", issue = "126840")]
302#[cfg_attr(not(test), rustc_diagnostic_item = "MpmcSender")]
303pub struct Sender<T> {
304    flavor: SenderFlavor<T>,
305}
306
307/// Sender flavors.
308enum SenderFlavor<T> {
309    /// Bounded channel based on a preallocated array.
310    Array(counter::Sender<array::Channel<T>>),
311
312    /// Unbounded channel implemented as a linked list.
313    List(counter::Sender<list::Channel<T>>),
314
315    /// Zero-capacity channel.
316    Zero(counter::Sender<zero::Channel<T>>),
317}
318
319#[unstable(feature = "mpmc_channel", issue = "126840")]
320unsafe impl<T: Send> Send for Sender<T> {}
321#[unstable(feature = "mpmc_channel", issue = "126840")]
322unsafe impl<T: Send> Sync for Sender<T> {}
323
324#[unstable(feature = "mpmc_channel", issue = "126840")]
325impl<T> UnwindSafe for Sender<T> {}
326#[unstable(feature = "mpmc_channel", issue = "126840")]
327impl<T> RefUnwindSafe for Sender<T> {}
328
329impl<T> Sender<T> {
330    /// Attempts to send a message into the channel without blocking.
331    ///
332    /// This method will either send a message into the channel immediately or return an error if
333    /// the channel is full or disconnected. The returned error contains the original message.
334    ///
335    /// If called on a zero-capacity channel, this method will send the message only if there
336    /// happens to be a receive operation on the other side of the channel at the same time.
337    ///
338    /// # Examples
339    ///
340    /// ```rust
341    /// #![feature(mpmc_channel)]
342    ///
343    /// use std::sync::mpmc::{channel, Receiver, Sender};
344    ///
345    /// let (sender, _receiver): (Sender<i32>, Receiver<i32>) = channel();
346    ///
347    /// assert!(sender.try_send(1).is_ok());
348    /// ```
349    #[unstable(feature = "mpmc_channel", issue = "126840")]
350    pub fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> {
351        match &self.flavor {
352            SenderFlavor::Array(chan) => chan.try_send(msg),
353            SenderFlavor::List(chan) => chan.try_send(msg),
354            SenderFlavor::Zero(chan) => chan.try_send(msg),
355        }
356    }
357
358    /// Attempts to send a value on this channel, returning it back if it could
359    /// not be sent.
360    ///
361    /// A successful send occurs when it is determined that the other end of
362    /// the channel has not hung up already. An unsuccessful send would be one
363    /// where the corresponding receiver has already been deallocated. Note
364    /// that a return value of [`Err`] means that the data will never be
365    /// received, but a return value of [`Ok`] does *not* mean that the data
366    /// will be received. It is possible for the corresponding receiver to
367    /// hang up immediately after this function returns [`Ok`]. However, if
368    /// the channel is zero-capacity, it acts as a rendezvous channel and a
369    /// return value of [`Ok`] means that the data has been received.
370    ///
371    /// If the channel is full and not disconnected, this call will block until
372    /// the send operation can proceed. If the channel becomes disconnected,
373    /// this call will wake up and return an error. The returned error contains
374    /// the original message.
375    ///
376    /// If called on a zero-capacity channel, this method will wait for a receive
377    /// operation to appear on the other side of the channel.
378    ///
379    /// If called on an unbounded channel, this method will never block in order to wait for space to
380    /// become available. (See [`std::sync`] for precise guarantees on blocking.)
381    ///
382    /// [`std::sync`]: ../index.html#blocking-guarantees
383    ///
384    /// # Examples
385    ///
386    /// ```
387    /// #![feature(mpmc_channel)]
388    ///
389    /// use std::sync::mpmc::channel;
390    ///
391    /// let (tx, rx) = channel();
392    ///
393    /// // This send is always successful
394    /// tx.send(1).unwrap();
395    ///
396    /// // This send will fail because the receiver is gone
397    /// drop(rx);
398    /// assert!(tx.send(1).is_err());
399    /// ```
400    #[unstable(feature = "mpmc_channel", issue = "126840")]
401    pub fn send(&self, msg: T) -> Result<(), SendError<T>> {
402        match &self.flavor {
403            SenderFlavor::Array(chan) => chan.send(msg, None),
404            SenderFlavor::List(chan) => chan.send(msg, None),
405            SenderFlavor::Zero(chan) => chan.send(msg, None),
406        }
407        .map_err(|err| match err {
408            SendTimeoutError::Disconnected(msg) => SendError(msg),
409            SendTimeoutError::Timeout(_) => unreachable!(),
410        })
411    }
412}
413
414impl<T> Sender<T> {
415    /// Waits for a message to be sent into the channel, but only for a limited time.
416    ///
417    /// If the channel is full and not disconnected, this call will block until the send operation
418    /// can proceed or the operation times out. If the channel becomes disconnected, this call will
419    /// wake up and return an error. The returned error contains the original message.
420    ///
421    /// If called on a zero-capacity channel, this method will wait for a receive operation to
422    /// appear on the other side of the channel.
423    ///
424    /// # Examples
425    ///
426    /// ```
427    /// #![feature(mpmc_channel)]
428    ///
429    /// use std::sync::mpmc::channel;
430    /// use std::time::Duration;
431    ///
432    /// let (tx, rx) = channel();
433    ///
434    /// tx.send_timeout(1, Duration::from_millis(400)).unwrap();
435    /// ```
436    #[unstable(feature = "mpmc_channel", issue = "126840")]
437    pub fn send_timeout(&self, msg: T, timeout: Duration) -> Result<(), SendTimeoutError<T>> {
438        match Instant::now().checked_add(timeout) {
439            Some(deadline) => self.send_deadline(msg, deadline),
440            // So far in the future that it's practically the same as waiting indefinitely.
441            None => self.send(msg).map_err(SendTimeoutError::from),
442        }
443    }
444
445    /// Waits for a message to be sent into the channel, but only until a given deadline.
446    ///
447    /// If the channel is full and not disconnected, this call will block until the send operation
448    /// can proceed or the operation times out. If the channel becomes disconnected, this call will
449    /// wake up and return an error. The returned error contains the original message.
450    ///
451    /// If called on a zero-capacity channel, this method will wait for a receive operation to
452    /// appear on the other side of the channel.
453    ///
454    /// # Examples
455    ///
456    /// ```
457    /// #![feature(mpmc_channel)]
458    ///
459    /// use std::sync::mpmc::channel;
460    /// use std::time::{Duration, Instant};
461    ///
462    /// let (tx, rx) = channel();
463    ///
464    /// let t = Instant::now() + Duration::from_millis(400);
465    /// tx.send_deadline(1, t).unwrap();
466    /// ```
467    #[unstable(feature = "mpmc_channel", issue = "126840")]
468    pub fn send_deadline(&self, msg: T, deadline: Instant) -> Result<(), SendTimeoutError<T>> {
469        match &self.flavor {
470            SenderFlavor::Array(chan) => chan.send(msg, Some(deadline)),
471            SenderFlavor::List(chan) => chan.send(msg, Some(deadline)),
472            SenderFlavor::Zero(chan) => chan.send(msg, Some(deadline)),
473        }
474    }
475
476    /// Returns `true` if the channel is empty.
477    ///
478    /// Note: Zero-capacity channels are always empty.
479    ///
480    /// # Examples
481    ///
482    /// ```
483    /// #![feature(mpmc_channel)]
484    ///
485    /// use std::sync::mpmc;
486    /// use std::thread;
487    ///
488    /// let (send, _recv) = mpmc::channel();
489    ///
490    /// let tx1 = send.clone();
491    /// let tx2 = send.clone();
492    ///
493    /// assert!(tx1.is_empty());
494    ///
495    /// let handle = thread::spawn(move || {
496    ///     tx2.send(1u8).unwrap();
497    /// });
498    ///
499    /// handle.join().unwrap();
500    ///
501    /// assert!(!tx1.is_empty());
502    /// ```
503    #[unstable(feature = "mpmc_channel", issue = "126840")]
504    pub fn is_empty(&self) -> bool {
505        match &self.flavor {
506            SenderFlavor::Array(chan) => chan.is_empty(),
507            SenderFlavor::List(chan) => chan.is_empty(),
508            SenderFlavor::Zero(chan) => chan.is_empty(),
509        }
510    }
511
512    /// Returns `true` if the channel is full.
513    ///
514    /// Note: Zero-capacity channels are always full.
515    ///
516    /// # Examples
517    ///
518    /// ```
519    /// #![feature(mpmc_channel)]
520    ///
521    /// use std::sync::mpmc;
522    /// use std::thread;
523    ///
524    /// let (send, _recv) = mpmc::sync_channel(1);
525    ///
526    /// let (tx1, tx2) = (send.clone(), send.clone());
527    /// assert!(!tx1.is_full());
528    ///
529    /// let handle = thread::spawn(move || {
530    ///     tx2.send(1u8).unwrap();
531    /// });
532    ///
533    /// handle.join().unwrap();
534    ///
535    /// assert!(tx1.is_full());
536    /// ```
537    #[unstable(feature = "mpmc_channel", issue = "126840")]
538    pub fn is_full(&self) -> bool {
539        match &self.flavor {
540            SenderFlavor::Array(chan) => chan.is_full(),
541            SenderFlavor::List(chan) => chan.is_full(),
542            SenderFlavor::Zero(chan) => chan.is_full(),
543        }
544    }
545
546    /// Returns the number of messages in the channel.
547    ///
548    /// # Examples
549    ///
550    /// ```
551    /// #![feature(mpmc_channel)]
552    ///
553    /// use std::sync::mpmc;
554    /// use std::thread;
555    ///
556    /// let (send, _recv) = mpmc::channel();
557    /// let (tx1, tx2) = (send.clone(), send.clone());
558    ///
559    /// assert_eq!(tx1.len(), 0);
560    ///
561    /// let handle = thread::spawn(move || {
562    ///     tx2.send(1u8).unwrap();
563    /// });
564    ///
565    /// handle.join().unwrap();
566    ///
567    /// assert_eq!(tx1.len(), 1);
568    /// ```
569    #[unstable(feature = "mpmc_channel", issue = "126840")]
570    pub fn len(&self) -> usize {
571        match &self.flavor {
572            SenderFlavor::Array(chan) => chan.len(),
573            SenderFlavor::List(chan) => chan.len(),
574            SenderFlavor::Zero(chan) => chan.len(),
575        }
576    }
577
578    /// If the channel is bounded, returns its capacity.
579    ///
580    /// # Examples
581    ///
582    /// ```
583    /// #![feature(mpmc_channel)]
584    ///
585    /// use std::sync::mpmc;
586    /// use std::thread;
587    ///
588    /// let (send, _recv) = mpmc::sync_channel(3);
589    /// let (tx1, tx2) = (send.clone(), send.clone());
590    ///
591    /// assert_eq!(tx1.capacity(), Some(3));
592    ///
593    /// let handle = thread::spawn(move || {
594    ///     tx2.send(1u8).unwrap();
595    /// });
596    ///
597    /// handle.join().unwrap();
598    ///
599    /// assert_eq!(tx1.capacity(), Some(3));
600    /// ```
601    #[unstable(feature = "mpmc_channel", issue = "126840")]
602    pub fn capacity(&self) -> Option<usize> {
603        match &self.flavor {
604            SenderFlavor::Array(chan) => chan.capacity(),
605            SenderFlavor::List(chan) => chan.capacity(),
606            SenderFlavor::Zero(chan) => chan.capacity(),
607        }
608    }
609
610    /// Returns `true` if senders belong to the same channel.
611    ///
612    /// # Examples
613    ///
614    /// ```
615    /// #![feature(mpmc_channel)]
616    ///
617    /// use std::sync::mpmc;
618    ///
619    /// let (tx1, _) = mpmc::channel::<i32>();
620    /// let (tx2, _) = mpmc::channel::<i32>();
621    ///
622    /// assert!(tx1.same_channel(&tx1));
623    /// assert!(!tx1.same_channel(&tx2));
624    /// ```
625    #[unstable(feature = "mpmc_channel", issue = "126840")]
626    pub fn same_channel(&self, other: &Sender<T>) -> bool {
627        match (&self.flavor, &other.flavor) {
628            (SenderFlavor::Array(a), SenderFlavor::Array(b)) => a == b,
629            (SenderFlavor::List(a), SenderFlavor::List(b)) => a == b,
630            (SenderFlavor::Zero(a), SenderFlavor::Zero(b)) => a == b,
631            _ => false,
632        }
633    }
634
635    /// Returns `true` if the channel is disconnected.
636    ///
637    /// Note that a return value of `false` does not guarantee the channel will
638    /// remain connected. The channel may be disconnected immediately after this method
639    /// returns, so a subsequent [`Sender::send`] may still fail with [`SendError`].
640    ///
641    /// # Examples
642    ///
643    /// ```
644    /// #![feature(mpmc_channel)]
645    ///
646    /// use std::sync::mpmc::channel;
647    ///
648    /// let (tx, rx) = channel::<i32>();
649    /// assert!(!tx.is_disconnected());
650    /// drop(rx);
651    /// assert!(tx.is_disconnected());
652    /// ```
653    #[unstable(feature = "mpmc_channel", issue = "126840")]
654    pub fn is_disconnected(&self) -> bool {
655        match &self.flavor {
656            SenderFlavor::Array(chan) => chan.is_disconnected(),
657            SenderFlavor::List(chan) => chan.is_disconnected(),
658            SenderFlavor::Zero(chan) => chan.is_disconnected(),
659        }
660    }
661}
662
663#[unstable(feature = "mpmc_channel", issue = "126840")]
664impl<T> Drop for Sender<T> {
665    fn drop(&mut self) {
666        unsafe {
667            match &self.flavor {
668                SenderFlavor::Array(chan) => chan.release(|c| c.disconnect_senders()),
669                SenderFlavor::List(chan) => chan.release(|c| c.disconnect_senders()),
670                SenderFlavor::Zero(chan) => chan.release(|c| c.disconnect()),
671            }
672        }
673    }
674}
675
676#[unstable(feature = "mpmc_channel", issue = "126840")]
677impl<T> Clone for Sender<T> {
678    fn clone(&self) -> Self {
679        let flavor = match &self.flavor {
680            SenderFlavor::Array(chan) => SenderFlavor::Array(chan.acquire()),
681            SenderFlavor::List(chan) => SenderFlavor::List(chan.acquire()),
682            SenderFlavor::Zero(chan) => SenderFlavor::Zero(chan.acquire()),
683        };
684
685        Sender { flavor }
686    }
687}
688
689#[unstable(feature = "mpmc_channel", issue = "126840")]
690impl<T> fmt::Debug for Sender<T> {
691    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
692        f.debug_struct("Sender").finish_non_exhaustive()
693    }
694}
695
696/// The receiving half of Rust's [`channel`] (or [`sync_channel`]) type.
697/// Different threads can share this [`Receiver`] by cloning it.
698///
699/// Messages sent to the channel can be retrieved using [`recv`].
700///
701/// [`recv`]: Receiver::recv
702///
703/// # Examples
704///
705/// ```rust
706/// #![feature(mpmc_channel)]
707///
708/// use std::sync::mpmc::channel;
709/// use std::thread;
710/// use std::time::Duration;
711///
712/// let (send, recv) = channel();
713///
714/// let tx_thread = thread::spawn(move || {
715///     send.send("Hello world!").unwrap();
716///     thread::sleep(Duration::from_secs(2)); // block for two seconds
717///     send.send("Delayed for 2 seconds").unwrap();
718/// });
719///
720/// let (rx1, rx2) = (recv.clone(), recv.clone());
721/// let rx_thread_1 = thread::spawn(move || {
722///     println!("{}", rx1.recv().unwrap()); // Received immediately
723/// });
724/// let rx_thread_2 = thread::spawn(move || {
725///     println!("{}", rx2.recv().unwrap()); // Received after 2 seconds
726/// });
727///
728/// tx_thread.join().unwrap();
729/// rx_thread_1.join().unwrap();
730/// rx_thread_2.join().unwrap();
731/// ```
732#[unstable(feature = "mpmc_channel", issue = "126840")]
733#[cfg_attr(not(test), rustc_diagnostic_item = "MpmcReceiver")]
734pub struct Receiver<T> {
735    flavor: ReceiverFlavor<T>,
736}
737
738/// An iterator over messages on a [`Receiver`], created by [`iter`].
739///
740/// This iterator will block whenever [`next`] is called,
741/// waiting for a new message, and [`None`] will be returned
742/// when the corresponding channel has hung up.
743///
744/// [`iter`]: Receiver::iter
745/// [`next`]: Iterator::next
746///
747/// # Examples
748///
749/// ```rust
750/// #![feature(mpmc_channel)]
751///
752/// use std::sync::mpmc::channel;
753/// use std::thread;
754///
755/// let (send, recv) = channel();
756///
757/// thread::spawn(move || {
758///     send.send(1u8).unwrap();
759///     send.send(2u8).unwrap();
760///     send.send(3u8).unwrap();
761/// });
762///
763/// for x in recv.iter() {
764///     println!("Got: {x}");
765/// }
766/// ```
767#[unstable(feature = "mpmc_channel", issue = "126840")]
768#[derive(Debug)]
769pub struct Iter<'a, T: 'a> {
770    rx: &'a Receiver<T>,
771}
772
773/// An iterator that attempts to yield all pending values for a [`Receiver`],
774/// created by [`try_iter`].
775///
776/// [`None`] will be returned when there are no pending values remaining or
777/// if the corresponding channel has hung up.
778///
779/// This iterator will never block the caller in order to wait for data to
780/// become available. Instead, it will return [`None`]. (See [`std::sync`] for
781/// precise guarantees on blocking.)
782///
783/// [`try_iter`]: Receiver::try_iter
784/// [`std::sync`]: ../index.html#blocking-guarantees
785///
786/// # Examples
787///
788/// ```rust
789/// #![feature(mpmc_channel)]
790///
791/// use std::sync::mpmc::channel;
792/// use std::thread;
793/// use std::time::Duration;
794///
795/// let (sender, receiver) = channel();
796///
797/// // Nothing is in the buffer yet
798/// assert!(receiver.try_iter().next().is_none());
799/// println!("Nothing in the buffer...");
800///
801/// thread::spawn(move || {
802///     sender.send(1).unwrap();
803///     sender.send(2).unwrap();
804///     sender.send(3).unwrap();
805/// });
806///
807/// println!("Going to sleep...");
808/// thread::sleep(Duration::from_secs(2)); // block for two seconds
809///
810/// for x in receiver.try_iter() {
811///     println!("Got: {x}");
812/// }
813/// ```
814#[unstable(feature = "mpmc_channel", issue = "126840")]
815#[derive(Debug)]
816pub struct TryIter<'a, T: 'a> {
817    rx: &'a Receiver<T>,
818}
819
820/// An owning iterator over messages on a [`Receiver`],
821/// created by [`into_iter`].
822///
823/// This iterator will block whenever [`next`]
824/// is called, waiting for a new message, and [`None`] will be
825/// returned if the corresponding channel has hung up.
826///
827/// [`into_iter`]: Receiver::into_iter
828/// [`next`]: Iterator::next
829///
830/// # Examples
831///
832/// ```rust
833/// #![feature(mpmc_channel)]
834///
835/// use std::sync::mpmc::channel;
836/// use std::thread;
837///
838/// let (send, recv) = channel();
839///
840/// thread::spawn(move || {
841///     send.send(1u8).unwrap();
842///     send.send(2u8).unwrap();
843///     send.send(3u8).unwrap();
844/// });
845///
846/// for x in recv.into_iter() {
847///     println!("Got: {x}");
848/// }
849/// ```
850#[unstable(feature = "mpmc_channel", issue = "126840")]
851#[derive(Debug)]
852pub struct IntoIter<T> {
853    rx: Receiver<T>,
854}
855
856#[unstable(feature = "mpmc_channel", issue = "126840")]
857impl<'a, T> Iterator for Iter<'a, T> {
858    type Item = T;
859
860    fn next(&mut self) -> Option<T> {
861        self.rx.recv().ok()
862    }
863}
864
865#[unstable(feature = "mpmc_channel", issue = "126840")]
866impl<'a, T> Iterator for TryIter<'a, T> {
867    type Item = T;
868
869    fn next(&mut self) -> Option<T> {
870        self.rx.try_recv().ok()
871    }
872}
873
874#[unstable(feature = "mpmc_channel", issue = "126840")]
875impl<'a, T> IntoIterator for &'a Receiver<T> {
876    type Item = T;
877    type IntoIter = Iter<'a, T>;
878
879    fn into_iter(self) -> Iter<'a, T> {
880        self.iter()
881    }
882}
883
884#[unstable(feature = "mpmc_channel", issue = "126840")]
885impl<T> Iterator for IntoIter<T> {
886    type Item = T;
887    fn next(&mut self) -> Option<T> {
888        self.rx.recv().ok()
889    }
890}
891
892#[unstable(feature = "mpmc_channel", issue = "126840")]
893impl<T> IntoIterator for Receiver<T> {
894    type Item = T;
895    type IntoIter = IntoIter<T>;
896
897    fn into_iter(self) -> IntoIter<T> {
898        IntoIter { rx: self }
899    }
900}
901
902/// Receiver flavors.
903enum ReceiverFlavor<T> {
904    /// Bounded channel based on a preallocated array.
905    Array(counter::Receiver<array::Channel<T>>),
906
907    /// Unbounded channel implemented as a linked list.
908    List(counter::Receiver<list::Channel<T>>),
909
910    /// Zero-capacity channel.
911    Zero(counter::Receiver<zero::Channel<T>>),
912}
913
914#[unstable(feature = "mpmc_channel", issue = "126840")]
915unsafe impl<T: Send> Send for Receiver<T> {}
916#[unstable(feature = "mpmc_channel", issue = "126840")]
917unsafe impl<T: Send> Sync for Receiver<T> {}
918
919#[unstable(feature = "mpmc_channel", issue = "126840")]
920impl<T> UnwindSafe for Receiver<T> {}
921#[unstable(feature = "mpmc_channel", issue = "126840")]
922impl<T> RefUnwindSafe for Receiver<T> {}
923
924impl<T> Receiver<T> {
925    /// Attempts to receive a message from the channel without blocking.
926    ///
927    /// This method will never block the caller in order to wait for data to
928    /// become available. Instead, this will always return immediately with a
929    /// possible option of pending data on the channel. (See [`std::sync`] for precise
930    /// guarantees on blocking.)
931    ///
932    /// If called on a zero-capacity channel, this method will receive a message only if there
933    /// happens to be a send operation on the other side of the channel at the same time.
934    ///
935    /// This is useful for a flavor of "optimistic check" before deciding to
936    /// block on a receiver.
937    ///
938    /// Compared with [`recv`], this function has two failure cases instead of one
939    /// (one for disconnection, one for an empty buffer).
940    ///
941    /// [`recv`]: Self::recv
942    /// [`std::sync`]: ../index.html#blocking-guarantees
943    ///
944    /// # Examples
945    ///
946    /// ```rust
947    /// #![feature(mpmc_channel)]
948    ///
949    /// use std::sync::mpmc::{Receiver, channel};
950    ///
951    /// let (_, receiver): (_, Receiver<i32>) = channel();
952    ///
953    /// assert!(receiver.try_recv().is_err());
954    /// ```
955    #[unstable(feature = "mpmc_channel", issue = "126840")]
956    pub fn try_recv(&self) -> Result<T, TryRecvError> {
957        match &self.flavor {
958            ReceiverFlavor::Array(chan) => chan.try_recv(),
959            ReceiverFlavor::List(chan) => chan.try_recv(),
960            ReceiverFlavor::Zero(chan) => chan.try_recv(),
961        }
962    }
963
964    /// Attempts to wait for a value on this receiver, returning an error if the
965    /// corresponding channel has hung up.
966    ///
967    /// This function will always block the current thread if there is no data
968    /// available and it's possible for more data to be sent (at least one sender
969    /// still exists). Once a message is sent to the corresponding [`Sender`],
970    /// this receiver will wake up and return that message.
971    ///
972    /// If the corresponding [`Sender`] has disconnected, or it disconnects while
973    /// this call is blocking, this call will wake up and return [`Err`] to
974    /// indicate that no more messages can ever be received on this channel.
975    /// However, since channels are buffered, messages sent before the disconnect
976    /// will still be properly received.
977    ///
978    /// # Examples
979    ///
980    /// ```
981    /// #![feature(mpmc_channel)]
982    ///
983    /// use std::sync::mpmc;
984    /// use std::thread;
985    ///
986    /// let (send, recv) = mpmc::channel();
987    /// let handle = thread::spawn(move || {
988    ///     send.send(1u8).unwrap();
989    /// });
990    ///
991    /// handle.join().unwrap();
992    ///
993    /// assert_eq!(Ok(1), recv.recv());
994    /// ```
995    ///
996    /// Buffering behavior:
997    ///
998    /// ```
999    /// #![feature(mpmc_channel)]
1000    ///
1001    /// use std::sync::mpmc;
1002    /// use std::thread;
1003    /// use std::sync::mpmc::RecvError;
1004    ///
1005    /// let (send, recv) = mpmc::channel();
1006    /// let handle = thread::spawn(move || {
1007    ///     send.send(1u8).unwrap();
1008    ///     send.send(2).unwrap();
1009    ///     send.send(3).unwrap();
1010    ///     drop(send);
1011    /// });
1012    ///
1013    /// // wait for the thread to join so we ensure the sender is dropped
1014    /// handle.join().unwrap();
1015    ///
1016    /// assert_eq!(Ok(1), recv.recv());
1017    /// assert_eq!(Ok(2), recv.recv());
1018    /// assert_eq!(Ok(3), recv.recv());
1019    /// assert_eq!(Err(RecvError), recv.recv());
1020    /// ```
1021    #[unstable(feature = "mpmc_channel", issue = "126840")]
1022    pub fn recv(&self) -> Result<T, RecvError> {
1023        match &self.flavor {
1024            ReceiverFlavor::Array(chan) => chan.recv(None),
1025            ReceiverFlavor::List(chan) => chan.recv(None),
1026            ReceiverFlavor::Zero(chan) => chan.recv(None),
1027        }
1028        .map_err(|_| RecvError)
1029    }
1030
1031    /// Attempts to wait for a value on this receiver, returning an error if the
1032    /// corresponding channel has hung up, or if it waits more than `timeout`.
1033    ///
1034    /// This function will always block the current thread if there is no data
1035    /// available and it's possible for more data to be sent (at least one sender
1036    /// still exists). Once a message is sent to the corresponding [`Sender`],
1037    /// this receiver will wake up and return that message.
1038    ///
1039    /// If the corresponding [`Sender`] has disconnected, or it disconnects while
1040    /// this call is blocking, this call will wake up and return [`Err`] to
1041    /// indicate that no more messages can ever be received on this channel.
1042    /// However, since channels are buffered, messages sent before the disconnect
1043    /// will still be properly received.
1044    ///
1045    /// # Examples
1046    ///
1047    /// Successfully receiving value before encountering timeout:
1048    ///
1049    /// ```no_run
1050    /// #![feature(mpmc_channel)]
1051    ///
1052    /// use std::thread;
1053    /// use std::time::Duration;
1054    /// use std::sync::mpmc;
1055    ///
1056    /// let (send, recv) = mpmc::channel();
1057    ///
1058    /// thread::spawn(move || {
1059    ///     send.send('a').unwrap();
1060    /// });
1061    ///
1062    /// assert_eq!(
1063    ///     recv.recv_timeout(Duration::from_millis(400)),
1064    ///     Ok('a')
1065    /// );
1066    /// ```
1067    ///
1068    /// Receiving an error upon reaching timeout:
1069    ///
1070    /// ```no_run
1071    /// #![feature(mpmc_channel)]
1072    ///
1073    /// use std::thread;
1074    /// use std::time::Duration;
1075    /// use std::sync::mpmc;
1076    ///
1077    /// let (send, recv) = mpmc::channel();
1078    ///
1079    /// thread::spawn(move || {
1080    ///     thread::sleep(Duration::from_millis(800));
1081    ///     send.send('a').unwrap();
1082    /// });
1083    ///
1084    /// assert_eq!(
1085    ///     recv.recv_timeout(Duration::from_millis(400)),
1086    ///     Err(mpmc::RecvTimeoutError::Timeout)
1087    /// );
1088    /// ```
1089    #[unstable(feature = "mpmc_channel", issue = "126840")]
1090    pub fn recv_timeout(&self, timeout: Duration) -> Result<T, RecvTimeoutError> {
1091        match Instant::now().checked_add(timeout) {
1092            Some(deadline) => self.recv_deadline(deadline),
1093            // So far in the future that it's practically the same as waiting indefinitely.
1094            None => self.recv().map_err(RecvTimeoutError::from),
1095        }
1096    }
1097
1098    /// Attempts to wait for a value on this receiver, returning an error if the
1099    /// corresponding channel has hung up, or if `deadline` is reached.
1100    ///
1101    /// This function will always block the current thread if there is no data
1102    /// available and it's possible for more data to be sent. Once a message is
1103    /// sent to the corresponding [`Sender`], then this receiver will wake up
1104    /// and return that message.
1105    ///
1106    /// If the corresponding [`Sender`] has disconnected, or it disconnects while
1107    /// this call is blocking, this call will wake up and return [`Err`] to
1108    /// indicate that no more messages can ever be received on this channel.
1109    /// However, since channels are buffered, messages sent before the disconnect
1110    /// will still be properly received.
1111    ///
1112    /// # Examples
1113    ///
1114    /// Successfully receiving value before reaching deadline:
1115    ///
1116    /// ```no_run
1117    /// #![feature(mpmc_channel)]
1118    ///
1119    /// use std::thread;
1120    /// use std::time::{Duration, Instant};
1121    /// use std::sync::mpmc;
1122    ///
1123    /// let (send, recv) = mpmc::channel();
1124    ///
1125    /// thread::spawn(move || {
1126    ///     send.send('a').unwrap();
1127    /// });
1128    ///
1129    /// assert_eq!(
1130    ///     recv.recv_deadline(Instant::now() + Duration::from_millis(400)),
1131    ///     Ok('a')
1132    /// );
1133    /// ```
1134    ///
1135    /// Receiving an error upon reaching deadline:
1136    ///
1137    /// ```no_run
1138    /// #![feature(mpmc_channel)]
1139    ///
1140    /// use std::thread;
1141    /// use std::time::{Duration, Instant};
1142    /// use std::sync::mpmc;
1143    ///
1144    /// let (send, recv) = mpmc::channel();
1145    ///
1146    /// thread::spawn(move || {
1147    ///     thread::sleep(Duration::from_millis(800));
1148    ///     send.send('a').unwrap();
1149    /// });
1150    ///
1151    /// assert_eq!(
1152    ///     recv.recv_deadline(Instant::now() + Duration::from_millis(400)),
1153    ///     Err(mpmc::RecvTimeoutError::Timeout)
1154    /// );
1155    /// ```
1156    #[unstable(feature = "mpmc_channel", issue = "126840")]
1157    pub fn recv_deadline(&self, deadline: Instant) -> Result<T, RecvTimeoutError> {
1158        match &self.flavor {
1159            ReceiverFlavor::Array(chan) => chan.recv(Some(deadline)),
1160            ReceiverFlavor::List(chan) => chan.recv(Some(deadline)),
1161            ReceiverFlavor::Zero(chan) => chan.recv(Some(deadline)),
1162        }
1163    }
1164
1165    /// Returns an iterator that will attempt to yield all pending values.
1166    /// It will return `None` if there are no more pending values or if the
1167    /// channel has hung up. The iterator will never [`panic!`] or block the
1168    /// user by waiting for values.
1169    ///
1170    /// # Examples
1171    ///
1172    /// ```no_run
1173    /// #![feature(mpmc_channel)]
1174    ///
1175    /// use std::sync::mpmc::channel;
1176    /// use std::thread;
1177    /// use std::time::Duration;
1178    ///
1179    /// let (sender, receiver) = channel();
1180    ///
1181    /// // nothing is in the buffer yet
1182    /// assert!(receiver.try_iter().next().is_none());
1183    ///
1184    /// thread::spawn(move || {
1185    ///     thread::sleep(Duration::from_secs(1));
1186    ///     sender.send(1).unwrap();
1187    ///     sender.send(2).unwrap();
1188    ///     sender.send(3).unwrap();
1189    /// });
1190    ///
1191    /// // nothing is in the buffer yet
1192    /// assert!(receiver.try_iter().next().is_none());
1193    ///
1194    /// // block for two seconds
1195    /// thread::sleep(Duration::from_secs(2));
1196    ///
1197    /// let mut iter = receiver.try_iter();
1198    /// assert_eq!(iter.next(), Some(1));
1199    /// assert_eq!(iter.next(), Some(2));
1200    /// assert_eq!(iter.next(), Some(3));
1201    /// assert_eq!(iter.next(), None);
1202    /// ```
1203    #[unstable(feature = "mpmc_channel", issue = "126840")]
1204    pub fn try_iter(&self) -> TryIter<'_, T> {
1205        TryIter { rx: self }
1206    }
1207}
1208
1209impl<T> Receiver<T> {
1210    /// Returns `true` if the channel is empty.
1211    ///
1212    /// Note: Zero-capacity channels are always empty.
1213    ///
1214    /// # Examples
1215    ///
1216    /// ```
1217    /// #![feature(mpmc_channel)]
1218    ///
1219    /// use std::sync::mpmc;
1220    /// use std::thread;
1221    ///
1222    /// let (send, recv) = mpmc::channel();
1223    ///
1224    /// assert!(recv.is_empty());
1225    ///
1226    /// let handle = thread::spawn(move || {
1227    ///     send.send(1u8).unwrap();
1228    /// });
1229    ///
1230    /// handle.join().unwrap();
1231    ///
1232    /// assert!(!recv.is_empty());
1233    /// ```
1234    #[unstable(feature = "mpmc_channel", issue = "126840")]
1235    pub fn is_empty(&self) -> bool {
1236        match &self.flavor {
1237            ReceiverFlavor::Array(chan) => chan.is_empty(),
1238            ReceiverFlavor::List(chan) => chan.is_empty(),
1239            ReceiverFlavor::Zero(chan) => chan.is_empty(),
1240        }
1241    }
1242
1243    /// Returns `true` if the channel is full.
1244    ///
1245    /// Note: Zero-capacity channels are always full.
1246    ///
1247    /// # Examples
1248    ///
1249    /// ```
1250    /// #![feature(mpmc_channel)]
1251    ///
1252    /// use std::sync::mpmc;
1253    /// use std::thread;
1254    ///
1255    /// let (send, recv) = mpmc::sync_channel(1);
1256    ///
1257    /// assert!(!recv.is_full());
1258    ///
1259    /// let handle = thread::spawn(move || {
1260    ///     send.send(1u8).unwrap();
1261    /// });
1262    ///
1263    /// handle.join().unwrap();
1264    ///
1265    /// assert!(recv.is_full());
1266    /// ```
1267    #[unstable(feature = "mpmc_channel", issue = "126840")]
1268    pub fn is_full(&self) -> bool {
1269        match &self.flavor {
1270            ReceiverFlavor::Array(chan) => chan.is_full(),
1271            ReceiverFlavor::List(chan) => chan.is_full(),
1272            ReceiverFlavor::Zero(chan) => chan.is_full(),
1273        }
1274    }
1275
1276    /// Returns the number of messages in the channel.
1277    ///
1278    /// # Examples
1279    ///
1280    /// ```
1281    /// #![feature(mpmc_channel)]
1282    ///
1283    /// use std::sync::mpmc;
1284    /// use std::thread;
1285    ///
1286    /// let (send, recv) = mpmc::channel();
1287    ///
1288    /// assert_eq!(recv.len(), 0);
1289    ///
1290    /// let handle = thread::spawn(move || {
1291    ///     send.send(1u8).unwrap();
1292    /// });
1293    ///
1294    /// handle.join().unwrap();
1295    ///
1296    /// assert_eq!(recv.len(), 1);
1297    /// ```
1298    #[unstable(feature = "mpmc_channel", issue = "126840")]
1299    pub fn len(&self) -> usize {
1300        match &self.flavor {
1301            ReceiverFlavor::Array(chan) => chan.len(),
1302            ReceiverFlavor::List(chan) => chan.len(),
1303            ReceiverFlavor::Zero(chan) => chan.len(),
1304        }
1305    }
1306
1307    /// If the channel is bounded, returns its capacity.
1308    ///
1309    /// # Examples
1310    ///
1311    /// ```
1312    /// #![feature(mpmc_channel)]
1313    ///
1314    /// use std::sync::mpmc;
1315    /// use std::thread;
1316    ///
1317    /// let (send, recv) = mpmc::sync_channel(3);
1318    ///
1319    /// assert_eq!(recv.capacity(), Some(3));
1320    ///
1321    /// let handle = thread::spawn(move || {
1322    ///     send.send(1u8).unwrap();
1323    /// });
1324    ///
1325    /// handle.join().unwrap();
1326    ///
1327    /// assert_eq!(recv.capacity(), Some(3));
1328    /// ```
1329    #[unstable(feature = "mpmc_channel", issue = "126840")]
1330    pub fn capacity(&self) -> Option<usize> {
1331        match &self.flavor {
1332            ReceiverFlavor::Array(chan) => chan.capacity(),
1333            ReceiverFlavor::List(chan) => chan.capacity(),
1334            ReceiverFlavor::Zero(chan) => chan.capacity(),
1335        }
1336    }
1337
1338    /// Returns `true` if receivers belong to the same channel.
1339    ///
1340    /// # Examples
1341    ///
1342    /// ```
1343    /// #![feature(mpmc_channel)]
1344    ///
1345    /// use std::sync::mpmc;
1346    ///
1347    /// let (_, rx1) = mpmc::channel::<i32>();
1348    /// let (_, rx2) = mpmc::channel::<i32>();
1349    ///
1350    /// assert!(rx1.same_channel(&rx1));
1351    /// assert!(!rx1.same_channel(&rx2));
1352    /// ```
1353    #[unstable(feature = "mpmc_channel", issue = "126840")]
1354    pub fn same_channel(&self, other: &Receiver<T>) -> bool {
1355        match (&self.flavor, &other.flavor) {
1356            (ReceiverFlavor::Array(a), ReceiverFlavor::Array(b)) => a == b,
1357            (ReceiverFlavor::List(a), ReceiverFlavor::List(b)) => a == b,
1358            (ReceiverFlavor::Zero(a), ReceiverFlavor::Zero(b)) => a == b,
1359            _ => false,
1360        }
1361    }
1362
1363    /// Returns an iterator that will block waiting for messages, but never
1364    /// [`panic!`]. It will return [`None`] when the channel has hung up.
1365    ///
1366    /// # Examples
1367    ///
1368    /// ```rust
1369    /// #![feature(mpmc_channel)]
1370    ///
1371    /// use std::sync::mpmc::channel;
1372    /// use std::thread;
1373    ///
1374    /// let (send, recv) = channel();
1375    ///
1376    /// thread::spawn(move || {
1377    ///     send.send(1).unwrap();
1378    ///     send.send(2).unwrap();
1379    ///     send.send(3).unwrap();
1380    /// });
1381    ///
1382    /// let mut iter = recv.iter();
1383    /// assert_eq!(iter.next(), Some(1));
1384    /// assert_eq!(iter.next(), Some(2));
1385    /// assert_eq!(iter.next(), Some(3));
1386    /// assert_eq!(iter.next(), None);
1387    /// ```
1388    #[unstable(feature = "mpmc_channel", issue = "126840")]
1389    pub fn iter(&self) -> Iter<'_, T> {
1390        Iter { rx: self }
1391    }
1392
1393    /// Returns `true` if the channel is disconnected.
1394    ///
1395    /// Note that a return value of `false` does not guarantee the channel will
1396    /// remain connected. The channel may be disconnected immediately after this method
1397    /// returns, so a subsequent [`Receiver::recv`] may still fail with [`RecvError`].
1398    ///
1399    /// # Examples
1400    ///
1401    /// ```
1402    /// #![feature(mpmc_channel)]
1403    ///
1404    /// use std::sync::mpmc::channel;
1405    ///
1406    /// let (tx, rx) = channel::<i32>();
1407    /// assert!(!rx.is_disconnected());
1408    /// drop(tx);
1409    /// assert!(rx.is_disconnected());
1410    /// ```
1411    #[unstable(feature = "mpmc_channel", issue = "126840")]
1412    pub fn is_disconnected(&self) -> bool {
1413        match &self.flavor {
1414            ReceiverFlavor::Array(chan) => chan.is_disconnected(),
1415            ReceiverFlavor::List(chan) => chan.is_disconnected(),
1416            ReceiverFlavor::Zero(chan) => chan.is_disconnected(),
1417        }
1418    }
1419}
1420
1421#[unstable(feature = "mpmc_channel", issue = "126840")]
1422impl<T> Drop for Receiver<T> {
1423    fn drop(&mut self) {
1424        unsafe {
1425            match &self.flavor {
1426                ReceiverFlavor::Array(chan) => chan.release(|c| c.disconnect_receivers()),
1427                ReceiverFlavor::List(chan) => chan.release(|c| c.disconnect_receivers()),
1428                ReceiverFlavor::Zero(chan) => chan.release(|c| c.disconnect()),
1429            }
1430        }
1431    }
1432}
1433
1434#[unstable(feature = "mpmc_channel", issue = "126840")]
1435impl<T> Clone for Receiver<T> {
1436    fn clone(&self) -> Self {
1437        let flavor = match &self.flavor {
1438            ReceiverFlavor::Array(chan) => ReceiverFlavor::Array(chan.acquire()),
1439            ReceiverFlavor::List(chan) => ReceiverFlavor::List(chan.acquire()),
1440            ReceiverFlavor::Zero(chan) => ReceiverFlavor::Zero(chan.acquire()),
1441        };
1442
1443        Receiver { flavor }
1444    }
1445}
1446
1447#[unstable(feature = "mpmc_channel", issue = "126840")]
1448impl<T> fmt::Debug for Receiver<T> {
1449    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1450        f.debug_struct("Receiver").finish_non_exhaustive()
1451    }
1452}
1453
1454#[cfg(test)]
1455mod tests;