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). The channel conceptually has an
19//!    infinite buffer.
20//!
21//! 2. A synchronous, bounded channel. The [`sync_channel`] function will
22//!    return a `(Sender, Receiver)` tuple where the storage for pending
23//!    messages is a pre-allocated buffer of a fixed size. All sends will be
24//!    **synchronous** by blocking until there is buffer space available. Note
25//!    that a bound of 0 is allowed, causing the channel to become a "rendezvous"
26//!    channel where each sender atomically hands off a message to a receiver.
27//!
28//! [`send`]: Sender::send
29//!
30//! ## Disconnection
31//!
32//! The send and receive operations on channels will all return a [`Result`]
33//! indicating whether the operation succeeded or not. An unsuccessful operation
34//! is normally indicative of the other half of a channel having "hung up" by
35//! being dropped in its corresponding thread.
36//!
37//! Once half of a channel has been deallocated, most operations can no longer
38//! continue to make progress, so [`Err`] will be returned. Many applications
39//! will continue to [`unwrap`] the results returned from this module,
40//! instigating a propagation of failure among threads if one unexpectedly dies.
41//!
42//! [`unwrap`]: Result::unwrap
43//!
44//! # Examples
45//!
46//! Simple usage:
47//!
48//! ```
49//! #![feature(mpmc_channel)]
50//!
51//! use std::thread;
52//! use std::sync::mpmc::channel;
53//!
54//! // Create a simple streaming channel
55//! let (tx, rx) = channel();
56//! thread::spawn(move || {
57//!     tx.send(10).unwrap();
58//! });
59//! assert_eq!(rx.recv().unwrap(), 10);
60//! ```
61//!
62//! Shared usage:
63//!
64//! ```
65//! #![feature(mpmc_channel)]
66//!
67//! use std::thread;
68//! use std::sync::mpmc::channel;
69//!
70//! thread::scope(|s| {
71//!     // Create a shared channel that can be sent along from many threads
72//!     // where tx is the sending half (tx for transmission), and rx is the receiving
73//!     // half (rx for receiving).
74//!     let (tx, rx) = channel();
75//!     for i in 0..10 {
76//!         let tx = tx.clone();
77//!         s.spawn(move || {
78//!             tx.send(i).unwrap();
79//!         });
80//!     }
81//!
82//!     for _ in 0..5 {
83//!         let rx1 = rx.clone();
84//!         let rx2 = rx.clone();
85//!         s.spawn(move || {
86//!             let j = rx1.recv().unwrap();
87//!             assert!(0 <= j && j < 10);
88//!         });
89//!         s.spawn(move || {
90//!             let j = rx2.recv().unwrap();
91//!             assert!(0 <= j && j < 10);
92//!         });
93//!     }
94//! })
95//! ```
96//!
97//! Propagating panics:
98//!
99//! ```
100//! #![feature(mpmc_channel)]
101//!
102//! use std::sync::mpmc::channel;
103//!
104//! // The call to recv() will return an error because the channel has already
105//! // hung up (or been deallocated)
106//! let (tx, rx) = channel::<i32>();
107//! drop(tx);
108//! assert!(rx.recv().is_err());
109//! ```
110
111// This module is used as the implementation for the channels in `sync::mpsc`.
112// The implementation comes from the crossbeam-channel crate:
113//
114// Copyright (c) 2019 The Crossbeam Project Developers
115//
116// Permission is hereby granted, free of charge, to any
117// person obtaining a copy of this software and associated
118// documentation files (the "Software"), to deal in the
119// Software without restriction, including without
120// limitation the rights to use, copy, modify, merge,
121// publish, distribute, sublicense, and/or sell copies of
122// the Software, and to permit persons to whom the Software
123// is furnished to do so, subject to the following
124// conditions:
125//
126// The above copyright notice and this permission notice
127// shall be included in all copies or substantial portions
128// of the Software.
129//
130// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
131// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
132// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
133// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
134// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
135// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
136// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
137// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
138// DEALINGS IN THE SOFTWARE.
139
140mod array;
141mod context;
142mod counter;
143mod error;
144mod list;
145mod select;
146mod utils;
147mod waker;
148mod zero;
149
150pub use error::*;
151
152use crate::fmt;
153use crate::panic::{RefUnwindSafe, UnwindSafe};
154use crate::time::{Duration, Instant};
155
156/// Creates a new asynchronous channel, returning the sender/receiver halves.
157///
158/// All data sent on the [`Sender`] will become available on the [`Receiver`] in
159/// the same order as it was sent, and no [`send`] will block the calling thread
160/// (this channel has an "infinite buffer", unlike [`sync_channel`], which will
161/// block after its buffer limit is reached). [`recv`] will block until a message
162/// is available while there is at least one [`Sender`] alive (including clones).
163///
164/// The [`Sender`] can be cloned to [`send`] to the same channel multiple times.
165/// The [`Receiver`] also can be cloned to have multi receivers.
166///
167/// If the [`Receiver`] is disconnected while trying to [`send`] with the
168/// [`Sender`], the [`send`] method will return a [`SendError`]. Similarly, if the
169/// [`Sender`] is disconnected while trying to [`recv`], the [`recv`] method will
170/// return a [`RecvError`].
171///
172/// [`send`]: Sender::send
173/// [`recv`]: Receiver::recv
174///
175/// # Examples
176///
177/// ```
178/// #![feature(mpmc_channel)]
179///
180/// use std::sync::mpmc::channel;
181/// use std::thread;
182///
183/// let (sender, receiver) = channel();
184///
185/// // Spawn off an expensive computation
186/// thread::spawn(move || {
187/// #   fn expensive_computation() {}
188///     sender.send(expensive_computation()).unwrap();
189/// });
190///
191/// // Do some useful work for a while
192///
193/// // Let's see what that answer was
194/// println!("{:?}", receiver.recv().unwrap());
195/// ```
196#[must_use]
197#[unstable(feature = "mpmc_channel", issue = "126840")]
198pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
199    let (s, r) = counter::new(list::Channel::new());
200    let s = Sender { flavor: SenderFlavor::List(s) };
201    let r = Receiver { flavor: ReceiverFlavor::List(r) };
202    (s, r)
203}
204
205/// Creates a new synchronous, bounded channel.
206///
207/// All data sent on the [`Sender`] will become available on the [`Receiver`]
208/// in the same order as it was sent. Like asynchronous [`channel`]s, the
209/// [`Receiver`] will block until a message becomes available. `sync_channel`
210/// differs greatly in the semantics of the sender, however.
211///
212/// This channel has an internal buffer on which messages will be queued.
213/// `bound` specifies the buffer size. When the internal buffer becomes full,
214/// future sends will *block* waiting for the buffer to open up. Note that a
215/// buffer size of 0 is valid, in which case this becomes "rendezvous channel"
216/// where each [`send`] will not return until a [`recv`] is paired with it.
217///
218/// The [`Sender`] can be cloned to [`send`] to the same channel multiple
219/// times. The [`Receiver`] also can be cloned to have multi receivers.
220///
221/// Like asynchronous channels, if the [`Receiver`] is disconnected while trying
222/// to [`send`] with the [`Sender`], the [`send`] method will return a
223/// [`SendError`]. Similarly, If the [`Sender`] is disconnected while trying
224/// to [`recv`], the [`recv`] method will return a [`RecvError`].
225///
226/// [`send`]: Sender::send
227/// [`recv`]: Receiver::recv
228///
229/// # Examples
230///
231/// ```
232/// use std::sync::mpsc::sync_channel;
233/// use std::thread;
234///
235/// let (sender, receiver) = sync_channel(1);
236///
237/// // this returns immediately
238/// sender.send(1).unwrap();
239///
240/// thread::spawn(move || {
241///     // this will block until the previous message has been received
242///     sender.send(2).unwrap();
243/// });
244///
245/// assert_eq!(receiver.recv().unwrap(), 1);
246/// assert_eq!(receiver.recv().unwrap(), 2);
247/// ```
248#[must_use]
249#[unstable(feature = "mpmc_channel", issue = "126840")]
250pub fn sync_channel<T>(cap: usize) -> (Sender<T>, Receiver<T>) {
251    if cap == 0 {
252        let (s, r) = counter::new(zero::Channel::new());
253        let s = Sender { flavor: SenderFlavor::Zero(s) };
254        let r = Receiver { flavor: ReceiverFlavor::Zero(r) };
255        (s, r)
256    } else {
257        let (s, r) = counter::new(array::Channel::with_capacity(cap));
258        let s = Sender { flavor: SenderFlavor::Array(s) };
259        let r = Receiver { flavor: ReceiverFlavor::Array(r) };
260        (s, r)
261    }
262}
263
264/// The sending-half of Rust's synchronous [`channel`] type.
265///
266/// Messages can be sent through this channel with [`send`].
267///
268/// Note: all senders (the original and its clones) need to be dropped for the receiver
269/// to stop blocking to receive messages with [`Receiver::recv`].
270///
271/// [`send`]: Sender::send
272///
273/// # Examples
274///
275/// ```rust
276/// #![feature(mpmc_channel)]
277///
278/// use std::sync::mpmc::channel;
279/// use std::thread;
280///
281/// let (sender, receiver) = channel();
282/// let sender2 = sender.clone();
283///
284/// // First thread owns sender
285/// thread::spawn(move || {
286///     sender.send(1).unwrap();
287/// });
288///
289/// // Second thread owns sender2
290/// thread::spawn(move || {
291///     sender2.send(2).unwrap();
292/// });
293///
294/// let msg = receiver.recv().unwrap();
295/// let msg2 = receiver.recv().unwrap();
296///
297/// assert_eq!(3, msg + msg2);
298/// ```
299#[unstable(feature = "mpmc_channel", issue = "126840")]
300#[cfg_attr(not(test), rustc_diagnostic_item = "MpmcSender")]
301pub struct Sender<T> {
302    flavor: SenderFlavor<T>,
303}
304
305/// Sender flavors.
306enum SenderFlavor<T> {
307    /// Bounded channel based on a preallocated array.
308    Array(counter::Sender<array::Channel<T>>),
309
310    /// Unbounded channel implemented as a linked list.
311    List(counter::Sender<list::Channel<T>>),
312
313    /// Zero-capacity channel.
314    Zero(counter::Sender<zero::Channel<T>>),
315}
316
317#[unstable(feature = "mpmc_channel", issue = "126840")]
318unsafe impl<T: Send> Send for Sender<T> {}
319#[unstable(feature = "mpmc_channel", issue = "126840")]
320unsafe impl<T: Send> Sync for Sender<T> {}
321
322#[unstable(feature = "mpmc_channel", issue = "126840")]
323impl<T> UnwindSafe for Sender<T> {}
324#[unstable(feature = "mpmc_channel", issue = "126840")]
325impl<T> RefUnwindSafe for Sender<T> {}
326
327impl<T> Sender<T> {
328    /// Attempts to send a message into the channel without blocking.
329    ///
330    /// This method will either send a message into the channel immediately or return an error if
331    /// the channel is full or disconnected. The returned error contains the original message.
332    ///
333    /// If called on a zero-capacity channel, this method will send the message only if there
334    /// happens to be a receive operation on the other side of the channel at the same time.
335    ///
336    /// # Examples
337    ///
338    /// ```rust
339    /// #![feature(mpmc_channel)]
340    ///
341    /// use std::sync::mpmc::{channel, Receiver, Sender};
342    ///
343    /// let (sender, _receiver): (Sender<i32>, Receiver<i32>) = channel();
344    ///
345    /// assert!(sender.try_send(1).is_ok());
346    /// ```
347    #[unstable(feature = "mpmc_channel", issue = "126840")]
348    pub fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> {
349        match &self.flavor {
350            SenderFlavor::Array(chan) => chan.try_send(msg),
351            SenderFlavor::List(chan) => chan.try_send(msg),
352            SenderFlavor::Zero(chan) => chan.try_send(msg),
353        }
354    }
355
356    /// Attempts to send a value on this channel, returning it back if it could
357    /// not be sent.
358    ///
359    /// A successful send occurs when it is determined that the other end of
360    /// the channel has not hung up already. An unsuccessful send would be one
361    /// where the corresponding receiver has already been deallocated. Note
362    /// that a return value of [`Err`] means that the data will never be
363    /// received, but a return value of [`Ok`] does *not* mean that the data
364    /// will be received. It is possible for the corresponding receiver to
365    /// hang up immediately after this function returns [`Ok`]. However, if
366    /// the channel is zero-capacity, it acts as a rendezvous channel and a
367    /// return value of [`Ok`] means that the data has been received.
368    ///
369    /// If the channel is full and not disconnected, this call will block until
370    /// the send operation can proceed. If the channel becomes disconnected,
371    /// this call will wake up and return an error. The returned error contains
372    /// the original message.
373    ///
374    /// If called on a zero-capacity channel, this method will wait for a receive
375    /// operation to appear on the other side of the channel.
376    ///
377    /// # Examples
378    ///
379    /// ```
380    /// #![feature(mpmc_channel)]
381    ///
382    /// use std::sync::mpmc::channel;
383    ///
384    /// let (tx, rx) = channel();
385    ///
386    /// // This send is always successful
387    /// tx.send(1).unwrap();
388    ///
389    /// // This send will fail because the receiver is gone
390    /// drop(rx);
391    /// assert!(tx.send(1).is_err());
392    /// ```
393    #[unstable(feature = "mpmc_channel", issue = "126840")]
394    pub fn send(&self, msg: T) -> Result<(), SendError<T>> {
395        match &self.flavor {
396            SenderFlavor::Array(chan) => chan.send(msg, None),
397            SenderFlavor::List(chan) => chan.send(msg, None),
398            SenderFlavor::Zero(chan) => chan.send(msg, None),
399        }
400        .map_err(|err| match err {
401            SendTimeoutError::Disconnected(msg) => SendError(msg),
402            SendTimeoutError::Timeout(_) => unreachable!(),
403        })
404    }
405}
406
407impl<T> Sender<T> {
408    /// Waits for a message to be sent into the channel, but only for a limited time.
409    ///
410    /// If the channel is full and not disconnected, this call will block until the send operation
411    /// can proceed or the operation times out. If the channel becomes disconnected, this call will
412    /// wake up and return an error. The returned error contains the original message.
413    ///
414    /// If called on a zero-capacity channel, this method will wait for a receive operation to
415    /// appear on the other side of the channel.
416    ///
417    /// # Examples
418    ///
419    /// ```
420    /// #![feature(mpmc_channel)]
421    ///
422    /// use std::sync::mpmc::channel;
423    /// use std::time::Duration;
424    ///
425    /// let (tx, rx) = channel();
426    ///
427    /// tx.send_timeout(1, Duration::from_millis(400)).unwrap();
428    /// ```
429    #[unstable(feature = "mpmc_channel", issue = "126840")]
430    pub fn send_timeout(&self, msg: T, timeout: Duration) -> Result<(), SendTimeoutError<T>> {
431        match Instant::now().checked_add(timeout) {
432            Some(deadline) => self.send_deadline(msg, deadline),
433            // So far in the future that it's practically the same as waiting indefinitely.
434            None => self.send(msg).map_err(SendTimeoutError::from),
435        }
436    }
437
438    /// Waits for a message to be sent into the channel, but only until a given deadline.
439    ///
440    /// If the channel is full and not disconnected, this call will block until the send operation
441    /// can proceed or the operation times out. If the channel becomes disconnected, this call will