Explain non-dropped sender recv in docs

Original senders that are still hanging around could cause
Receiver::recv to not block since this is a potential footgun
for beginners, clarify more on this in the docs for readers to
be aware about it.

Fix minor tidbits in sender recv doc

Co-authored-by: Dylan DPC <dylan.dpc@gmail.com>

Add example for unbounded receive loops in doc

Show the drop(tx) pattern, based on tokio docs
https://tokio-rs.github.io/tokio/doc/tokio/sync/index.html

Fix example code for drop sender recv

Fix wording in sender docs

Co-authored-by: Josh Triplett <josh@joshtriplett.org>
This commit is contained in:
Ivan Tham 2020-12-22 02:16:01 +08:00
parent 11c94a1977
commit 0f3c7d18fb

View File

@ -105,6 +105,35 @@
//! });
//! rx.recv().unwrap();
//! ```
//!
//! Unbounded receive loop:
//!
//! ```
//! use std::sync::mpsc::sync_channel;
//! use std::thread;
//!
//! let (tx, rx) = sync_channel(3);
//!
//! for _ in 0..3 {
//! // It would be the same without thread and clone here
//! // since there will still be one `tx` left.
//! let tx = tx.clone();
//! // cloned tx dropped within thread
//! thread::spawn(move || tx.send("ok").unwrap());
//! }
//!
//! // Drop the last sender to stop `rx` waiting for message.
//! // The program will not complete if we comment this out.
//! // **All** `tx` needs to be dropped for `rx` to have `Err`.
//! drop(tx);
//!
//! // Unbounded receiver waiting for all senders to complete.
//! while let Ok(msg) = rx.recv() {
//! println!("{}", msg);
//! }
//!
//! println!("completed");
//! ```
#![stable(feature = "rust1", since = "1.0.0")]
@ -436,6 +465,9 @@ pub struct IntoIter<T> {
///
/// Messages can be sent through this channel with [`send`].
///
/// Note: all senders (the original and the clones) need to be dropped for the receiver
/// to stop blocking to receive messages with [`Receiver::recv`].
///
/// [`send`]: Sender::send
///
/// # Examples
@ -642,7 +674,7 @@ fn inner_unsafe(&self) -> &UnsafeCell<Flavor<T>> {
/// the same order as it was sent, and no [`send`] will block the calling thread
/// (this channel has an "infinite buffer", unlike [`sync_channel`], which will
/// block after its buffer limit is reached). [`recv`] will block until a message
/// is available.
/// is available while there is at least one [`Sender`] alive (including clones).
///
/// The [`Sender`] can be cloned to [`send`] to the same channel multiple times, but
/// only one [`Receiver`] is supported.
@ -805,6 +837,11 @@ pub fn send(&self, t: T) -> Result<(), SendError<T>> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for Sender<T> {
/// Clone a sender to send to other threads.
///
/// Note, be aware of the lifetime of the sender because all senders
/// (including the original) need to be dropped in order for
/// [`Receiver::recv`] to stop blocking.
fn clone(&self) -> Sender<T> {
let packet = match *unsafe { self.inner() } {
Flavor::Oneshot(ref p) => {
@ -1063,9 +1100,10 @@ pub fn try_recv(&self) -> Result<T, TryRecvError> {
/// corresponding channel has hung up.
///
/// This function will always block the current thread if there is no data
/// available and it's possible for more data to be sent. Once a message is
/// sent to the corresponding [`Sender`] (or [`SyncSender`]), then this
/// receiver will wake up and return that message.
/// available and it's possible for more data to be sent (at least one sender
/// still exists). Once a message is sent to the corresponding [`Sender`]
/// (or [`SyncSender`]), this receiver will wake up and return that
/// message.
///
/// If the corresponding [`Sender`] has disconnected, or it disconnects while
/// this call is blocking, this call will wake up and return [`Err`] to
@ -1145,9 +1183,10 @@ pub fn recv(&self) -> Result<T, RecvError> {
/// corresponding channel has hung up, or if it waits more than `timeout`.
///
/// This function will always block the current thread if there is no data
/// available and it's possible for more data to be sent. Once a message is
/// sent to the corresponding [`Sender`] (or [`SyncSender`]), then this
/// receiver will wake up and return that message.
/// available and it's possible for more data to be sent (at least one sender
/// still exists). Once a message is sent to the corresponding [`Sender`]
/// (or [`SyncSender`]), this receiver will wake up and return that
/// message.
///
/// If the corresponding [`Sender`] has disconnected, or it disconnects while
/// this call is blocking, this call will wake up and return [`Err`] to