nuclei/sync/local/mpsc/
bounded.rs1use core::fmt;
8use core::future::Future;
9use core::mem;
10use core::pin::Pin;
11use core::task::{Context, Poll};
12use std::rc::Rc;
13
14use super::chan::{Chan, Limit};
15use crate::sync::TryAcquireError;
16use crate::sync::local::semaphore::{Acquire, Semaphore};
17use crate::sync::mpsc::error::{SendError, TrySendError};
18
19pub(super) struct Bounded {
20 slots: Semaphore,
21 max: usize,
22}
23
24impl Limit for Bounded {
25 fn release(&self, n: usize) {
26 if n > 0 {
27 self.slots.add_permits(n);
28 }
29 }
30
31 fn is_idle(&self) -> bool {
32 self.slots.available_permits() == self.max
33 }
34
35 fn close(&self) {
36 self.slots.close();
37 }
38}
39
40#[track_caller]
60pub fn channel<T>(buffer: usize) -> (Sender<T>, Receiver<T>) {
61 assert!(buffer > 0, "mpsc bounded channel requires buffer > 0");
62 let chan = Rc::new(Chan::new(Bounded {
63 slots: Semaphore::new(buffer),
64 max: buffer,
65 }));
66 let tx = Sender {
67 chan: Rc::clone(&chan),
68 };
69 (tx, Receiver { chan })
70}
71
72pub struct Sender<T> {
76 chan: Rc<Chan<T, Bounded>>,
77}
78
79impl<T> Sender<T> {
80 pub async fn send(&self, value: T) -> Result<(), SendError<T>> {
100 match self.reserve().await {
101 Ok(permit) => {
102 permit.send(value);
103 Ok(())
104 }
105 Err(_) => Err(SendError(value)),
106 }
107 }
108
109 pub fn try_send(&self, value: T) -> Result<(), TrySendError<T>> {
118 match self.try_reserve() {
119 Ok(permit) => {
120 permit.send(value);
121 Ok(())
122 }
123 Err(TrySendError::Full(())) => Err(TrySendError::Full(value)),
124 Err(TrySendError::Closed(())) => Err(TrySendError::Closed(value)),
125 }
126 }
127
128 pub async fn reserve(&self) -> Result<Permit<'_, T>, SendError<()>> {
139 Reserve {
140 chan: &self.chan,
141 acquire: self.chan.limit.slots.acquire(),
142 }
143 .await
144 }
145
146 pub fn try_reserve(&self) -> Result<Permit<'_, T>, TrySendError<()>> {
153 match self.chan.limit.slots.try_acquire() {
154 Ok(permit) => {
155 permit.forget();
156 Ok(Permit { chan: &self.chan })
157 }
158 Err(TryAcquireError::NoPermits) => Err(TrySendError::Full(())),
159 Err(TryAcquireError::Closed) => Err(TrySendError::Closed(())),
160 }
161 }
162
163 pub async fn closed(&self) {
166 self.chan.closed().await;
167 }
168
169 pub fn is_closed(&self) -> bool {
171 self.chan.is_closed()
172 }
173
174 pub fn same_channel(&self, other: &Self) -> bool {
176 Rc::ptr_eq(&self.chan, &other.chan)
177 }
178
179 pub fn capacity(&self) -> usize {
181 self.chan.limit.slots.available_permits()
182 }
183
184 pub fn max_capacity(&self) -> usize {
186 self.chan.limit.max
187 }
188}
189
190impl<T> Clone for Sender<T> {
191 fn clone(&self) -> Self {
192 self.chan.add_sender();
193 Self {
194 chan: Rc::clone(&self.chan),
195 }
196 }
197}
198
199impl<T> Drop for Sender<T> {
200 fn drop(&mut self) {
201 self.chan.drop_sender();
202 }
203}
204
205impl<T> fmt::Debug for Sender<T> {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 f.debug_struct("Sender")
208 .field("capacity", &self.capacity())
209 .field("max_capacity", &self.max_capacity())
210 .field("closed", &self.is_closed())
211 .finish()
212 }
213}
214
215struct Reserve<'a, T> {
219 chan: &'a Chan<T, Bounded>,
220 acquire: Acquire<'a>,
221}
222
223impl<'a, T> Future for Reserve<'a, T> {
224 type Output = Result<Permit<'a, T>, SendError<()>>;
225
226 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
227 let this = self.get_mut();
228 match Pin::new(&mut this.acquire).poll(cx) {
229 Poll::Ready(Ok(permit)) => {
230 permit.forget();
231 Poll::Ready(Ok(Permit { chan: this.chan }))
232 }
233 Poll::Ready(Err(_)) => Poll::Ready(Err(SendError(()))),
234 Poll::Pending => Poll::Pending,
235 }
236 }
237}
238
239impl<T> Drop for Reserve<'_, T> {
240 fn drop(&mut self) {
241 self.acquire.cancel();
242 self.chan.wake_if_finished();
243 }
244}
245
246#[must_use = "dropping a permit gives its slot back unused"]
261pub struct Permit<'a, T> {
262 chan: &'a Chan<T, Bounded>,
263}
264
265impl<T> Permit<'_, T> {
266 pub fn send(self, value: T) {
268 let chan = self.chan;
269 mem::forget(self);
271 chan.push(value);
272 }
273}
274
275impl<T> Drop for Permit<'_, T> {
276 fn drop(&mut self) {
277 self.chan.give_back(1);
278 }
279}
280
281impl<T> fmt::Debug for Permit<'_, T> {
282 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
283 f.debug_struct("Permit").finish_non_exhaustive()
284 }
285}
286
287pub struct Receiver<T> {
292 chan: Rc<Chan<T, Bounded>>,
293}
294
295impl<T> Receiver<T> {
296 receiver_methods!();
297
298 pub fn capacity(&self) -> usize {
300 self.chan.limit.slots.available_permits()
301 }
302
303 pub fn max_capacity(&self) -> usize {
305 self.chan.limit.max
306 }
307}
308
309impl<T> Drop for Receiver<T> {
310 fn drop(&mut self) {
311 self.chan.drop_rx();
312 }
313}
314
315impl<T> fmt::Debug for Receiver<T> {
316 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317 f.debug_struct("Receiver")
318 .field("len", &self.len())
319 .field("closed", &self.is_closed())
320 .finish()
321 }
322}