From 67b810c9c347caf0fa9e1fa4e7a1cbacabab76cd Mon Sep 17 00:00:00 2001 From: Oguz Bilgener Date: Mon, 24 May 2021 22:40:08 -0400 Subject: [PATCH 01/10] doc: Add examples to --- tokio/src/sync/semaphore.rs | 228 ++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index af75042be05..7316c7056ac 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -24,6 +24,51 @@ use std::sync::Arc; /// To use the `Semaphore` in a poll function, you can use the [`PollSemaphore`] /// utility. /// +/// # Examples +/// +/// ``` +/// use std::sync::Arc; +/// use tokio::sync::{Semaphore, TryAcquireError}; +/// +/// #[tokio::main] +/// async fn main() { +/// let semaphore = Semaphore::new(3); +/// { +/// let a_permit = semaphore.acquire().await; +/// let two_permits = semaphore.acquire_many(2).await; +/// assert_eq!(a_permit.is_ok(), true); +/// assert_eq!(two_permits.is_ok(), true); +/// // all three permits acquired without waiting +/// assert_eq!(semaphore.available_permits(), 0); +/// // any more `acquire()` or `acquire_many()` calls will wait +/// // `try_acquire` attempts to acquire, but fail immediately in this case +/// let fourth_permit = semaphore.try_acquire(); +/// assert_eq!(fourth_permit.err(), Some(TryAcquireError::NoPermits)); +/// semaphore.close(); +/// // cannot obtain more permits after close +/// assert_eq!(semaphore.acquire().await.is_err(), true); +/// } // all permits are dropped at this point +/// assert_eq!(semaphore.available_permits(), 3); +/// +/// // wrap a semaphore in [`Arc`] to share a semaphore across tasks +/// // use [`acquire_owned`] to move permits across tasks +/// let semaphore = Arc::new(Semaphore::new(3)); +/// let mut join_handles = Vec::new(); +/// for _ in 1..=5 { +/// let permit = semaphore.clone().acquire_owned().await.unwrap(); +/// join_handles.push(tokio::spawn(async move { +/// // perform task... +/// // explicitly own `permit` in the task +/// drop(permit); +/// })); +/// } +/// assert_eq!(join_handles.len(), 5); +/// for j in join_handles { +/// j.await.unwrap(); +/// } +/// } +/// ``` +/// /// [`PollSemaphore`]: https://docs.rs/tokio-util/0.6/tokio_util/sync/struct.PollSemaphore.html #[derive(Debug)] pub struct Semaphore { @@ -105,6 +150,25 @@ impl Semaphore { /// Otherwise, this returns a [`SemaphorePermit`] representing the /// acquired permit. /// + /// # Examples + /// + ///``` + /// use tokio::sync::Semaphore; + /// + /// #[tokio::main] + /// async fn main() { + /// let semaphore = Semaphore::new(2); + /// let p1 = semaphore.acquire().await; + /// let p2 = semaphore.acquire().await; + /// assert_eq!(p1.is_ok(), true); + /// assert_eq!(p2.is_ok(), true); + /// assert_eq!(semaphore.available_permits(), 0); + /// semaphore.close(); + /// let p3 = semaphore.acquire().await; + /// assert_eq!(p3.is_err(), true); + /// } + /// ``` + /// /// [`AcquireError`]: crate::sync::AcquireError /// [`SemaphorePermit`]: crate::sync::SemaphorePermit pub async fn acquire(&self) -> Result, AcquireError> { @@ -121,6 +185,25 @@ impl Semaphore { /// Otherwise, this returns a [`SemaphorePermit`] representing the /// acquired permits. /// + /// # Examples + /// + ///``` + /// use tokio::sync::Semaphore; + /// + /// #[tokio::main] + /// async fn main() { + /// let semaphore = Semaphore::new(5); + /// let p1 = semaphore.acquire_many(3).await; + /// assert_eq!(semaphore.available_permits(), 2); + /// let p2 = semaphore.acquire_many(2).await; + /// assert_eq!(p1.is_ok(), true); + /// assert_eq!(p2.is_ok(), true); + /// semaphore.close(); + /// let p3 = semaphore.acquire_many(99).await; + /// assert_eq!(p3.is_err(), true); + /// } + /// ``` + /// /// [`AcquireError`]: crate::sync::AcquireError /// [`SemaphorePermit`]: crate::sync::SemaphorePermit pub async fn acquire_many(&self, n: u32) -> Result, AcquireError> { @@ -137,6 +220,26 @@ impl Semaphore { /// and a [`TryAcquireError::NoPermits`] if there are no permits left. Otherwise, /// this returns a [`SemaphorePermit`] representing the acquired permits. /// + /// # Examples + /// + ///``` + /// use tokio::sync::{Semaphore, TryAcquireError}; + /// + /// #[tokio::main] + /// async fn main() { + /// let semaphore = Semaphore::new(2); + /// let p1 = semaphore.acquire().await; + /// let p2 = semaphore.try_acquire(); + /// let p3 = semaphore.try_acquire(); + /// assert_eq!(p1.is_ok(), true); + /// assert_eq!(p2.is_ok(), true); + /// assert_eq!(p3.err(), Some(TryAcquireError::NoPermits)); + /// semaphore.close(); + /// let p4 = semaphore.try_acquire(); + /// assert_eq!(p4.err(), Some(TryAcquireError::Closed)); + /// } + /// ``` + /// /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed /// [`TryAcquireError::NoPermits`]: crate::sync::TryAcquireError::NoPermits /// [`SemaphorePermit`]: crate::sync::SemaphorePermit @@ -156,6 +259,25 @@ impl Semaphore { /// and a [`TryAcquireError::NoPermits`] if there are no permits left. Otherwise, /// this returns a [`SemaphorePermit`] representing the acquired permits. /// + /// # Examples + /// + ///``` + /// use tokio::sync::{Semaphore, TryAcquireError}; + /// + /// #[tokio::main] + /// async fn main() { + /// let semaphore = Semaphore::new(4); + /// let p1 = semaphore.try_acquire_many(3); + /// assert_eq!(semaphore.available_permits(), 1); + /// let p2 = semaphore.try_acquire_many(2); + /// assert_eq!(p1.is_ok(), true); + /// assert_eq!(p2.err(), Some(TryAcquireError::NoPermits)); + /// semaphore.close(); + /// let p3 = semaphore.try_acquire_many(99); + /// assert_eq!(p3.err(), Some(TryAcquireError::Closed)); + /// } + /// ``` + /// /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed /// [`TryAcquireError::NoPermits`]: crate::sync::TryAcquireError::NoPermits /// [`SemaphorePermit`]: crate::sync::SemaphorePermit @@ -176,6 +298,32 @@ impl Semaphore { /// Otherwise, this returns a [`OwnedSemaphorePermit`] representing the /// acquired permit. /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// use tokio::sync::Semaphore; + /// + /// #[tokio::main] + /// async fn main() { + /// let semaphore = Arc::new(Semaphore::new(2)); + /// let sem_clone = semaphore.clone(); + /// let handle = tokio::spawn(async move { + /// let permit = sem_clone.acquire_owned().await; + /// assert_eq!(permit.is_ok(), true); + /// }); + /// { + /// let p1 = semaphore.clone().acquire_owned().await; + /// assert_eq!(semaphore.available_permits(), 1); + /// let p2 = semaphore.clone().acquire_owned().await; + /// assert_eq!(semaphore.available_permits(), 0); + /// assert_eq!(p1.is_ok(), true); + /// assert_eq!(p2.is_ok(), true); + /// } // release the permits so the task can acquire them + /// handle.await.unwrap(); + /// } + /// ``` + /// /// [`Arc`]: std::sync::Arc /// [`AcquireError`]: crate::sync::AcquireError /// [`OwnedSemaphorePermit`]: crate::sync::OwnedSemaphorePermit @@ -194,6 +342,33 @@ impl Semaphore { /// Otherwise, this returns a [`OwnedSemaphorePermit`] representing the /// acquired permit. /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// use tokio::sync::Semaphore; + /// + /// #[tokio::main] + /// async fn main() { + /// let semaphore = Arc::new(Semaphore::new(5)); + /// let sem_clone = semaphore.clone(); + /// let handle = tokio::spawn(async move { + /// let permit = sem_clone.acquire_many_owned(5).await; + /// assert_eq!(permit.is_ok(), true); + /// }); + /// { + /// let p1 = semaphore.clone().acquire_many_owned(2).await; + /// assert_eq!(semaphore.available_permits(), 3); + /// let p2 = semaphore.clone().acquire_owned().await; + /// assert_eq!(semaphore.available_permits(), 2); + /// assert_eq!(p1.is_ok(), true); + /// assert_eq!(p2.is_ok(), true); + /// } // release the permits so the task can acquire them + /// handle.await.unwrap(); + /// } + /// ``` + /// + /// /// [`Arc`]: std::sync::Arc /// [`AcquireError`]: crate::sync::AcquireError /// [`OwnedSemaphorePermit`]: crate::sync::OwnedSemaphorePermit @@ -216,6 +391,34 @@ impl Semaphore { /// Otherwise, this returns a [`OwnedSemaphorePermit`] representing the /// acquired permit. /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// use tokio::sync::{Semaphore, TryAcquireError}; + /// + /// #[tokio::main] + /// async fn main() { + /// let semaphore = Arc::new(Semaphore::new(2)); + /// let sem_clone = semaphore.clone(); + /// let handle = tokio::spawn(async move { + /// let permit = sem_clone.try_acquire_owned(); + /// assert_eq!(permit.is_ok(), true); + /// }); + /// { + /// let p1 = semaphore.clone().try_acquire_owned(); + /// assert_eq!(semaphore.available_permits(), 1); + /// let p2 = semaphore.clone().try_acquire_owned(); + /// assert_eq!(semaphore.available_permits(), 0); + /// let p3 = semaphore.clone().try_acquire_owned(); + /// assert_eq!(p1.is_ok(), true); + /// assert_eq!(p2.is_ok(), true); + /// assert_eq!(p3.err(), Some(TryAcquireError::NoPermits)); + /// } // release the permits so the task can acquire them + /// handle.await.unwrap(); + /// } + /// ``` + /// /// [`Arc`]: std::sync::Arc /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed /// [`TryAcquireError::NoPermits`]: crate::sync::TryAcquireError::NoPermits @@ -238,6 +441,31 @@ impl Semaphore { /// Otherwise, this returns a [`OwnedSemaphorePermit`] representing the /// acquired permit. /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// use tokio::sync::{Semaphore, TryAcquireError}; + /// + /// #[tokio::main] + /// async fn main() { + /// let semaphore = Arc::new(Semaphore::new(5)); + /// let sem_clone = semaphore.clone(); + /// let handle = tokio::spawn(async move { + /// let permit = sem_clone.try_acquire_many_owned(5); + /// assert_eq!(permit.is_ok(), true); + /// }); + /// { + /// let p1 = semaphore.clone().try_acquire_many_owned(3); + /// assert_eq!(semaphore.available_permits(), 2); + /// let p2 = semaphore.clone().try_acquire_many_owned(99); + /// assert_eq!(p1.is_ok(), true); + /// assert_eq!(p2.err(), Some(TryAcquireError::NoPermits)); + /// } // release the permits so the task can acquire them + /// handle.await.unwrap(); + /// } + /// ``` + /// /// [`Arc`]: std::sync::Arc /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed /// [`TryAcquireError::NoPermits`]: crate::sync::TryAcquireError::NoPermits From fcd40df37379413cabc5fad883cff96d977b8a6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Bilgener?= Date: Wed, 26 May 2021 15:24:06 -0400 Subject: [PATCH 02/10] Apply suggestions from code review Co-authored-by: Alice Ryhl --- tokio/src/sync/semaphore.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 7316c7056ac..178dc682dc9 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -158,14 +158,15 @@ impl Semaphore { /// #[tokio::main] /// async fn main() { /// let semaphore = Semaphore::new(2); - /// let p1 = semaphore.acquire().await; - /// let p2 = semaphore.acquire().await; - /// assert_eq!(p1.is_ok(), true); - /// assert_eq!(p2.is_ok(), true); + /// + /// let permit_1 = semaphore.acquire().await.unwrap(); + /// assert_eq!(semaphore.available_permits(), 1); + /// + /// let permit_2 = semaphore.acquire().await.unwrap(); /// assert_eq!(semaphore.available_permits(), 0); - /// semaphore.close(); - /// let p3 = semaphore.acquire().await; - /// assert_eq!(p3.is_err(), true); + /// + /// drop(permit_1); + /// assert_eq!(semaphore.available_permits(), 1); /// } /// ``` /// From d22c439705fb95af2d92ef13b012e03c0b77c471 Mon Sep 17 00:00:00 2001 From: Oguz Bilgener Date: Wed, 26 May 2021 16:52:44 -0400 Subject: [PATCH 03/10] Simplify per the code review --- tokio/src/sync/semaphore.rs | 218 ++++++++++++++++++------------------ 1 file changed, 111 insertions(+), 107 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 178dc682dc9..0da4680fa82 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -27,33 +27,33 @@ use std::sync::Arc; /// # Examples /// /// ``` -/// use std::sync::Arc; /// use tokio::sync::{Semaphore, TryAcquireError}; /// /// #[tokio::main] /// async fn main() { /// let semaphore = Semaphore::new(3); -/// { -/// let a_permit = semaphore.acquire().await; -/// let two_permits = semaphore.acquire_many(2).await; -/// assert_eq!(a_permit.is_ok(), true); -/// assert_eq!(two_permits.is_ok(), true); -/// // all three permits acquired without waiting -/// assert_eq!(semaphore.available_permits(), 0); -/// // any more `acquire()` or `acquire_many()` calls will wait -/// // `try_acquire` attempts to acquire, but fail immediately in this case -/// let fourth_permit = semaphore.try_acquire(); -/// assert_eq!(fourth_permit.err(), Some(TryAcquireError::NoPermits)); -/// semaphore.close(); -/// // cannot obtain more permits after close -/// assert_eq!(semaphore.acquire().await.is_err(), true); -/// } // all permits are dropped at this point -/// assert_eq!(semaphore.available_permits(), 3); /// -/// // wrap a semaphore in [`Arc`] to share a semaphore across tasks -/// // use [`acquire_owned`] to move permits across tasks +/// let a_permit = semaphore.acquire().await.unwrap(); +/// let two_permits = semaphore.acquire_many(2).await.unwrap(); +/// +/// assert_eq!(semaphore.available_permits(), 0); +/// +/// let permit_attempt = semaphore.try_acquire(); +/// assert_eq!(permit_attempt.err(), Some(TryAcquireError::NoPermits)); +/// } +/// ``` +/// +/// Use [`Semaphore::acquire_owned`] to move permits across tasks: +/// +/// ``` +/// use std::sync::Arc; +/// use tokio::sync::Semaphore; +/// +/// #[tokio::main] +/// async fn main() { /// let semaphore = Arc::new(Semaphore::new(3)); /// let mut join_handles = Vec::new(); +/// /// for _ in 1..=5 { /// let permit = semaphore.clone().acquire_owned().await.unwrap(); /// join_handles.push(tokio::spawn(async move { @@ -62,7 +62,7 @@ use std::sync::Arc; /// drop(permit); /// })); /// } -/// assert_eq!(join_handles.len(), 5); +/// /// for j in join_handles { /// j.await.unwrap(); /// } @@ -70,6 +70,7 @@ use std::sync::Arc; /// ``` /// /// [`PollSemaphore`]: https://docs.rs/tokio-util/0.6/tokio_util/sync/struct.PollSemaphore.html +/// [`Semaphore::acquire_owned`]: crate::sync::Semaphore::acquire_owned #[derive(Debug)] pub struct Semaphore { /// The low level semaphore @@ -124,6 +125,15 @@ impl Semaphore { } /// Creates a new semaphore with the initial number of permits. + /// + /// # Examples + /// + /// ``` + /// use tokio::sync::Semaphore; + /// + /// static SEM: Semaphore = Semaphore::const_new(10); + /// ``` + /// #[cfg(all(feature = "parking_lot", not(all(loom, test))))] #[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))] pub const fn const_new(permits: usize) -> Self { @@ -194,14 +204,9 @@ impl Semaphore { /// #[tokio::main] /// async fn main() { /// let semaphore = Semaphore::new(5); - /// let p1 = semaphore.acquire_many(3).await; + /// + /// let p1 = semaphore.acquire_many(3).await.unwrap(); /// assert_eq!(semaphore.available_permits(), 2); - /// let p2 = semaphore.acquire_many(2).await; - /// assert_eq!(p1.is_ok(), true); - /// assert_eq!(p2.is_ok(), true); - /// semaphore.close(); - /// let p3 = semaphore.acquire_many(99).await; - /// assert_eq!(p3.is_err(), true); /// } /// ``` /// @@ -224,20 +229,20 @@ impl Semaphore { /// # Examples /// ///``` - /// use tokio::sync::{Semaphore, TryAcquireError}; + /// use tokio::sync::Semaphore; /// /// #[tokio::main] /// async fn main() { /// let semaphore = Semaphore::new(2); - /// let p1 = semaphore.acquire().await; - /// let p2 = semaphore.try_acquire(); - /// let p3 = semaphore.try_acquire(); - /// assert_eq!(p1.is_ok(), true); - /// assert_eq!(p2.is_ok(), true); - /// assert_eq!(p3.err(), Some(TryAcquireError::NoPermits)); - /// semaphore.close(); - /// let p4 = semaphore.try_acquire(); - /// assert_eq!(p4.err(), Some(TryAcquireError::Closed)); + /// + /// let permit_1 = semaphore.try_acquire().unwrap(); + /// assert_eq!(semaphore.available_permits(), 1); + /// + /// let permit_2 = semaphore.try_acquire().unwrap(); + /// assert_eq!(semaphore.available_permits(), 0); + /// + /// drop(permit_1); + /// assert_eq!(semaphore.available_permits(), 1); /// } /// ``` /// @@ -268,14 +273,12 @@ impl Semaphore { /// #[tokio::main] /// async fn main() { /// let semaphore = Semaphore::new(4); - /// let p1 = semaphore.try_acquire_many(3); + /// + /// let permit_1 = semaphore.try_acquire_many(3).unwrap(); /// assert_eq!(semaphore.available_permits(), 1); - /// let p2 = semaphore.try_acquire_many(2); - /// assert_eq!(p1.is_ok(), true); - /// assert_eq!(p2.err(), Some(TryAcquireError::NoPermits)); - /// semaphore.close(); - /// let p3 = semaphore.try_acquire_many(99); - /// assert_eq!(p3.err(), Some(TryAcquireError::Closed)); + /// + /// let permit_2 = semaphore.try_acquire_many(2); + /// assert_eq!(permit_2.err(), Some(TryAcquireError::NoPermits)); /// } /// ``` /// @@ -307,21 +310,21 @@ impl Semaphore { /// /// #[tokio::main] /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(2)); - /// let sem_clone = semaphore.clone(); - /// let handle = tokio::spawn(async move { - /// let permit = sem_clone.acquire_owned().await; - /// assert_eq!(permit.is_ok(), true); - /// }); - /// { - /// let p1 = semaphore.clone().acquire_owned().await; - /// assert_eq!(semaphore.available_permits(), 1); - /// let p2 = semaphore.clone().acquire_owned().await; - /// assert_eq!(semaphore.available_permits(), 0); - /// assert_eq!(p1.is_ok(), true); - /// assert_eq!(p2.is_ok(), true); - /// } // release the permits so the task can acquire them - /// handle.await.unwrap(); + /// let semaphore = Arc::new(Semaphore::new(3)); + /// let mut join_handles = Vec::new(); + /// + /// for _ in 1..=5 { + /// let permit = semaphore.clone().acquire_owned().await.unwrap(); + /// join_handles.push(tokio::spawn(async move { + /// // perform task... + /// // explicitly own `permit` in the task + /// drop(permit); + /// })); + /// } + /// + /// for j in join_handles { + /// j.await.unwrap(); + /// } /// } /// ``` /// @@ -351,21 +354,21 @@ impl Semaphore { /// /// #[tokio::main] /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(5)); - /// let sem_clone = semaphore.clone(); - /// let handle = tokio::spawn(async move { - /// let permit = sem_clone.acquire_many_owned(5).await; - /// assert_eq!(permit.is_ok(), true); - /// }); - /// { - /// let p1 = semaphore.clone().acquire_many_owned(2).await; - /// assert_eq!(semaphore.available_permits(), 3); - /// let p2 = semaphore.clone().acquire_owned().await; - /// assert_eq!(semaphore.available_permits(), 2); - /// assert_eq!(p1.is_ok(), true); - /// assert_eq!(p2.is_ok(), true); - /// } // release the permits so the task can acquire them - /// handle.await.unwrap(); + /// let semaphore = Arc::new(Semaphore::new(15)); + /// let mut join_handles = Vec::new(); + /// + /// for i in 1..=5 { + /// let permit = semaphore.clone().acquire_many_owned(i).await.unwrap(); + /// join_handles.push(tokio::spawn(async move { + /// // perform task... + /// // explicitly own `permit` in the task + /// drop(permit); + /// })); + /// } + /// + /// for j in join_handles { + /// j.await.unwrap(); + /// } /// } /// ``` /// @@ -396,27 +399,26 @@ impl Semaphore { /// /// ``` /// use std::sync::Arc; - /// use tokio::sync::{Semaphore, TryAcquireError}; + /// use tokio::sync::Semaphore; /// /// #[tokio::main] /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(2)); - /// let sem_clone = semaphore.clone(); - /// let handle = tokio::spawn(async move { - /// let permit = sem_clone.try_acquire_owned(); - /// assert_eq!(permit.is_ok(), true); - /// }); - /// { - /// let p1 = semaphore.clone().try_acquire_owned(); - /// assert_eq!(semaphore.available_permits(), 1); - /// let p2 = semaphore.clone().try_acquire_owned(); - /// assert_eq!(semaphore.available_permits(), 0); - /// let p3 = semaphore.clone().try_acquire_owned(); - /// assert_eq!(p1.is_ok(), true); - /// assert_eq!(p2.is_ok(), true); - /// assert_eq!(p3.err(), Some(TryAcquireError::NoPermits)); - /// } // release the permits so the task can acquire them - /// handle.await.unwrap(); + /// // use [`acquire_owned`] to move permits across tasks + /// let semaphore = Arc::new(Semaphore::new(5)); + /// let mut join_handles = Vec::new(); + /// + /// for _ in 1..=5 { + /// let permit = semaphore.clone().try_acquire_owned().unwrap(); + /// join_handles.push(tokio::spawn(async move { + /// // perform task... + /// // explicitly own `permit` in the task + /// drop(permit); + /// })); + /// } + /// + /// for j in join_handles { + /// j.await.unwrap(); + /// } /// } /// ``` /// @@ -446,24 +448,26 @@ impl Semaphore { /// /// ``` /// use std::sync::Arc; - /// use tokio::sync::{Semaphore, TryAcquireError}; + /// use tokio::sync::Semaphore; /// /// #[tokio::main] /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(5)); - /// let sem_clone = semaphore.clone(); - /// let handle = tokio::spawn(async move { - /// let permit = sem_clone.try_acquire_many_owned(5); - /// assert_eq!(permit.is_ok(), true); - /// }); - /// { - /// let p1 = semaphore.clone().try_acquire_many_owned(3); - /// assert_eq!(semaphore.available_permits(), 2); - /// let p2 = semaphore.clone().try_acquire_many_owned(99); - /// assert_eq!(p1.is_ok(), true); - /// assert_eq!(p2.err(), Some(TryAcquireError::NoPermits)); - /// } // release the permits so the task can acquire them - /// handle.await.unwrap(); + /// // use [`acquire_owned`] to move permits across tasks + /// let semaphore = Arc::new(Semaphore::new(15)); + /// let mut join_handles = Vec::new(); + /// + /// for i in 1..=5 { + /// let permit = semaphore.clone().try_acquire_many_owned(i).unwrap(); + /// join_handles.push(tokio::spawn(async move { + /// // perform task... + /// // explicitly own `permit` in the task + /// drop(permit); + /// })); + /// } + /// + /// for j in join_handles { + /// j.await.unwrap(); + /// } /// } /// ``` /// From f2f7f060d916fff0cc3266c1145518e01fe86519 Mon Sep 17 00:00:00 2001 From: Oguz Bilgener Date: Wed, 26 May 2021 17:16:36 -0400 Subject: [PATCH 04/10] Cleanup --- tokio/src/sync/semaphore.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 0da4680fa82..bb0f50d4073 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -26,6 +26,8 @@ use std::sync::Arc; /// /// # Examples /// +/// Basic usage: +/// /// ``` /// use tokio::sync::{Semaphore, TryAcquireError}; /// @@ -403,7 +405,6 @@ impl Semaphore { /// /// #[tokio::main] /// async fn main() { - /// // use [`acquire_owned`] to move permits across tasks /// let semaphore = Arc::new(Semaphore::new(5)); /// let mut join_handles = Vec::new(); /// @@ -452,7 +453,6 @@ impl Semaphore { /// /// #[tokio::main] /// async fn main() { - /// // use [`acquire_owned`] to move permits across tasks /// let semaphore = Arc::new(Semaphore::new(15)); /// let mut join_handles = Vec::new(); /// From 5b0a3fa7040a0373696d1f8babc162df94539848 Mon Sep 17 00:00:00 2001 From: Oguz Bilgener Date: Wed, 26 May 2021 18:50:29 -0400 Subject: [PATCH 05/10] Simplify more --- tokio/src/sync/semaphore.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index bb0f50d4073..3203f7f0274 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -231,7 +231,7 @@ impl Semaphore { /// # Examples /// ///``` - /// use tokio::sync::Semaphore; + /// use tokio::sync::{Semaphore, TryAcquireError}; /// /// #[tokio::main] /// async fn main() { @@ -243,8 +243,8 @@ impl Semaphore { /// let permit_2 = semaphore.try_acquire().unwrap(); /// assert_eq!(semaphore.available_permits(), 0); /// - /// drop(permit_1); - /// assert_eq!(semaphore.available_permits(), 1); + /// let permit_3 = semaphore.try_acquire(); + /// assert_eq!(permit_3.err(), Some(TryAcquireError::NoPermits)); /// } /// ``` /// @@ -356,11 +356,11 @@ impl Semaphore { /// /// #[tokio::main] /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(15)); + /// let semaphore = Arc::new(Semaphore::new(10)); /// let mut join_handles = Vec::new(); /// /// for i in 1..=5 { - /// let permit = semaphore.clone().acquire_many_owned(i).await.unwrap(); + /// let permit = semaphore.clone().acquire_many_owned(2).await.unwrap(); /// join_handles.push(tokio::spawn(async move { /// // perform task... /// // explicitly own `permit` in the task @@ -453,11 +453,11 @@ impl Semaphore { /// /// #[tokio::main] /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(15)); + /// let semaphore = Arc::new(Semaphore::new(10)); /// let mut join_handles = Vec::new(); /// /// for i in 1..=5 { - /// let permit = semaphore.clone().try_acquire_many_owned(i).unwrap(); + /// let permit = semaphore.clone().try_acquire_many_owned(2).unwrap(); /// join_handles.push(tokio::spawn(async move { /// // perform task... /// // explicitly own `permit` in the task From 55734540396fcaab88eeb24d11f12225ef8df36b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Bilgener?= Date: Tue, 1 Jun 2021 15:45:54 -0400 Subject: [PATCH 06/10] Apply suggestions from code review Co-authored-by: John-John Tedro --- tokio/src/sync/semaphore.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 3203f7f0274..28f6a17ee57 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -164,7 +164,7 @@ impl Semaphore { /// /// # Examples /// - ///``` + /// ``` /// use tokio::sync::Semaphore; /// /// #[tokio::main] @@ -200,7 +200,7 @@ impl Semaphore { /// /// # Examples /// - ///``` + /// ``` /// use tokio::sync::Semaphore; /// /// #[tokio::main] @@ -230,7 +230,7 @@ impl Semaphore { /// /// # Examples /// - ///``` + /// ``` /// use tokio::sync::{Semaphore, TryAcquireError}; /// /// #[tokio::main] @@ -269,7 +269,7 @@ impl Semaphore { /// /// # Examples /// - ///``` + /// ``` /// use tokio::sync::{Semaphore, TryAcquireError}; /// /// #[tokio::main] @@ -374,7 +374,6 @@ impl Semaphore { /// } /// ``` /// - /// /// [`Arc`]: std::sync::Arc /// [`AcquireError`]: crate::sync::AcquireError /// [`OwnedSemaphorePermit`]: crate::sync::OwnedSemaphorePermit From be537bea2b957b270e763821a869d42521376f56 Mon Sep 17 00:00:00 2001 From: Oguz Bilgener Date: Tue, 1 Jun 2021 16:35:03 -0400 Subject: [PATCH 07/10] Fix a few things --- tokio/src/sync/semaphore.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 28f6a17ee57..d3e4cb626a2 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -65,8 +65,8 @@ use std::sync::Arc; /// })); /// } /// -/// for j in join_handles { -/// j.await.unwrap(); +/// for handle in join_handles { +/// handle.await.unwrap(); /// } /// } /// ``` @@ -324,8 +324,8 @@ impl Semaphore { /// })); /// } /// - /// for j in join_handles { - /// j.await.unwrap(); + /// for handle in join_handles { + /// handle.await.unwrap(); /// } /// } /// ``` @@ -359,7 +359,7 @@ impl Semaphore { /// let semaphore = Arc::new(Semaphore::new(10)); /// let mut join_handles = Vec::new(); /// - /// for i in 1..=5 { + /// for _ in 1..=5 { /// let permit = semaphore.clone().acquire_many_owned(2).await.unwrap(); /// join_handles.push(tokio::spawn(async move { /// // perform task... @@ -368,8 +368,8 @@ impl Semaphore { /// })); /// } /// - /// for j in join_handles { - /// j.await.unwrap(); + /// for handle in join_handles { + /// handle.await.unwrap(); /// } /// } /// ``` @@ -416,8 +416,8 @@ impl Semaphore { /// })); /// } /// - /// for j in join_handles { - /// j.await.unwrap(); + /// for handle in join_handles { + /// handle.await.unwrap(); /// } /// } /// ``` @@ -455,7 +455,7 @@ impl Semaphore { /// let semaphore = Arc::new(Semaphore::new(10)); /// let mut join_handles = Vec::new(); /// - /// for i in 1..=5 { + /// for _ in 1..=5 { /// let permit = semaphore.clone().try_acquire_many_owned(2).unwrap(); /// join_handles.push(tokio::spawn(async move { /// // perform task... @@ -464,8 +464,8 @@ impl Semaphore { /// })); /// } /// - /// for j in join_handles { - /// j.await.unwrap(); + /// for handle in join_handles { + /// handle.await.unwrap(); /// } /// } /// ``` From 26d17a69a9d8cf6bdf8145258d3bb693daf183a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Bilgener?= Date: Wed, 2 Jun 2021 11:10:09 -0400 Subject: [PATCH 08/10] Update tokio/src/sync/semaphore.rs Co-authored-by: Alice Ryhl --- tokio/src/sync/semaphore.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index d3e4cb626a2..2a141c788fb 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -264,8 +264,8 @@ impl Semaphore { /// Tries to acquire `n` permits from the semaphore. /// /// If the semaphore has been closed, this returns a [`TryAcquireError::Closed`] - /// and a [`TryAcquireError::NoPermits`] if there are no permits left. Otherwise, - /// this returns a [`SemaphorePermit`] representing the acquired permits. + /// and a [`TryAcquireError::NoPermits`] if there are not enough permits left. + /// Otherwise, this returns a [`SemaphorePermit`] representing the acquired permits. /// /// # Examples /// From 759b003ca0c830e8ba7ee1e82466f7c39a2a5711 Mon Sep 17 00:00:00 2001 From: Oguz Bilgener Date: Sun, 6 Jun 2021 13:08:06 -0400 Subject: [PATCH 09/10] simplify try owned examples --- tokio/src/sync/semaphore.rs | 51 ++++++++++++++----------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 2a141c788fb..5ff9eadc0fe 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -56,7 +56,7 @@ use std::sync::Arc; /// let semaphore = Arc::new(Semaphore::new(3)); /// let mut join_handles = Vec::new(); /// -/// for _ in 1..=5 { +/// for _ in 0..5 { /// let permit = semaphore.clone().acquire_owned().await.unwrap(); /// join_handles.push(tokio::spawn(async move { /// // perform task... @@ -207,7 +207,7 @@ impl Semaphore { /// async fn main() { /// let semaphore = Semaphore::new(5); /// - /// let p1 = semaphore.acquire_many(3).await.unwrap(); + /// let permit = semaphore.acquire_many(3).await.unwrap(); /// assert_eq!(semaphore.available_permits(), 2); /// } /// ``` @@ -315,7 +315,7 @@ impl Semaphore { /// let semaphore = Arc::new(Semaphore::new(3)); /// let mut join_handles = Vec::new(); /// - /// for _ in 1..=5 { + /// for _ in 0..5 { /// let permit = semaphore.clone().acquire_owned().await.unwrap(); /// join_handles.push(tokio::spawn(async move { /// // perform task... @@ -359,7 +359,7 @@ impl Semaphore { /// let semaphore = Arc::new(Semaphore::new(10)); /// let mut join_handles = Vec::new(); /// - /// for _ in 1..=5 { + /// for _ in 0..5 { /// let permit = semaphore.clone().acquire_many_owned(2).await.unwrap(); /// join_handles.push(tokio::spawn(async move { /// // perform task... @@ -400,25 +400,20 @@ impl Semaphore { /// /// ``` /// use std::sync::Arc; - /// use tokio::sync::Semaphore; + /// use tokio::sync::{Semaphore, TryAcquireError}; /// /// #[tokio::main] /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(5)); - /// let mut join_handles = Vec::new(); + /// let semaphore = Arc::new(Semaphore::new(2)); /// - /// for _ in 1..=5 { - /// let permit = semaphore.clone().try_acquire_owned().unwrap(); - /// join_handles.push(tokio::spawn(async move { - /// // perform task... - /// // explicitly own `permit` in the task - /// drop(permit); - /// })); - /// } + /// let permit_1 = Arc::clone(&semaphore).try_acquire_owned().unwrap(); + /// assert_eq!(semaphore.available_permits(), 1); /// - /// for handle in join_handles { - /// handle.await.unwrap(); - /// } + /// let permit_2 = Arc::clone(&semaphore).try_acquire_owned().unwrap(); + /// assert_eq!(semaphore.available_permits(), 0); + /// + /// let permit_3 = semaphore.try_acquire_owned(); + /// assert_eq!(permit_3.err(), Some(TryAcquireError::NoPermits)); /// } /// ``` /// @@ -448,25 +443,17 @@ impl Semaphore { /// /// ``` /// use std::sync::Arc; - /// use tokio::sync::Semaphore; + /// use tokio::sync::{Semaphore, TryAcquireError}; /// /// #[tokio::main] /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(10)); - /// let mut join_handles = Vec::new(); + /// let semaphore = Arc::new(Semaphore::new(4)); /// - /// for _ in 1..=5 { - /// let permit = semaphore.clone().try_acquire_many_owned(2).unwrap(); - /// join_handles.push(tokio::spawn(async move { - /// // perform task... - /// // explicitly own `permit` in the task - /// drop(permit); - /// })); - /// } + /// let permit_1 = Arc::clone(&semaphore).try_acquire_many_owned(3).unwrap(); + /// assert_eq!(semaphore.available_permits(), 1); /// - /// for handle in join_handles { - /// handle.await.unwrap(); - /// } + /// let permit_2 = semaphore.try_acquire_many_owned(2); + /// assert_eq!(permit_2.err(), Some(TryAcquireError::NoPermits)); /// } /// ``` /// From 90f27e72b2e4e4099f07f5e40246393f1f343173 Mon Sep 17 00:00:00 2001 From: Oguz Bilgener Date: Sun, 6 Jun 2021 16:41:13 -0400 Subject: [PATCH 10/10] remove async main from examples that don't need it --- tokio/src/sync/semaphore.rs | 68 +++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 5ff9eadc0fe..5d42d1c2378 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -233,19 +233,18 @@ impl Semaphore { /// ``` /// use tokio::sync::{Semaphore, TryAcquireError}; /// - /// #[tokio::main] - /// async fn main() { - /// let semaphore = Semaphore::new(2); + /// # fn main() { + /// let semaphore = Semaphore::new(2); /// - /// let permit_1 = semaphore.try_acquire().unwrap(); - /// assert_eq!(semaphore.available_permits(), 1); + /// let permit_1 = semaphore.try_acquire().unwrap(); + /// assert_eq!(semaphore.available_permits(), 1); /// - /// let permit_2 = semaphore.try_acquire().unwrap(); - /// assert_eq!(semaphore.available_permits(), 0); + /// let permit_2 = semaphore.try_acquire().unwrap(); + /// assert_eq!(semaphore.available_permits(), 0); /// - /// let permit_3 = semaphore.try_acquire(); - /// assert_eq!(permit_3.err(), Some(TryAcquireError::NoPermits)); - /// } + /// let permit_3 = semaphore.try_acquire(); + /// assert_eq!(permit_3.err(), Some(TryAcquireError::NoPermits)); + /// # } /// ``` /// /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed @@ -272,16 +271,15 @@ impl Semaphore { /// ``` /// use tokio::sync::{Semaphore, TryAcquireError}; /// - /// #[tokio::main] - /// async fn main() { - /// let semaphore = Semaphore::new(4); + /// # fn main() { + /// let semaphore = Semaphore::new(4); /// - /// let permit_1 = semaphore.try_acquire_many(3).unwrap(); - /// assert_eq!(semaphore.available_permits(), 1); + /// let permit_1 = semaphore.try_acquire_many(3).unwrap(); + /// assert_eq!(semaphore.available_permits(), 1); /// - /// let permit_2 = semaphore.try_acquire_many(2); - /// assert_eq!(permit_2.err(), Some(TryAcquireError::NoPermits)); - /// } + /// let permit_2 = semaphore.try_acquire_many(2); + /// assert_eq!(permit_2.err(), Some(TryAcquireError::NoPermits)); + /// # } /// ``` /// /// [`TryAcquireError::Closed`]: crate::sync::TryAcquireError::Closed @@ -402,19 +400,18 @@ impl Semaphore { /// use std::sync::Arc; /// use tokio::sync::{Semaphore, TryAcquireError}; /// - /// #[tokio::main] - /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(2)); + /// # fn main() { + /// let semaphore = Arc::new(Semaphore::new(2)); /// - /// let permit_1 = Arc::clone(&semaphore).try_acquire_owned().unwrap(); - /// assert_eq!(semaphore.available_permits(), 1); + /// let permit_1 = Arc::clone(&semaphore).try_acquire_owned().unwrap(); + /// assert_eq!(semaphore.available_permits(), 1); /// - /// let permit_2 = Arc::clone(&semaphore).try_acquire_owned().unwrap(); - /// assert_eq!(semaphore.available_permits(), 0); + /// let permit_2 = Arc::clone(&semaphore).try_acquire_owned().unwrap(); + /// assert_eq!(semaphore.available_permits(), 0); /// - /// let permit_3 = semaphore.try_acquire_owned(); - /// assert_eq!(permit_3.err(), Some(TryAcquireError::NoPermits)); - /// } + /// let permit_3 = semaphore.try_acquire_owned(); + /// assert_eq!(permit_3.err(), Some(TryAcquireError::NoPermits)); + /// # } /// ``` /// /// [`Arc`]: std::sync::Arc @@ -445,16 +442,15 @@ impl Semaphore { /// use std::sync::Arc; /// use tokio::sync::{Semaphore, TryAcquireError}; /// - /// #[tokio::main] - /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(4)); + /// # fn main() { + /// let semaphore = Arc::new(Semaphore::new(4)); /// - /// let permit_1 = Arc::clone(&semaphore).try_acquire_many_owned(3).unwrap(); - /// assert_eq!(semaphore.available_permits(), 1); + /// let permit_1 = Arc::clone(&semaphore).try_acquire_many_owned(3).unwrap(); + /// assert_eq!(semaphore.available_permits(), 1); /// - /// let permit_2 = semaphore.try_acquire_many_owned(2); - /// assert_eq!(permit_2.err(), Some(TryAcquireError::NoPermits)); - /// } + /// let permit_2 = semaphore.try_acquire_many_owned(2); + /// assert_eq!(permit_2.err(), Some(TryAcquireError::NoPermits)); + /// # } /// ``` /// /// [`Arc`]: std::sync::Arc