-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add links and some examples to std::sync::mpsc docs #40981
Changes from 4 commits
5a6ebdf
89c35ae
ae8ba78
dab8e81
ab4f442
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,40 +13,50 @@ | |
//! This module provides message-based communication over channels, concretely | ||
//! defined among three types: | ||
//! | ||
//! * `Sender` | ||
//! * `SyncSender` | ||
//! * `Receiver` | ||
//! * [`Sender`] | ||
//! * [`SyncSender`] | ||
//! * [`Receiver`] | ||
//! | ||
//! A `Sender` or `SyncSender` is used to send data to a `Receiver`. Both | ||
//! A [`Sender`] or [`SyncSender`] is used to send data to a [`Receiver`]. Both | ||
//! senders are clone-able (multi-producer) such that many threads can send | ||
//! simultaneously to one receiver (single-consumer). | ||
//! | ||
//! These channels come in two flavors: | ||
//! | ||
//! 1. An asynchronous, infinitely buffered channel. The `channel()` function | ||
//! 1. An asynchronous, infinitely buffered channel. The [`channel()`] function | ||
//! will return a `(Sender, Receiver)` tuple where all sends will be | ||
//! **asynchronous** (they never block). The channel conceptually has an | ||
//! infinite buffer. | ||
//! | ||
//! 2. A synchronous, bounded channel. The `sync_channel()` function will return | ||
//! a `(SyncSender, Receiver)` tuple where the storage for pending messages | ||
//! is a pre-allocated buffer of a fixed size. All sends will be | ||
//! 2. A synchronous, bounded channel. The [`sync_channel()`] function will | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
//! return a `(SyncSender, Receiver)` tuple where the storage for pending | ||
//! messages is a pre-allocated buffer of a fixed size. All sends will be | ||
//! **synchronous** by blocking until there is buffer space available. Note | ||
//! that a bound of 0 is allowed, causing the channel to become a | ||
//! "rendezvous" channel where each sender atomically hands off a message to | ||
//! a receiver. | ||
//! that a bound of 0 is allowed, causing the channel to become a "rendezvous" | ||
//! channel where each sender atomically hands off a message to a receiver. | ||
//! | ||
//! [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html | ||
//! [`SyncSender`]: ../../../std/sync/mpsc/struct.SyncSender.html | ||
//! [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html | ||
//! [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send | ||
//! [`channel()`]: ../../../std/sync/mpsc/fn.channel.html | ||
//! [`sync_channel()`]: ../../../std/sync/mpsc/fn.sync_channel.html | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and both of these lines to match |
||
//! | ||
//! ## Disconnection | ||
//! | ||
//! The send and receive operations on channels will all return a `Result` | ||
//! The send and receive operations on channels will all return a [`Result`] | ||
//! indicating whether the operation succeeded or not. An unsuccessful operation | ||
//! is normally indicative of the other half of a channel having "hung up" by | ||
//! being dropped in its corresponding thread. | ||
//! | ||
//! Once half of a channel has been deallocated, most operations can no longer | ||
//! continue to make progress, so `Err` will be returned. Many applications will | ||
//! continue to `unwrap()` the results returned from this module, instigating a | ||
//! propagation of failure among threads if one unexpectedly dies. | ||
//! continue to make progress, so [`Err`] will be returned. Many applications | ||
//! will continue to [`unwrap()`] the results returned from this module, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and here |
||
//! instigating a propagation of failure among threads if one unexpectedly dies. | ||
//! | ||
//! [`Result`]: ../../../std/result/enum.Result.html | ||
//! [`Err`]: ../../../std/result/enum.Result.html#variant.Err | ||
//! [`unwrap()`]: ../../../std/result/enum.Result.html#method.unwrap | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and here |
||
//! | ||
//! # Examples | ||
//! | ||
|
@@ -288,7 +298,28 @@ mod mpsc_queue; | |
mod spsc_queue; | ||
|
||
/// The receiving-half of Rust's channel type. This half can only be owned by | ||
/// one thread | ||
/// one thread. | ||
/// | ||
/// Messages sent to the channel can be retrieved using [`recv`]. | ||
/// | ||
/// [`recv`]: ../../../std/sync/mpsc/struct.Receiver.html#method.recv | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```rust | ||
/// use std::sync::mpsc::channel; | ||
/// use std::thread; | ||
/// use std::time::Duration; | ||
/// let (send, recv) = channel(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you add a blank line above and below this one? just the |
||
/// thread::spawn(move || { | ||
/// send.send("Hello world!").unwrap(); | ||
/// thread::sleep(Duration::from_secs(2)); // block for two seconds | ||
/// send.send("Delayed for 2 seconds").unwrap(); | ||
/// }); | ||
/// println!("{}", recv.recv().unwrap()); // Received immediately | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, only one above please! |
||
/// println!("Waiting..."); | ||
/// println!("{}", recv.recv().unwrap()); // Received after 2 seconds | ||
/// ``` | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub struct Receiver<T> { | ||
inner: UnsafeCell<Flavor<T>>, | ||
|
@@ -302,30 +333,39 @@ unsafe impl<T: Send> Send for Receiver<T> { } | |
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T> !Sync for Receiver<T> { } | ||
|
||
/// An iterator over messages on a receiver, this iterator will block | ||
/// whenever `next` is called, waiting for a new message, and `None` will be | ||
/// returned when the corresponding channel has hung up. | ||
/// An iterator over messages on a receiver, this iterator will block whenever | ||
/// [`next`] is called, waiting for a new message, and [`None`] will be returned | ||
/// when the corresponding channel has hung up. | ||
/// | ||
/// [`next`]: ../../../std/iter/trait.Iterator.html#tymethod.next | ||
/// [`None`]: ../../../std/option/enum.Option.html#variant.None | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
#[derive(Debug)] | ||
pub struct Iter<'a, T: 'a> { | ||
rx: &'a Receiver<T> | ||
} | ||
|
||
/// An iterator that attempts to yield all pending values for a receiver. | ||
/// `None` will be returned when there are no pending values remaining or | ||
/// if the corresponding channel has hung up. | ||
/// [`None`] will be returned when there are no pending values remaining or if | ||
/// the corresponding channel has hung up. | ||
/// | ||
/// This Iterator will never block the caller in order to wait for data to | ||
/// become available. Instead, it will return `None`. | ||
/// become available. Instead, it will return [`None`]. | ||
/// | ||
/// [`None`]: ../../../std/option/enum.Option.html#variant.None | ||
#[stable(feature = "receiver_try_iter", since = "1.15.0")] | ||
#[derive(Debug)] | ||
pub struct TryIter<'a, T: 'a> { | ||
rx: &'a Receiver<T> | ||
} | ||
|
||
/// An owning iterator over messages on a receiver, this iterator will block | ||
/// whenever `next` is called, waiting for a new message, and `None` will be | ||
/// whenever [`next`] is called, waiting for a new message, and [`None`] will be | ||
/// returned when the corresponding channel has hung up. | ||
/// | ||
/// [`next`]: ../../../std/iter/trait.Iterator.html#tymethod.next | ||
/// [`None`]: ../../../std/option/enum.Option.html#variant.None | ||
/// | ||
#[stable(feature = "receiver_into_iter", since = "1.1.0")] | ||
#[derive(Debug)] | ||
pub struct IntoIter<T> { | ||
|
@@ -334,6 +374,30 @@ pub struct IntoIter<T> { | |
|
||
/// The sending-half of Rust's asynchronous channel type. This half can only be | ||
/// owned by one thread, but it can be cloned to send to other threads. | ||
/// | ||
/// Messages can be sent through this channel with [`send`]. | ||
/// | ||
/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```rust | ||
/// use std::sync::mpsc::channel; | ||
/// use std::thread; | ||
/// let (sender, receiver) = channel(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you put a blank line above this one... |
||
/// let sender2 = sender.clone(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and below this one? |
||
/// // First thread owns sender | ||
/// thread::spawn(move || { | ||
/// sender.send(1).unwrap(); | ||
/// }); | ||
/// // Second thread owns sender2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and one above here |
||
/// thread::spawn(move || { | ||
/// sender2.send(2).unwrap(); | ||
/// }); | ||
/// let msg = receiver.recv().unwrap(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and one above here |
||
/// let msg2 = receiver.recv().unwrap(); | ||
/// assert_eq!(3, msg + msg2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and one above here, please! |
||
/// ``` | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub struct Sender<T> { | ||
inner: UnsafeCell<Flavor<T>>, | ||
|
@@ -349,6 +413,10 @@ impl<T> !Sync for Sender<T> { } | |
|
||
/// The sending-half of Rust's synchronous channel type. This half can only be | ||
/// owned by one thread, but it can be cloned to send to other threads. | ||
/// | ||
/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send | ||
/// [`SyncSender::send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send | ||
/// | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub struct SyncSender<T> { | ||
inner: Arc<sync::Packet<T>>, | ||
|
@@ -360,25 +428,32 @@ unsafe impl<T: Send> Send for SyncSender<T> {} | |
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T> !Sync for SyncSender<T> {} | ||
|
||
/// An error returned from the `send` function on channels. | ||
/// An error returned from the [`send`] function on channels. | ||
/// | ||
/// A `send` operation can only fail if the receiving end of a channel is | ||
/// A [`send`] operation can only fail if the receiving end of a channel is | ||
/// disconnected, implying that the data could never be received. The error | ||
/// contains the data being sent as a payload so it can be recovered. | ||
/// | ||
/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
#[derive(PartialEq, Eq, Clone, Copy)] | ||
pub struct SendError<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T); | ||
|
||
/// An error returned from the `recv` function on a `Receiver`. | ||
/// An error returned from the [`recv`] function on a [`Receiver`]. | ||
/// | ||
/// The `recv` operation can only fail if the sending half of a channel is | ||
/// The [`recv`] operation can only fail if the sending half of a channel is | ||
/// disconnected, implying that no further messages will ever be received. | ||
/// | ||
/// [`recv`]: ../../../std/sync/mpsc/struct.Receiver.html#method.recv | ||
/// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html | ||
#[derive(PartialEq, Eq, Clone, Copy, Debug)] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub struct RecvError; | ||
|
||
/// This enumeration is the list of the possible reasons that `try_recv` could | ||
/// This enumeration is the list of the possible reasons that [`try_recv`] could | ||
/// not return data when called. | ||
/// | ||
/// [`try_recv`]: ../../../std/sync/mpsc/struct.Receiver.html#method.try_recv | ||
#[derive(PartialEq, Eq, Clone, Copy, Debug)] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub enum TryRecvError { | ||
|
@@ -393,8 +468,10 @@ pub enum TryRecvError { | |
Disconnected, | ||
} | ||
|
||
/// This enumeration is the list of possible errors that `recv_timeout` could | ||
/// This enumeration is the list of possible errors that [`recv_timeout`] could | ||
/// not return data when called. | ||
/// | ||
/// [`recv_timeout`]: ../../../std/sync/mpsc/struct.Receiver.html#method.recv_timeout | ||
#[derive(PartialEq, Eq, Clone, Copy, Debug)] | ||
#[stable(feature = "mpsc_recv_timeout", since = "1.12.0")] | ||
pub enum RecvTimeoutError { | ||
|
@@ -409,7 +486,9 @@ pub enum RecvTimeoutError { | |
} | ||
|
||
/// This enumeration is the list of the possible error outcomes for the | ||
/// `SyncSender::try_send` method. | ||
/// [`SyncSender::try_send`] method. | ||
/// | ||
/// [`SyncSender::try_send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.try_send | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
#[derive(PartialEq, Eq, Clone, Copy)] | ||
pub enum TrySendError<T> { | ||
|
@@ -556,10 +635,13 @@ impl<T> Sender<T> { | |
/// A successful send occurs when it is determined that the other end of | ||
/// the channel has not hung up already. An unsuccessful send would be one | ||
/// where the corresponding receiver has already been deallocated. Note | ||
/// that a return value of `Err` means that the data will never be | ||
/// received, but a return value of `Ok` does *not* mean that the data | ||
/// that a return value of [`Err`] means that the data will never be | ||
/// received, but a return value of [`Ok`] does *not* mean that the data | ||
/// will be received. It is possible for the corresponding receiver to | ||
/// hang up immediately after this function returns `Ok`. | ||
/// hang up immediately after this function returns [`Ok`]. | ||
/// | ||
/// [`Err`]: ../../../std/result/enum.Result.html#variant.Err | ||
/// [`Ok`]: ../../../std/result/enum.Result.html#variant.Ok | ||
/// | ||
/// This method will never block the current thread. | ||
/// | ||
|
@@ -702,23 +784,29 @@ impl<T> SyncSender<T> { | |
/// time. If the buffer size is 0, however, it can be guaranteed that the | ||
/// receiver has indeed received the data if this function returns success. | ||
/// | ||
/// This function will never panic, but it may return `Err` if the | ||
/// `Receiver` has disconnected and is no longer able to receive | ||
/// This function will never panic, but it may return [`Err`] if the | ||
/// [`Receiver`] has disconnected and is no longer able to receive | ||
/// information. | ||
/// | ||
/// [`Err`]: ../../../std/result/enum.Result.html#variant.Err | ||
/// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn send(&self, t: T) -> Result<(), SendError<T>> { | ||
self.inner.send(t).map_err(SendError) | ||
} | ||
|
||
/// Attempts to send a value on this channel without blocking. | ||
/// | ||
/// This method differs from `send` by returning immediately if the | ||
/// This method differs from [`send`] by returning immediately if the | ||
/// channel's buffer is full or no receiver is waiting to acquire some | ||
/// data. Compared with `send`, this function has two failure cases | ||
/// data. Compared with [`send`], this function has two failure cases | ||
/// instead of one (one for disconnection, one for a full buffer). | ||
/// | ||
/// See `SyncSender::send` for notes about guarantees of whether the | ||
/// See [`SyncSender::send`] for notes about guarantees of whether the | ||
/// receiver has received the data or not if this function is successful. | ||
/// | ||
/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send | ||
/// [`SyncSender::send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> { | ||
self.inner.try_send(t) | ||
|
@@ -819,15 +907,18 @@ impl<T> Receiver<T> { | |
/// | ||
/// 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`, then this receiver will wake up and | ||
/// sent to the corresponding [`Sender`], then 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 | ||
/// If the corresponding [`Sender`] has disconnected, or it disconnects while | ||
/// this call is blocking, this call will wake up and return [`Err`] to | ||
/// indicate that no more messages can ever be received on this channel. | ||
/// However, since channels are buffered, messages sent before the disconnect | ||
/// will still be properly received. | ||
/// | ||
/// [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html | ||
/// [`Err`]: ../../../std/result/enum.Result.html#variant.Err | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
|
@@ -907,15 +998,18 @@ impl<T> Receiver<T> { | |
/// | ||
/// 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`, then this receiver will wake up and | ||
/// sent to the corresponding [`Sender`], then 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 | ||
/// If the corresponding [`Sender`] has disconnected, or it disconnects while | ||
/// this call is blocking, this call will wake up and return [`Err`] to | ||
/// indicate that no more messages can ever be received on this channel. | ||
/// However, since channels are buffered, messages sent before the disconnect | ||
/// will still be properly received. | ||
/// | ||
/// [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html | ||
/// [`Err`]: ../../../std/result/enum.Result.html#variant.Err | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```no_run | ||
|
@@ -993,16 +1087,37 @@ impl<T> Receiver<T> { | |
} | ||
|
||
/// Returns an iterator that will block waiting for messages, but never | ||
/// `panic!`. It will return `None` when the channel has hung up. | ||
/// [`panic!`]. It will return [`None`] when the channel has hung up. | ||
/// | ||
/// [`panic!`]: ../../../std/macro.panic.html | ||
/// [`None`]: ../../../std/option/enum.Option.html#variant.None | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```rust | ||
/// use std::sync::mpsc::channel; | ||
/// use std::thread; | ||
/// let (send, recv) = channel(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. one blank line above and below this line, please! |
||
/// thread::spawn(move || { | ||
/// send.send(1u8).unwrap(); | ||
/// send.send(2u8).unwrap(); | ||
/// send.send(3u8).unwrap(); | ||
/// }); | ||
/// for x in recv.iter() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and one above here |
||
/// println!("Got: {}", x); | ||
/// } | ||
/// ``` | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn iter(&self) -> Iter<T> { | ||
Iter { rx: self } | ||
} | ||
|
||
/// Returns an iterator that will attempt to yield all pending values. | ||
/// It will return `None` if there are no more pending values or if the | ||
/// channel has hung up. The iterator will never `panic!` or block the | ||
/// channel has hung up. The iterator will never [`panic!`] or block the | ||
/// user by waiting for values. | ||
/// | ||
/// [`panic!`]: ../../../std/macro.panic.html | ||
#[stable(feature = "receiver_try_iter", since = "1.15.0")] | ||
pub fn try_iter(&self) -> TryIter<T> { | ||
TryIter { rx: self } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you're adapting existing text here, but the style is to drop the
()
s. Would you mind doing that as well please?