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;