Skip to main content

tokio/sync/
semaphore.rs

1use super::batch_semaphore as ll; // low level implementation
2use super::{AcquireError, TryAcquireError};
3#[cfg(all(tokio_unstable, feature = "tracing"))]
4use crate::util::trace;
5use std::sync::Arc;
6
7/// Counting semaphore performing asynchronous permit acquisition.
8///
9/// A semaphore maintains a set of permits. Permits are used to synchronize
10/// access to a shared resource. A semaphore differs from a mutex in that it
11/// can allow more than one concurrent caller to access the shared resource at a
12/// time.
13///
14/// When `acquire` is called and the semaphore has remaining permits, the
15/// function immediately returns a permit. However, if no remaining permits are
16/// available, `acquire` (asynchronously) waits until an outstanding permit is
17/// dropped. At this point, the freed permit is assigned to the caller.
18///
19/// This `Semaphore` is fair, which means that permits are given out in the order
20/// they were requested. This fairness is also applied when `acquire_many` gets
21/// involved, so if a call to `acquire_many` at the front of the queue requests
22/// more permits than currently available, this can prevent a call to `acquire`
23/// from completing, even if the semaphore has enough permits to complete the call
24/// to `acquire`.
25///
26/// To use the `Semaphore` in a poll function, you can use the [`PollSemaphore`]
27/// utility.
28///
29/// # Memory ordering
30///
31/// If a task writes some data and then releases a permit, any task that later
32/// acquires a permit is guaranteed to see that data. This makes it safe to use
33/// a semaphore to hand data off between tasks through shared state.
34///
35/// Stated more precisely in terms of atomic memory orderings: acquiring a
36/// permit (via [`acquire`], [`acquire_many`], [`try_acquire`],
37/// [`try_acquire_many`], or their `_owned` variants), releasing permits (by
38/// dropping a [`SemaphorePermit`] or [`OwnedSemaphorePermit`], or by calling
39/// [`add_permits`] or [`forget_permits`]), and closing the semaphore (via
40/// [`close`]) are all `AcqRel` operations. They are totally ordered, and each
41/// one synchronizes-with all such operations that precede it, giving the same
42/// guarantees as `AcqRel` operations on a single atomic.
43///
44/// A failed acquisition attempt (including [`TryAcquireError::NoPermits`] and
45/// [`TryAcquireError::Closed`]), along with the [`available_permits`] and
46/// [`is_closed`] methods, behave like an `Acquire` load.
47///
48/// [`acquire`]: Semaphore::acquire
49/// [`acquire_many`]: Semaphore::acquire_many
50/// [`try_acquire`]: Semaphore::try_acquire
51/// [`try_acquire_many`]: Semaphore::try_acquire_many
52/// [`add_permits`]: Semaphore::add_permits
53/// [`forget_permits`]: Semaphore::forget_permits
54/// [`close`]: Semaphore::close
55/// [`available_permits`]: Semaphore::available_permits
56/// [`is_closed`]: Semaphore::is_closed
57///
58/// # Examples
59///
60/// Basic usage:
61///
62/// ```
63/// use tokio::sync::{Semaphore, TryAcquireError};
64///
65/// # #[tokio::main(flavor = "current_thread")]
66/// # async fn main() {
67/// let semaphore = Semaphore::new(3);
68///
69/// let a_permit = semaphore.acquire().await.unwrap();
70/// let two_permits = semaphore.acquire_many(2).await.unwrap();
71///
72/// assert_eq!(semaphore.available_permits(), 0);
73///
74/// let permit_attempt = semaphore.try_acquire();
75/// assert_eq!(permit_attempt.err(), Some(TryAcquireError::NoPermits));
76/// # }
77/// ```
78///
79/// ## Limit the number of simultaneously opened files in your program
80///
81/// Most operating systems have limits on the number of open file
82/// handles. Even in systems without explicit limits, resource constraints
83/// implicitly set an upper bound on the number of open files. If your
84/// program attempts to open a large number of files and exceeds this
85/// limit, it will result in an error.
86///
87/// This example uses a Semaphore with 100 permits. By acquiring a permit from
88/// the Semaphore before accessing a file, you ensure that your program opens
89/// no more than 100 files at a time. When trying to open the 101st
90/// file, the program will wait until a permit becomes available before
91/// proceeding to open another file.
92/// ```
93/// # #[cfg(not(target_family = "wasm"))]
94/// # {
95/// use std::io::Result;
96/// use tokio::fs::File;
97/// use tokio::sync::Semaphore;
98/// use tokio::io::AsyncWriteExt;
99///
100/// static PERMITS: Semaphore = Semaphore::const_new(100);
101///
102/// async fn write_to_file(message: &[u8]) -> Result<()> {
103///     let _permit = PERMITS.acquire().await.unwrap();
104///     let mut buffer = File::create("example.txt").await?;
105///     buffer.write_all(message).await?;
106///     Ok(()) // Permit goes out of scope here, and is available again for acquisition
107/// }
108/// # }
109/// ```
110///
111/// ## Limit the number of outgoing requests being sent at the same time
112///
113/// In some scenarios, it might be required to limit the number of outgoing
114/// requests being sent in parallel. This could be due to limits of a consumed
115/// API or the network resources of the system the application is running on.
116///
117/// This example uses an `Arc<Semaphore>` with 10 permits. Each task spawned is
118/// given a reference to the semaphore by cloning the `Arc<Semaphore>`. Before
119/// a task sends a request, it must acquire a permit from the semaphore by
120/// calling [`Semaphore::acquire`]. This ensures that at most 10 requests are
121/// sent in parallel at any given time. After a task has sent a request, it
122/// drops the permit to allow other tasks to send requests.
123///
124/// ```
125/// use std::sync::Arc;
126/// use tokio::sync::Semaphore;
127///
128/// # #[tokio::main(flavor = "current_thread")]
129/// # async fn main() {
130/// // Define maximum number of parallel requests.
131/// let semaphore = Arc::new(Semaphore::new(5));
132/// // Spawn many tasks that will send requests.
133/// let mut jhs = Vec::new();
134/// for task_id in 0..50 {
135///     let semaphore = semaphore.clone();
136///     let jh = tokio::spawn(async move {
137///         // Acquire permit before sending request.
138///         let _permit = semaphore.acquire().await.unwrap();
139///         // Send the request.
140///         let response = send_request(task_id).await;
141///         // Drop the permit after the request has been sent.
142///         drop(_permit);
143///         // Handle response.
144///         // ...
145///
146///         response
147///     });
148///     jhs.push(jh);
149/// }
150/// // Collect responses from tasks.
151/// let mut responses = Vec::new();
152/// for jh in jhs {
153///     let response = jh.await.unwrap();
154///     responses.push(response);
155/// }
156/// // Process responses.
157/// // ...
158/// # }
159/// # async fn send_request(task_id: usize) {
160/// #     // Send request.
161/// # }
162/// ```
163///
164/// ## Limit the number of incoming requests being handled at the same time
165///
166/// Similar to limiting the number of simultaneously opened files, network handles
167/// are a limited resource. Allowing an unbounded amount of requests to be processed
168/// could result in a denial-of-service, among many other issues.
169///
170/// This example uses an `Arc<Semaphore>` instead of a global variable.
171/// To limit the number of requests that can be processed at the time,
172/// we acquire a permit for each task before spawning it. Once acquired,
173/// a new task is spawned; and once finished, the permit is dropped inside
174/// of the task to allow others to spawn. Permits must be acquired via
175/// [`Semaphore::acquire_owned`] to be movable across the task boundary.
176/// (Since our semaphore is not a global variable — if it was, then `acquire` would be enough.)
177///
178/// ```no_run
179/// # #[cfg(not(target_family = "wasm"))]
180/// # {
181/// use std::sync::Arc;
182/// use tokio::sync::Semaphore;
183/// use tokio::net::TcpListener;
184///
185/// #[tokio::main]
186/// async fn main() -> std::io::Result<()> {
187///     let semaphore = Arc::new(Semaphore::new(3));
188///     let listener = TcpListener::bind("127.0.0.1:8080").await?;
189///
190///     loop {
191///         // Acquire permit before accepting the next socket.
192///         //
193///         // We use `acquire_owned` so that we can move `permit` into
194///         // other tasks.
195///         let permit = semaphore.clone().acquire_owned().await.unwrap();
196///         let (mut socket, _) = listener.accept().await?;
197///
198///         tokio::spawn(async move {
199///             // Do work using the socket.
200///             handle_connection(&mut socket).await;
201///             // Drop socket while the permit is still live.
202///             drop(socket);
203///             // Drop the permit, so more tasks can be created.
204///             drop(permit);
205///         });
206///     }
207/// }
208/// # async fn handle_connection(_socket: &mut tokio::net::TcpStream) {
209/// #   // Do work
210/// # }
211/// # }
212/// ```
213///
214/// ## Prevent tests from running in parallel
215///
216/// By default, Rust runs tests in the same file in parallel. However, in some
217/// cases, running two tests in parallel may lead to problems. For example, this
218/// can happen when tests use the same database.
219///
220/// Consider the following scenario:
221/// 1. `test_insert`: Inserts a key-value pair into the database, then retrieves
222///    the value using the same key to verify the insertion.
223/// 2. `test_update`: Inserts a key, then updates the key to a new value and
224///    verifies that the value has been accurately updated.
225/// 3. `test_others`: A third test that doesn't modify the database state. It
226///    can run in parallel with the other tests.
227///
228/// In this example, `test_insert` and `test_update` need to run in sequence to
229/// work, but it doesn't matter which test runs first. We can leverage a
230/// semaphore with a single permit to address this challenge.
231///
232/// ```
233/// # use tokio::sync::Mutex;
234/// # use std::collections::BTreeMap;
235/// # struct Database {
236/// #   map: Mutex<BTreeMap<String, i32>>,
237/// # }
238/// # impl Database {
239/// #    pub const fn setup() -> Database {
240/// #        Database {
241/// #            map: Mutex::const_new(BTreeMap::new()),
242/// #        }
243/// #    }
244/// #    pub async fn insert(&self, key: &str, value: i32) {
245/// #        self.map.lock().await.insert(key.to_string(), value);
246/// #    }
247/// #    pub async fn update(&self, key: &str, value: i32) {
248/// #        self.map.lock().await
249/// #            .entry(key.to_string())
250/// #            .and_modify(|origin| *origin = value);
251/// #    }
252/// #    pub async fn delete(&self, key: &str) {
253/// #        self.map.lock().await.remove(key);
254/// #    }
255/// #    pub async fn get(&self, key: &str) -> i32 {
256/// #        *self.map.lock().await.get(key).unwrap()
257/// #    }
258/// # }
259/// use tokio::sync::Semaphore;
260///
261/// // Initialize a static semaphore with only one permit, which is used to
262/// // prevent test_insert and test_update from running in parallel.
263/// static PERMIT: Semaphore = Semaphore::const_new(1);
264///
265/// // Initialize the database that will be used by the subsequent tests.
266/// static DB: Database = Database::setup();
267///
268/// #[tokio::test]
269/// # async fn fake_test_insert() {}
270/// async fn test_insert() {
271///     // Acquire permit before proceeding. Since the semaphore has only one permit,
272///     // the test will wait if the permit is already acquired by other tests.
273///     let permit = PERMIT.acquire().await.unwrap();
274///
275///     // Do the actual test stuff with database
276///
277///     // Insert a key-value pair to database
278///     let (key, value) = ("name", 0);
279///     DB.insert(key, value).await;
280///
281///     // Verify that the value has been inserted correctly.
282///     assert_eq!(DB.get(key).await, value);
283///
284///     // Undo the insertion, so the database is empty at the end of the test.
285///     DB.delete(key).await;
286///
287///     // Drop permit. This allows the other test to start running.
288///     drop(permit);
289/// }
290///
291/// #[tokio::test]
292/// # async fn fake_test_update() {}
293/// async fn test_update() {
294///     // Acquire permit before proceeding. Since the semaphore has only one permit,
295///     // the test will wait if the permit is already acquired by other tests.
296///     let permit = PERMIT.acquire().await.unwrap();
297///
298///     // Do the same insert.
299///     let (key, value) = ("name", 0);
300///     DB.insert(key, value).await;
301///
302///     // Update the existing value with a new one.
303///     let new_value = 1;
304///     DB.update(key, new_value).await;
305///
306///     // Verify that the value has been updated correctly.
307///     assert_eq!(DB.get(key).await, new_value);
308///
309///     // Undo any modificattion.
310///     DB.delete(key).await;
311///
312///     // Drop permit. This allows the other test to start running.
313///     drop(permit);
314/// }
315///
316/// #[tokio::test]
317/// # async fn fake_test_others() {}
318/// async fn test_others() {
319///     // This test can run in parallel with test_insert and test_update,
320///     // so it does not use PERMIT.
321/// }
322/// # #[tokio::main(flavor = "current_thread")]
323/// # async fn main() {
324/// #   test_insert().await;
325/// #   test_update().await;
326/// #   test_others().await;
327/// # }
328/// ```
329///
330/// ## Rate limiting using a token bucket
331///
332/// This example showcases the [`add_permits`] and [`SemaphorePermit::forget`] methods.
333///
334/// Many applications and systems have constraints on the rate at which certain
335/// operations should occur. Exceeding this rate can result in suboptimal
336/// performance or even errors.
337///
338/// This example implements rate limiting using a [token bucket]. A token bucket is a form of rate
339/// limiting that doesn't kick in immediately, to allow for short bursts of incoming requests that
340/// arrive at the same time.
341///
342/// With a token bucket, each incoming request consumes a token, and the tokens are refilled at a
343/// certain rate that defines the rate limit. When a burst of requests arrives, tokens are
344/// immediately given out until the bucket is empty. Once the bucket is empty, requests will have to
345/// wait for new tokens to be added.
346///
347/// Unlike the example that limits how many requests can be handled at the same time, we do not add
348/// tokens back when we finish handling a request. Instead, tokens are added only by a timer task.
349///
350/// Note that this implementation is suboptimal when the duration is small, because it consumes a
351/// lot of cpu constantly looping and sleeping.
352///
353/// [token bucket]: https://en.wikipedia.org/wiki/Token_bucket
354/// [`add_permits`]: crate::sync::Semaphore::add_permits
355/// [`SemaphorePermit::forget`]: crate::sync::SemaphorePermit::forget
356/// ```
357/// use std::sync::Arc;
358/// use tokio::sync::Semaphore;
359/// use tokio::time::{interval, Duration};
360///
361/// struct TokenBucket {
362///     sem: Arc<Semaphore>,
363///     jh: tokio::task::JoinHandle<()>,
364/// }
365///
366/// impl TokenBucket {
367///     fn new(duration: Duration, capacity: usize) -> Self {
368///         let sem = Arc::new(Semaphore::new(capacity));
369///
370///         // refills the tokens at the end of each interval
371///         let jh = tokio::spawn({
372///             let sem = sem.clone();
373///             let mut interval = interval(duration);
374///             interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
375///
376///             async move {
377///                 loop {
378///                     interval.tick().await;
379///
380///                     if sem.available_permits() < capacity {
381///                         sem.add_permits(1);
382///                     }
383///                 }
384///             }
385///         });
386///
387///         Self { jh, sem }
388///     }
389///
390///     async fn acquire(&self) {
391///         // This can return an error if the semaphore is closed, but we
392///         // never close it, so this error can never happen.
393///         let permit = self.sem.acquire().await.unwrap();
394///         // To avoid releasing the permit back to the semaphore, we use
395///         // the `SemaphorePermit::forget` method.
396///         permit.forget();
397///     }
398/// }
399///
400/// impl Drop for TokenBucket {
401///     fn drop(&mut self) {
402///         // Kill the background task so it stops taking up resources when we
403///         // don't need it anymore.
404///         self.jh.abort();
405///     }
406/// }
407///
408/// # #[tokio::main(flavor = "current_thread")]
409/// # async fn _hidden() {}
410/// # #[tokio::main(flavor = "current_thread", start_paused = true)]
411/// # async fn main() {
412/// let capacity = 5;
413/// let update_interval = Duration::from_secs_f32(1.0 / capacity as f32);
414/// let bucket = TokenBucket::new(update_interval, capacity);
415///
416/// for _ in 0..5 {
417///     bucket.acquire().await;
418///
419///     // do the operation
420/// }
421/// # }
422/// ```
423///
424/// [`PollSemaphore`]: https://docs.rs/tokio-util/latest/tokio_util/sync/struct.PollSemaphore.html
425/// [`Semaphore::acquire_owned`]: crate::sync::Semaphore::acquire_owned
426#[derive(Debug)]
427pub struct Semaphore {
428    /// The low level semaphore
429    ll_sem: ll::Semaphore,
430    #[cfg(all(tokio_unstable, feature = "tracing"))]
431    resource_span: tracing::Span,
432}
433
434/// A permit from the semaphore.
435///
436/// This type is created by the [`acquire`] method.
437///
438/// [`acquire`]: crate::sync::Semaphore::acquire()
439#[must_use]
440#[clippy::has_significant_drop]
441#[derive(Debug)]
442pub struct SemaphorePermit<'a> {
443    sem: &'a Semaphore,
444    permits: usize,
445}
446
447/// An owned permit from the semaphore.
448///
449/// This type is created by the [`acquire_owned`] method.
450///
451/// [`acquire_owned`]: crate::sync::Semaphore::acquire_owned()
452#[must_use]
453#[clippy::has_significant_drop]
454#[derive(Debug)]
455pub struct OwnedSemaphorePermit {
456    sem: Arc<Semaphore>,
457    permits: usize,
458}
459
460#[test]
461#[cfg(not(loom))]
462fn bounds() {
463    fn check_unpin<T: Unpin>() {}
464    // This has to take a value, since the async fn's return type is unnameable.
465    fn check_send_sync_val<T: Send + Sync>(_t: T) {}
466    fn check_send_sync<T: Send + Sync>() {}
467    check_unpin::<Semaphore>();
468    check_unpin::<SemaphorePermit<'_>>();
469    check_send_sync::<Semaphore>();
470
471    let semaphore = Semaphore::new(0);
472    check_send_sync_val(semaphore.acquire());
473}
474
475impl Semaphore {
476    /// The maximum number of permits which a semaphore can hold. It is `usize::MAX >> 3`.
477    ///
478    /// Exceeding this limit typically results in a panic.
479    pub const MAX_PERMITS: usize = super::batch_semaphore::Semaphore::MAX_PERMITS;
480
481    /// Creates a new semaphore with the initial number of permits.
482    ///
483    /// Panics if `permits` exceeds [`Semaphore::MAX_PERMITS`].
484    #[track_caller]
485    pub fn new(permits: usize) -> Self {
486        #[cfg(all(tokio_unstable, feature = "tracing"))]
487        let resource_span = {
488            let location = std::panic::Location::caller();
489
490            tracing::trace_span!(
491                parent: None,
492                "runtime.resource",
493                concrete_type = "Semaphore",
494                kind = "Sync",
495                loc.file = location.file(),
496                loc.line = location.line(),
497                loc.col = location.column(),
498                inherits_child_attrs = true,
499            )
500        };
501
502        #[cfg(all(tokio_unstable, feature = "tracing"))]
503        let ll_sem = resource_span.in_scope(|| ll::Semaphore::new(permits));
504
505        #[cfg(any(not(tokio_unstable), not(feature = "tracing")))]
506        let ll_sem = ll::Semaphore::new(permits);
507
508        Self {
509            ll_sem,
510            #[cfg(all(tokio_unstable, feature = "tracing"))]
511            resource_span,
512        }
513    }
514
515    /// Creates a new semaphore with the initial number of permits.
516    ///
517    /// When using the `tracing` [unstable feature], a `Semaphore` created with
518    /// `const_new` will not be instrumented. As such, it will not be visible
519    /// in [`tokio-console`]. Instead, [`Semaphore::new`] should be used to
520    /// create an instrumented object if that is needed.
521    ///
522    /// # Examples
523    ///
524    /// ```
525    /// use tokio::sync::Semaphore;
526    ///
527    /// static SEM: Semaphore = Semaphore::const_new(10);
528    /// ```
529    ///
530    /// [`tokio-console`]: https://github.com/tokio-rs/console
531    /// [unstable feature]: crate#unstable-features
532    #[cfg(not(all(loom, test)))]
533    pub const fn const_new(permits: usize) -> Self {
534        Self {
535            ll_sem: ll::Semaphore::const_new(permits),
536            #[cfg(all(tokio_unstable, feature = "tracing"))]
537            resource_span: tracing::Span::none(),
538        }
539    }
540
541    /// Creates a new closed semaphore with 0 permits.
542    pub(crate) fn new_closed() -> Self {
543        Self {
544            ll_sem: ll::Semaphore::new_closed(),
545            #[cfg(all(tokio_unstable, feature = "tracing"))]
546            resource_span: tracing::Span::none(),
547        }
548    }
549
550    /// Creates a new closed semaphore with 0 permits.
551    #[cfg(not(all(loom, test)))]
552    pub(crate) const fn const_new_closed() -> Self {
553        Self {
554            ll_sem: ll::Semaphore::const_new_closed(),
555            #[cfg(all(tokio_unstable, feature = "tracing"))]
556            resource_span: tracing::Span::none(),
557        }
558    }
559
560    /// Returns the current number of available permits.
561    pub fn available_permits(&self) -> usize {
562        self.ll_sem.available_permits()
563    }
564
565    /// Adds `n` new permits to the semaphore.
566    ///
567    /// The maximum number of permits is [`Semaphore::MAX_PERMITS`], and this function will panic if the limit is exceeded.
568    pub fn add_permits(&self, n: usize) {
569        self.ll_sem.release(n);
570    }
571
572    /// Decrease a semaphore's permits by a maximum of `n`.
573    ///
574    /// If there are insufficient permits and it's not possible to reduce by `n`,
575    /// return the number of permits that were actually reduced.
576    pub fn forget_permits(&self, n: usize) -> usize {
577        self.ll_sem.forget_permits(n)
578    }
579
580    /// Acquires a permit from the semaphore.
581    ///
582    /// If the semaphore has been closed, this returns an [`AcquireError`].
583    /// Otherwise, this returns a [`SemaphorePermit`] representing the
584    /// acquired permit.
585    ///
586    /// # Cancel safety
587    ///
588    /// This method uses a queue to fairly distribute permits in the order they
589    /// were requested. Cancelling a call to `acquire` makes you lose your place
590    /// in the queue.
591    ///
592    /// # Examples
593    ///
594    /// ```
595    /// use tokio::sync::Semaphore;
596    ///
597    /// # #[tokio::main(flavor = "current_thread")]
598    /// # async fn main() {
599    /// let semaphore = Semaphore::new(2);
600    ///
601    /// let permit_1 = semaphore.acquire().await.unwrap();
602    /// assert_eq!(semaphore.available_permits(), 1);
603    ///
604    /// let permit_2 = semaphore.acquire().await.unwrap();
605    /// assert_eq!(semaphore.available_permits(), 0);
606    ///
607    /// drop(permit_1);
608    /// assert_eq!(semaphore.available_permits(), 1);
609    /// # }
610    /// ```
611    ///
612    /// [`AcquireError`]: crate::sync::AcquireError
613    /// [`SemaphorePermit`]: crate::sync::SemaphorePermit
614    pub async fn acquire(&self) -> Result<SemaphorePermit<'_>, AcquireError> {
615        #[cfg(all(tokio_unstable, feature = "tracing"))]
616        let inner = trace::async_op(
617            || self.ll_sem.acquire(1),
618            self.resource_span.clone(),
619            "Semaphore::acquire",
620            "poll",
621            true,
622        );
623        #[cfg(not(all(tokio_unstable, feature = "tracing")))]
624        let inner = self.ll_sem.acquire(1);
625
626        inner.await?;
627        Ok(SemaphorePermit {
628            sem: self,
629            permits: 1,
630        })
631    }
632
633    /// Acquires `n` permits from the semaphore.
634    ///
635    /// If the semaphore has been closed, this returns an [`AcquireError`].
636    /// Otherwise, this returns a [`SemaphorePermit`] representing the
637    /// acquired permits.
638    ///
639    /// # Cancel safety
640    ///
641    /// This method uses a queue to fairly distribute permits in the order they
642    /// were requested. Cancelling a call to `acquire_many` makes you lose your
643    /// place in the queue.
644    ///
645    /// # Examples
646    ///
647    /// ```
648    /// use tokio::sync::Semaphore;
649    ///
650    /// # #[tokio::main(flavor = "current_thread")]
651    /// # async fn main() {
652    /// let semaphore = Semaphore::new(5);
653    ///
654    /// let permit = semaphore.acquire_many(3).await.unwrap();
655    /// assert_eq!(semaphore.available_permits(), 2);
656    /// # }
657    /// ```
658    ///
659    /// [`AcquireError`]: crate::sync::AcquireError
660    /// [`SemaphorePermit`]: crate::sync::SemaphorePermit
661    pub async fn acquire_many(&self, n: u32) -> Result<SemaphorePermit<'_>, AcquireError> {
662        #[cfg(all(tokio_unstable, feature = "tracing"))]
663        trace::async_op(
664            || self.ll_sem.acquire(n as usize),
665            self.resource_span.clone(),
666            "Semaphore::acquire_many",
667            "poll",
668            true,
669        )
670        .await?;
671
672        #[cfg(not(all(tokio_unstable, feature = "tracing")))]
673        self.ll_sem.acquire(n as usize).await?;
674
675        Ok(SemaphorePermit {
676            sem: self,
677            permits: n as usize,
678        })
679    }
680
681    /// Tries to acquire a permit from the semaphore.
682    ///
683    /// If the semaphore has been closed, this returns a [`TryAcquireError::Closed`]
684    /// and a [`TryAcquireError::NoPermits`] if there are no permits left. Otherwise,
685    /// this returns a [`SemaphorePermit`] representing the acquired permits.
686    ///
687    /// # Examples
688    ///
689    /// ```
690    /// use tokio::sync::{Semaphore, TryAcquireError};
691    ///
692    /// # fn main() {
693    /// let semaphore = Semaphore::new(2);
694    ///
695    /// let permit_1 = semaphore.try_acquire().unwrap();
696    /// assert_eq!(semaphore.available_permits(), 1);
697    ///
698    /// let permit_2 = semaphore.try_acquire().unwrap();
699    /// assert_eq!(semaphore.available_permits(), 0);
700    ///
701    /// let permit_3 = semaphore.try_acquire();
702    /// assert_eq!(permit_3.err(), Some(TryAcquireError::NoPermits));
703    /// # }
704    /// ```
705    ///
706    /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed
707    /// [`TryAcquireError::NoPermits`]: crate::sync::TryAcquireError::NoPermits
708    /// [`SemaphorePermit`]: crate::sync::SemaphorePermit
709    pub fn try_acquire(&self) -> Result<SemaphorePermit<'_>, TryAcquireError> {
710        match self.ll_sem.try_acquire(1) {
711            Ok(()) => Ok(SemaphorePermit {
712                sem: self,
713                permits: 1,
714            }),
715            Err(e) => Err(e),
716        }
717    }
718
719    /// Tries to acquire `n` permits from the semaphore.
720    ///
721    /// If the semaphore has been closed, this returns a [`TryAcquireError::Closed`]
722    /// and a [`TryAcquireError::NoPermits`] if there are not enough permits left.
723    /// Otherwise, this returns a [`SemaphorePermit`] representing the acquired permits.
724    ///
725    /// # Examples
726    ///
727    /// ```
728    /// use tokio::sync::{Semaphore, TryAcquireError};
729    ///
730    /// # fn main() {
731    /// let semaphore = Semaphore::new(4);
732    ///
733    /// let permit_1 = semaphore.try_acquire_many(3).unwrap();
734    /// assert_eq!(semaphore.available_permits(), 1);
735    ///
736    /// let permit_2 = semaphore.try_acquire_many(2);
737    /// assert_eq!(permit_2.err(), Some(TryAcquireError::NoPermits));
738    /// # }
739    /// ```
740    ///
741    /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed
742    /// [`TryAcquireError::NoPermits`]: crate::sync::TryAcquireError::NoPermits
743    /// [`SemaphorePermit`]: crate::sync::SemaphorePermit
744    pub fn try_acquire_many(&self, n: u32) -> Result<SemaphorePermit<'_>, TryAcquireError> {
745        match self.ll_sem.try_acquire(n as usize) {
746            Ok(()) => Ok(SemaphorePermit {
747                sem: self,
748                permits: n as usize,
749            }),
750            Err(e) => Err(e),
751        }
752    }
753
754    /// Acquires a permit from the semaphore, blocking the current thread until
755    /// one is available.
756    ///
757    /// If the semaphore has been closed, this returns an [`AcquireError`].
758    /// Otherwise, this returns a [`SemaphorePermit`] representing the
759    /// acquired permit.
760    ///
761    /// This method is intended for use in synchronous code, such as inside
762    /// [`spawn_blocking`] or when the semaphore is shared between asynchronous
763    /// and synchronous code. It is the blocking equivalent of [`acquire`].
764    ///
765    /// # Panics
766    ///
767    /// This function panics if called within an asynchronous execution
768    /// context.
769    ///
770    /// # Examples
771    ///
772    /// ```
773    /// # #[cfg(not(target_family = "wasm"))]
774    /// # {
775    /// use std::sync::Arc;
776    /// use tokio::sync::Semaphore;
777    ///
778    /// #[tokio::main(flavor = "current_thread")]
779    /// async fn main() {
780    ///     let semaphore = Arc::new(Semaphore::new(2));
781    ///
782    ///     let semaphore2 = semaphore.clone();
783    ///     let blocking_task = tokio::task::spawn_blocking(move || {
784    ///         // Inside a blocking context we cannot use `.await`, so we use
785    ///         // `blocking_acquire` instead.
786    ///         let _permit = semaphore2.blocking_acquire().unwrap();
787    ///
788    ///         // ... perform blocking work while holding the permit ...
789    ///     });
790    ///
791    ///     blocking_task.await.unwrap();
792    /// }
793    /// # }
794    /// ```
795    ///
796    /// [`AcquireError`]: crate::sync::AcquireError
797    /// [`SemaphorePermit`]: crate::sync::SemaphorePermit
798    /// [`spawn_blocking`]: crate::task::spawn_blocking
799    /// [`acquire`]: Semaphore::acquire
800    #[track_caller]
801    #[cfg(feature = "sync")]
802    pub fn blocking_acquire(&self) -> Result<SemaphorePermit<'_>, AcquireError> {
803        crate::future::block_on(self.acquire())
804    }
805
806    /// Acquires `n` permits from the semaphore, blocking the current thread
807    /// until they are available.
808    ///
809    /// If the semaphore has been closed, this returns an [`AcquireError`].
810    /// Otherwise, this returns a [`SemaphorePermit`] representing the
811    /// acquired permits.
812    ///
813    /// This method is the blocking equivalent of [`acquire_many`].
814    ///
815    /// # Panics
816    ///
817    /// This function panics if called within an asynchronous execution
818    /// context.
819    ///
820    /// # Examples
821    ///
822    /// ```
823    /// use tokio::sync::Semaphore;
824    ///
825    /// fn main() {
826    ///     let semaphore = Semaphore::new(5);
827    ///
828    ///     let permit = semaphore.blocking_acquire_many(3).unwrap();
829    ///     assert_eq!(semaphore.available_permits(), 2);
830    /// }
831    /// ```
832    ///
833    /// [`AcquireError`]: crate::sync::AcquireError
834    /// [`SemaphorePermit`]: crate::sync::SemaphorePermit
835    /// [`acquire_many`]: Semaphore::acquire_many
836    #[track_caller]
837    #[cfg(feature = "sync")]
838    pub fn blocking_acquire_many(&self, n: u32) -> Result<SemaphorePermit<'_>, AcquireError> {
839        crate::future::block_on(self.acquire_many(n))
840    }
841
842    /// Acquires a permit from the semaphore.
843    ///
844    /// The semaphore must be wrapped in an [`Arc`] to call this method.
845    /// If the semaphore has been closed, this returns an [`AcquireError`].
846    /// Otherwise, this returns a [`OwnedSemaphorePermit`] representing the
847    /// acquired permit.
848    ///
849    /// # Cancel safety
850    ///
851    /// This method uses a queue to fairly distribute permits in the order they
852    /// were requested. Cancelling a call to `acquire_owned` makes you lose your
853    /// place in the queue.
854    ///
855    /// # Examples
856    ///
857    /// ```
858    /// use std::sync::Arc;
859    /// use tokio::sync::Semaphore;
860    ///
861    /// # #[tokio::main(flavor = "current_thread")]
862    /// # async fn main() {
863    /// let semaphore = Arc::new(Semaphore::new(3));
864    /// let mut join_handles = Vec::new();
865    ///
866    /// for _ in 0..5 {
867    ///     let permit = semaphore.clone().acquire_owned().await.unwrap();
868    ///     join_handles.push(tokio::spawn(async move {
869    ///         // perform task...
870    ///         // explicitly own `permit` in the task
871    ///         drop(permit);
872    ///     }));
873    /// }
874    ///
875    /// for handle in join_handles {
876    ///     handle.await.unwrap();
877    /// }
878    /// # }
879    /// ```
880    ///
881    /// [`Arc`]: std::sync::Arc
882    /// [`AcquireError`]: crate::sync::AcquireError
883    /// [`OwnedSemaphorePermit`]: crate::sync::OwnedSemaphorePermit
884    pub async fn acquire_owned(self: Arc<Self>) -> Result<OwnedSemaphorePermit, AcquireError> {
885        #[cfg(all(tokio_unstable, feature = "tracing"))]
886        let inner = trace::async_op(
887            || self.ll_sem.acquire(1),
888            self.resource_span.clone(),
889            "Semaphore::acquire_owned",
890            "poll",
891            true,
892        );
893        #[cfg(not(all(tokio_unstable, feature = "tracing")))]
894        let inner = self.ll_sem.acquire(1);
895
896        inner.await?;
897        Ok(OwnedSemaphorePermit {
898            sem: self,
899            permits: 1,
900        })
901    }
902
903    /// Acquires `n` permits from the semaphore.
904    ///
905    /// The semaphore must be wrapped in an [`Arc`] to call this method.
906    /// If the semaphore has been closed, this returns an [`AcquireError`].
907    /// Otherwise, this returns a [`OwnedSemaphorePermit`] representing the
908    /// acquired permit.
909    ///
910    /// # Cancel safety
911    ///
912    /// This method uses a queue to fairly distribute permits in the order they
913    /// were requested. Cancelling a call to `acquire_many_owned` makes you lose
914    /// your place in the queue.
915    ///
916    /// # Examples
917    ///
918    /// ```
919    /// use std::sync::Arc;
920    /// use tokio::sync::Semaphore;
921    ///
922    /// # #[tokio::main(flavor = "current_thread")]
923    /// # async fn main() {
924    /// let semaphore = Arc::new(Semaphore::new(10));
925    /// let mut join_handles = Vec::new();
926    ///
927    /// for _ in 0..5 {
928    ///     let permit = semaphore.clone().acquire_many_owned(2).await.unwrap();
929    ///     join_handles.push(tokio::spawn(async move {
930    ///         // perform task...
931    ///         // explicitly own `permit` in the task
932    ///         drop(permit);
933    ///     }));
934    /// }
935    ///
936    /// for handle in join_handles {
937    ///     handle.await.unwrap();
938    /// }
939    /// # }
940    /// ```
941    ///
942    /// [`Arc`]: std::sync::Arc
943    /// [`AcquireError`]: crate::sync::AcquireError
944    /// [`OwnedSemaphorePermit`]: crate::sync::OwnedSemaphorePermit
945    pub async fn acquire_many_owned(
946        self: Arc<Self>,
947        n: u32,
948    ) -> Result<OwnedSemaphorePermit, AcquireError> {
949        #[cfg(all(tokio_unstable, feature = "tracing"))]
950        let inner = trace::async_op(
951            || self.ll_sem.acquire(n as usize),
952            self.resource_span.clone(),
953            "Semaphore::acquire_many_owned",
954            "poll",
955            true,
956        );
957        #[cfg(not(all(tokio_unstable, feature = "tracing")))]
958        let inner = self.ll_sem.acquire(n as usize);
959
960        inner.await?;
961        Ok(OwnedSemaphorePermit {
962            sem: self,
963            permits: n as usize,
964        })
965    }
966
967    /// Tries to acquire a permit from the semaphore.
968    ///
969    /// The semaphore must be wrapped in an [`Arc`] to call this method. If
970    /// the semaphore has been closed, this returns a [`TryAcquireError::Closed`]
971    /// and a [`TryAcquireError::NoPermits`] if there are no permits left.
972    /// Otherwise, this returns a [`OwnedSemaphorePermit`] representing the
973    /// acquired permit.
974    ///
975    /// # Examples
976    ///
977    /// ```
978    /// use std::sync::Arc;
979    /// use tokio::sync::{Semaphore, TryAcquireError};
980    ///
981    /// # fn main() {
982    /// let semaphore = Arc::new(Semaphore::new(2));
983    ///
984    /// let permit_1 = Arc::clone(&semaphore).try_acquire_owned().unwrap();
985    /// assert_eq!(semaphore.available_permits(), 1);
986    ///
987    /// let permit_2 = Arc::clone(&semaphore).try_acquire_owned().unwrap();
988    /// assert_eq!(semaphore.available_permits(), 0);
989    ///
990    /// let permit_3 = semaphore.try_acquire_owned();
991    /// assert_eq!(permit_3.err(), Some(TryAcquireError::NoPermits));
992    /// # }
993    /// ```
994    ///
995    /// [`Arc`]: std::sync::Arc
996    /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed
997    /// [`TryAcquireError::NoPermits`]: crate::sync::TryAcquireError::NoPermits
998    /// [`OwnedSemaphorePermit`]: crate::sync::OwnedSemaphorePermit
999    pub fn try_acquire_owned(self: Arc<Self>) -> Result<OwnedSemaphorePermit, TryAcquireError> {
1000        match self.ll_sem.try_acquire(1) {
1001            Ok(()) => Ok(OwnedSemaphorePermit {
1002                sem: self,
1003                permits: 1,
1004            }),
1005            Err(e) => Err(e),
1006        }
1007    }
1008
1009    /// Tries to acquire `n` permits from the semaphore.
1010    ///
1011    /// The semaphore must be wrapped in an [`Arc`] to call this method. If
1012    /// the semaphore has been closed, this returns a [`TryAcquireError::Closed`]
1013    /// and a [`TryAcquireError::NoPermits`] if there are no permits left.
1014    /// Otherwise, this returns a [`OwnedSemaphorePermit`] representing the
1015    /// acquired permit.
1016    ///
1017    /// # Examples
1018    ///
1019    /// ```
1020    /// use std::sync::Arc;
1021    /// use tokio::sync::{Semaphore, TryAcquireError};
1022    ///
1023    /// # fn main() {
1024    /// let semaphore = Arc::new(Semaphore::new(4));
1025    ///
1026    /// let permit_1 = Arc::clone(&semaphore).try_acquire_many_owned(3).unwrap();
1027    /// assert_eq!(semaphore.available_permits(), 1);
1028    ///
1029    /// let permit_2 = semaphore.try_acquire_many_owned(2);
1030    /// assert_eq!(permit_2.err(), Some(TryAcquireError::NoPermits));
1031    /// # }
1032    /// ```
1033    ///
1034    /// [`Arc`]: std::sync::Arc
1035    /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed
1036    /// [`TryAcquireError::NoPermits`]: crate::sync::TryAcquireError::NoPermits
1037    /// [`OwnedSemaphorePermit`]: crate::sync::OwnedSemaphorePermit
1038    pub fn try_acquire_many_owned(
1039        self: Arc<Self>,
1040        n: u32,
1041    ) -> Result<OwnedSemaphorePermit, TryAcquireError> {
1042        match self.ll_sem.try_acquire(n as usize) {
1043            Ok(()) => Ok(OwnedSemaphorePermit {
1044                sem: self,
1045                permits: n as usize,
1046            }),
1047            Err(e) => Err(e),
1048        }
1049    }
1050
1051    /// Acquires a permit from the semaphore, blocking the current thread until
1052    /// one is available.
1053    ///
1054    /// The semaphore must be wrapped in an [`Arc`] to call this method.
1055    /// If the semaphore has been closed, this returns an [`AcquireError`].
1056    /// Otherwise, this returns an [`OwnedSemaphorePermit`] representing the
1057    /// acquired permit.
1058    ///
1059    /// This method is the blocking equivalent of [`acquire_owned`].
1060    ///
1061    /// # Panics
1062    ///
1063    /// This function panics if called within an asynchronous execution
1064    /// context.
1065    ///
1066    /// # Examples
1067    ///
1068    /// ```
1069    /// use std::sync::Arc;
1070    /// use tokio::sync::Semaphore;
1071    ///
1072    /// fn main() {
1073    ///     let semaphore = Arc::new(Semaphore::new(2));
1074    ///
1075    ///     let permit = semaphore.clone().blocking_acquire_owned().unwrap();
1076    ///     assert_eq!(semaphore.available_permits(), 1);
1077    /// }
1078    /// ```
1079    ///
1080    /// [`Arc`]: std::sync::Arc
1081    /// [`AcquireError`]: crate::sync::AcquireError
1082    /// [`OwnedSemaphorePermit`]: crate::sync::OwnedSemaphorePermit
1083    /// [`acquire_owned`]: Semaphore::acquire_owned
1084    #[track_caller]
1085    #[cfg(feature = "sync")]
1086    pub fn blocking_acquire_owned(self: Arc<Self>) -> Result<OwnedSemaphorePermit, AcquireError> {
1087        crate::future::block_on(self.acquire_owned())
1088    }
1089
1090    /// Acquires `n` permits from the semaphore, blocking the current thread
1091    /// until they are available.
1092    ///
1093    /// The semaphore must be wrapped in an [`Arc`] to call this method.
1094    /// If the semaphore has been closed, this returns an [`AcquireError`].
1095    /// Otherwise, this returns an [`OwnedSemaphorePermit`] representing the
1096    /// acquired permits.
1097    ///
1098    /// This method is the blocking equivalent of [`acquire_many_owned`].
1099    ///
1100    /// # Panics
1101    ///
1102    /// This function panics if called within an asynchronous execution
1103    /// context.
1104    ///
1105    /// # Examples
1106    ///
1107    /// ```
1108    /// use std::sync::Arc;
1109    /// use tokio::sync::Semaphore;
1110    ///
1111    /// fn main() {
1112    ///     let semaphore = Arc::new(Semaphore::new(5));
1113    ///
1114    ///     let permit = semaphore.clone().blocking_acquire_many_owned(3).unwrap();
1115    ///     assert_eq!(semaphore.available_permits(), 2);
1116    /// }
1117    /// ```
1118    ///
1119    /// [`Arc`]: std::sync::Arc
1120    /// [`AcquireError`]: crate::sync::AcquireError
1121    /// [`OwnedSemaphorePermit`]: crate::sync::OwnedSemaphorePermit
1122    /// [`acquire_many_owned`]: Semaphore::acquire_many_owned
1123    #[track_caller]
1124    #[cfg(feature = "sync")]
1125    pub fn blocking_acquire_many_owned(
1126        self: Arc<Self>,
1127        n: u32,
1128    ) -> Result<OwnedSemaphorePermit, AcquireError> {
1129        crate::future::block_on(self.acquire_many_owned(n))
1130    }
1131
1132    /// Closes the semaphore.
1133    ///
1134    /// This prevents the semaphore from issuing new permits and notifies all pending waiters.
1135    ///
1136    /// # Examples
1137    ///
1138    /// ```
1139    /// use tokio::sync::Semaphore;
1140    /// use std::sync::Arc;
1141    /// use tokio::sync::TryAcquireError;
1142    ///
1143    /// # #[tokio::main(flavor = "current_thread")]
1144    /// # async fn main() {
1145    /// let semaphore = Arc::new(Semaphore::new(1));
1146    /// let semaphore2 = semaphore.clone();
1147    ///
1148    /// tokio::spawn(async move {
1149    ///     let permit = semaphore.acquire_many(2).await;
1150    ///     assert!(permit.is_err());
1151    ///     println!("waiter received error");
1152    /// });
1153    ///
1154    /// println!("closing semaphore");
1155    /// semaphore2.close();
1156    ///
1157    /// // Cannot obtain more permits
1158    /// assert_eq!(semaphore2.try_acquire().err(), Some(TryAcquireError::Closed))
1159    /// # }
1160    /// ```
1161    pub fn close(&self) {
1162        self.ll_sem.close();
1163    }
1164
1165    /// Returns true if the semaphore is closed
1166    pub fn is_closed(&self) -> bool {
1167        self.ll_sem.is_closed()
1168    }
1169}
1170
1171impl<'a> SemaphorePermit<'a> {
1172    /// Forgets the permit **without** releasing it back to the semaphore.
1173    /// This can be used to reduce the amount of permits available from a
1174    /// semaphore.
1175    ///
1176    /// # Examples
1177    ///
1178    /// ```
1179    /// use std::sync::Arc;
1180    /// use tokio::sync::Semaphore;
1181    ///
1182    /// let sem = Arc::new(Semaphore::new(10));
1183    /// {
1184    ///     let permit = sem.try_acquire_many(5).unwrap();
1185    ///     assert_eq!(sem.available_permits(), 5);
1186    ///     permit.forget();
1187    /// }
1188    ///
1189    /// // Since we forgot the permit, available permits won't go back to its initial value
1190    /// // even after the permit is dropped.
1191    /// assert_eq!(sem.available_permits(), 5);
1192    /// ```
1193    pub fn forget(mut self) {
1194        self.permits = 0;
1195    }
1196
1197    /// Merge two [`SemaphorePermit`] instances together, consuming `other`
1198    /// without releasing the permits it holds.
1199    ///
1200    /// Permits held by both `self` and `other` are released when `self` drops.
1201    ///
1202    /// # Panics
1203    ///
1204    /// This function panics if permits from different [`Semaphore`] instances
1205    /// are merged.
1206    ///
1207    /// # Examples
1208    ///
1209    /// ```
1210    /// use std::sync::Arc;
1211    /// use tokio::sync::Semaphore;
1212    ///
1213    /// let sem = Arc::new(Semaphore::new(10));
1214    /// let mut permit = sem.try_acquire().unwrap();
1215    ///
1216    /// for _ in 0..9 {
1217    ///     let _permit = sem.try_acquire().unwrap();
1218    ///     // Merge individual permits into a single one.
1219    ///     permit.merge(_permit)
1220    /// }
1221    ///
1222    /// assert_eq!(sem.available_permits(), 0);
1223    ///
1224    /// // Release all permits in a single batch.
1225    /// drop(permit);
1226    ///
1227    /// assert_eq!(sem.available_permits(), 10);
1228    /// ```
1229    #[track_caller]
1230    pub fn merge(&mut self, mut other: Self) {
1231        assert!(
1232            std::ptr::eq(self.sem, other.sem),
1233            "merging permits from different semaphore instances"
1234        );
1235        self.permits = self
1236            .permits
1237            .checked_add(other.permits)
1238            .expect("number of permits overflowed");
1239        other.permits = 0;
1240    }
1241
1242    /// Splits `n` permits from `self` and returns a new [`SemaphorePermit`] instance that holds `n` permits.
1243    ///
1244    /// If there are insufficient permits and it's not possible to reduce by `n`, returns `None`.
1245    ///
1246    /// # Examples
1247    ///
1248    /// ```
1249    /// use std::sync::Arc;
1250    /// use tokio::sync::Semaphore;
1251    ///
1252    /// let sem = Arc::new(Semaphore::new(3));
1253    ///
1254    /// let mut p1 = sem.try_acquire_many(3).unwrap();
1255    /// let p2 = p1.split(1).unwrap();
1256    ///
1257    /// assert_eq!(p1.num_permits(), 2);
1258    /// assert_eq!(p2.num_permits(), 1);
1259    /// ```
1260    pub fn split(&mut self, n: usize) -> Option<Self> {
1261        if n > self.permits {
1262            return None;
1263        }
1264
1265        self.permits -= n;
1266
1267        Some(Self {
1268            sem: self.sem,
1269            permits: n,
1270        })
1271    }
1272
1273    /// Returns the [`Semaphore`] from which this permit was acquired.
1274    pub fn semaphore(&self) -> &Semaphore {
1275        self.sem
1276    }
1277
1278    /// Returns the number of permits held by `self`.
1279    pub fn num_permits(&self) -> usize {
1280        self.permits
1281    }
1282}
1283
1284impl OwnedSemaphorePermit {
1285    /// Forgets the permit **without** releasing it back to the semaphore.
1286    /// This can be used to reduce the amount of permits available from a
1287    /// semaphore.
1288    ///
1289    /// # Examples
1290    ///
1291    /// ```
1292    /// use std::sync::Arc;
1293    /// use tokio::sync::Semaphore;
1294    ///
1295    /// let sem = Arc::new(Semaphore::new(10));
1296    /// {
1297    ///     let permit = sem.clone().try_acquire_many_owned(5).unwrap();
1298    ///     assert_eq!(sem.available_permits(), 5);
1299    ///     permit.forget();
1300    /// }
1301    ///
1302    /// // Since we forgot the permit, available permits won't go back to its initial value
1303    /// // even after the permit is dropped.
1304    /// assert_eq!(sem.available_permits(), 5);
1305    /// ```
1306    pub fn forget(mut self) {
1307        self.permits = 0;
1308    }
1309
1310    /// Merge two [`OwnedSemaphorePermit`] instances together, consuming `other`
1311    /// without releasing the permits it holds.
1312    ///
1313    /// Permits held by both `self` and `other` are released when `self` drops.
1314    ///
1315    /// # Panics
1316    ///
1317    /// This function panics if permits from different [`Semaphore`] instances
1318    /// are merged.
1319    ///
1320    /// # Examples
1321    ///
1322    /// ```
1323    /// use std::sync::Arc;
1324    /// use tokio::sync::Semaphore;
1325    ///
1326    /// let sem = Arc::new(Semaphore::new(10));
1327    /// let mut permit = sem.clone().try_acquire_owned().unwrap();
1328    ///
1329    /// for _ in 0..9 {
1330    ///     let _permit = sem.clone().try_acquire_owned().unwrap();
1331    ///     // Merge individual permits into a single one.
1332    ///     permit.merge(_permit)
1333    /// }
1334    ///
1335    /// assert_eq!(sem.available_permits(), 0);
1336    ///
1337    /// // Release all permits in a single batch.
1338    /// drop(permit);
1339    ///
1340    /// assert_eq!(sem.available_permits(), 10);
1341    /// ```
1342    #[track_caller]
1343    pub fn merge(&mut self, mut other: Self) {
1344        assert!(
1345            Arc::ptr_eq(&self.sem, &other.sem),
1346            "merging permits from different semaphore instances"
1347        );
1348        self.permits = self
1349            .permits
1350            .checked_add(other.permits)
1351            .expect("number of permits overflowed");
1352        other.permits = 0;
1353    }
1354
1355    /// Splits `n` permits from `self` and returns a new [`OwnedSemaphorePermit`] instance that holds `n` permits.
1356    ///
1357    /// If there are insufficient permits and it's not possible to reduce by `n`, returns `None`.
1358    ///
1359    /// # Note
1360    ///
1361    /// It will clone the owned `Arc<Semaphore>` to construct the new instance.
1362    ///
1363    /// # Examples
1364    ///
1365    /// ```
1366    /// use std::sync::Arc;
1367    /// use tokio::sync::Semaphore;
1368    ///
1369    /// let sem = Arc::new(Semaphore::new(3));
1370    ///
1371    /// let mut p1 = sem.try_acquire_many_owned(3).unwrap();
1372    /// let p2 = p1.split(1).unwrap();
1373    ///
1374    /// assert_eq!(p1.num_permits(), 2);
1375    /// assert_eq!(p2.num_permits(), 1);
1376    /// ```
1377    pub fn split(&mut self, n: usize) -> Option<Self> {
1378        if n > self.permits {
1379            return None;
1380        }
1381
1382        self.permits -= n;
1383
1384        Some(Self {
1385            sem: self.sem.clone(),
1386            permits: n,
1387        })
1388    }
1389
1390    /// Returns the [`Semaphore`] from which this permit was acquired.
1391    pub fn semaphore(&self) -> &Arc<Semaphore> {
1392        &self.sem
1393    }
1394
1395    /// Returns the number of permits held by `self`.
1396    pub fn num_permits(&self) -> usize {
1397        self.permits
1398    }
1399}
1400
1401impl Drop for SemaphorePermit<'_> {
1402    fn drop(&mut self) {
1403        self.sem.add_permits(self.permits);
1404    }
1405}
1406
1407impl Drop for OwnedSemaphorePermit {
1408    fn drop(&mut self) {
1409        self.sem.add_permits(self.permits);
1410    }
1411}