Skip to main content

nuclei/sync/local/mpsc/
mod.rs

1//! Multi-producer, single-consumer channels for the tasks of one shard.
2//!
3//! The names, signatures and error types follow [`sync::mpsc`](crate::sync::mpsc),
4//! so code switches by changing the path. The state sits in one `Rc` and
5//! plain cells, so the halves are `!Send` and no operation touches an atomic.
6//!
7//! The bounded flavor ([`channel`]) holds at most a fixed number of messages
8//! and serves waiting sends strictly in arrival order; the unbounded one
9//! ([`unbounded_channel`]) never makes a send wait.
10//!
11//! What one sender sends comes out in the order it was sent. When every
12//! sender is dropped the stream ends: once the buffered values are received,
13//! `recv` returns `None`. If the receiver is dropped, its unread values are
14//! dropped with it and every later send fails with an error that holds the
15//! value; [`Receiver::close`] first stops further sends and keeps the
16//! buffered values, and the slots reserved before it, usable.
17//!
18//! Left out, because a local channel never leaves its thread: the
19//! `blocking_*` methods (a blocking call there could only wait for itself)
20//! and `WeakSender`.
21//!
22//! Receives, and sends that complete at their first attempt, spend the
23//! cooperative budget (see [`task::coop`](crate::task::coop)) as the atomic
24//! channels do.
25
26/// The receiving methods both flavors share.
27macro_rules! receiver_methods {
28    () => {
29        /// Receives the next value, waiting for one if the channel is open
30        /// and empty. Answers `None` once the channel is closed and drained
31        /// (no sender, and no reserved slot still to be used).
32        ///
33        /// Cancel safe: a dropped future loses no value.
34        pub async fn recv(&mut self) -> Option<T> {
35            core::future::poll_fn(|cx| self.poll_recv(cx)).await
36        }
37
38        /// Receives up to `limit` values into `buf` and answers how many,
39        /// waiting for at least one. Answers 0 when `limit` is 0 or the
40        /// channel ended.
41        ///
42        /// Cancel safe: a dropped future loses no value.
43        pub async fn recv_many(&mut self, buf: &mut Vec<T>, limit: usize) -> usize {
44            core::future::poll_fn(|cx| self.poll_recv_many(cx, buf, limit)).await
45        }
46
47        /// Polls to receive the next value; the waker of `cx` is woken when
48        /// a value arrives or the channel ends.
49        pub fn poll_recv(
50            &mut self,
51            cx: &mut core::task::Context<'_>,
52        ) -> core::task::Poll<Option<T>> {
53            self.chan.poll_recv(cx)
54        }
55
56        /// Polls to receive up to `limit` values into `buf`; see
57        /// [`recv_many`](Self::recv_many).
58        pub fn poll_recv_many(
59            &mut self,
60            cx: &mut core::task::Context<'_>,
61            buf: &mut Vec<T>,
62            limit: usize,
63        ) -> core::task::Poll<usize> {
64            self.chan.poll_recv_many(cx, buf, limit)
65        }
66
67        /// Receives the next value without waiting.
68        ///
69        /// # Errors
70        ///
71        /// [`TryRecvError::Empty`](crate::sync::mpsc::error::TryRecvError::Empty)
72        /// if a value may yet come,
73        /// [`TryRecvError::Disconnected`](crate::sync::mpsc::error::TryRecvError::Disconnected)
74        /// if the channel ended.
75        pub fn try_recv(&mut self) -> Result<T, crate::sync::mpsc::error::TryRecvError> {
76            self.chan.try_recv()
77        }
78
79        /// Closes the receiving half without dropping it: no further value
80        /// can be sent, and sends that wait fail. The values already
81        /// buffered, and the slots reserved before the close, stay usable.
82        pub fn close(&mut self) {
83            self.chan.close_rx();
84        }
85
86        /// Whether the channel is closed: [`close`](Self::close) was called,
87        /// or every sender is gone. Buffered values may still be received.
88        pub fn is_closed(&self) -> bool {
89            self.chan.rx_is_closed()
90        }
91
92        /// Whether the channel holds no value.
93        pub fn is_empty(&self) -> bool {
94            self.chan.len() == 0
95        }
96
97        /// How many values the channel holds.
98        pub fn len(&self) -> usize {
99            self.chan.len()
100        }
101    };
102}
103
104mod bounded;
105mod chan;
106mod unbounded;
107
108pub use self::bounded::{Permit, Receiver, Sender, channel};
109pub use self::unbounded::{UnboundedReceiver, UnboundedSender, unbounded_channel};