pub struct Semaphore { /* private fields */ }
Expand description
An async counting semaphore for controlling access to a set of resources.
See the module level documentation for more.
Implementations§
Source§impl Semaphore
impl Semaphore
Sourcepub fn new(permits: usize) -> Self
pub fn new(permits: usize) -> Self
Creates a new semaphore with the given number of permits.
§Examples
use mea::semaphore::Semaphore;
let sem = Semaphore::new(5); // Creates a semaphore with 5 permits
Sourcepub fn available_permits(&self) -> usize
pub fn available_permits(&self) -> usize
Returns the current number of permits available.
§Examples
use mea::semaphore::Semaphore;
let sem = Semaphore::new(2);
assert_eq!(sem.available_permits(), 2);
let permit = sem.try_acquire(1).unwrap();
assert_eq!(sem.available_permits(), 1);
Sourcepub fn forget(&self, n: usize) -> usize
pub fn forget(&self, n: usize) -> usize
Reduces the semaphore’s permits by a maximum of n
.
Returns the actual number of permits that were reduced. This may be less
than n
if there are insufficient permits available.
This is useful when you want to permanently remove permits from the semaphore.
§Examples
use mea::semaphore::Semaphore;
let sem = Semaphore::new(5);
assert_eq!(sem.forget(3), 3); // Removes 3 permits
assert_eq!(sem.available_permits(), 2);
// Trying to forget more permits than available
assert_eq!(sem.forget(3), 2); // Only removes remaining 2 permits
assert_eq!(sem.available_permits(), 0);
Sourcepub fn forget_exact(&self, n: usize)
pub fn forget_exact(&self, n: usize)
Reduces the semaphore’s permits by exactly n
.
If the semaphore has not enough permits, this would enqueue front an empty waiter to
consume the permits, which ensures the permits are reduced by exactly n
.
This is useful when you want to permanently remove permits from the semaphore.
§Examples
use mea::semaphore::Semaphore;
let sem = Semaphore::new(5);
sem.forget_exact(3); // Removes 3 permits
assert_eq!(sem.available_permits(), 2);
// Trying to forget more permits than available
sem.forget_exact(3); // Only removes remaining 2 permits
assert_eq!(sem.available_permits(), 0);
sem.release(5); // Adds 5 permits
assert_eq!(sem.available_permits(), 4); // Only 4 permits are available
Sourcepub fn try_acquire(&self, permits: usize) -> Option<SemaphorePermit<'_>>
pub fn try_acquire(&self, permits: usize) -> Option<SemaphorePermit<'_>>
Attempts to acquire n
permits from the semaphore without blocking.
If the permits are successfully acquired, a SemaphorePermit
is returned.
The permits will be automatically returned to the semaphore when the permit
is dropped, unless forget
is called.
§Examples
use mea::semaphore::Semaphore;
let sem = Semaphore::new(2);
// First acquisition succeeds
let permit1 = sem.try_acquire(1).unwrap();
assert_eq!(sem.available_permits(), 1);
// Second acquisition succeeds
let permit2 = sem.try_acquire(1).unwrap();
assert_eq!(sem.available_permits(), 0);
// Third acquisition fails
assert!(sem.try_acquire(1).is_none());
Sourcepub fn try_acquire_and_forget(&self, permits: usize) -> bool
pub fn try_acquire_and_forget(&self, permits: usize) -> bool
Attempts to acquire n
permits from the semaphore without blocking.
This method performs as a combinator of Semaphore::try_acquire
and
Semaphore::forget
.
Sourcepub async fn acquire(&self, permits: usize) -> SemaphorePermit<'_>
pub async fn acquire(&self, permits: usize) -> SemaphorePermit<'_>
Acquires n
permits from the semaphore.
If the permits are not immediately available, this method will wait until they become
available. Returns a SemaphorePermit
that will release the permits when dropped.
§Cancel safety
This method uses a queue to fairly distribute permits in the order they were requested.
Cancelling a call to acquire
makes you lose your place in the queue.
§Examples
use std::sync::Arc;
use mea::semaphore::Semaphore;
let sem = Arc::new(Semaphore::new(2));
let sem2 = sem.clone();
let handle = tokio::spawn(async move {
let permit = sem2.acquire(1).await;
// Do some work with the permit.
// Permit is automatically released when dropped.
});
let permit = sem.acquire(1).await;
// Do some work with the permit
drop(permit); // Explicitly release the permit
handle.await.unwrap();
Sourcepub async fn acquire_and_forget(&self, permits: usize)
pub async fn acquire_and_forget(&self, permits: usize)
Acquires n
permits from the semaphore.
This method performs as a combinator of Semaphore::acquire
and
Semaphore::forget
.
Sourcepub fn try_acquire_owned(
self: Arc<Self>,
permits: usize,
) -> Option<OwnedSemaphorePermit>
pub fn try_acquire_owned( self: Arc<Self>, permits: usize, ) -> Option<OwnedSemaphorePermit>
Attempts to acquire n
permits from the semaphore without blocking.
The semaphore must be wrapped in an Arc
to call this method.
If the permits are successfully acquired, a OwnedSemaphorePermit
is returned.
The permits will be automatically returned to the semaphore when the permit
is dropped, unless forget
is called.
§Examples
use std::sync::Arc;
use mea::semaphore::Semaphore;
let sem = Arc::new(Semaphore::new(2));
let p1 = sem.clone().try_acquire_owned(1).unwrap();
assert_eq!(sem.available_permits(), 1);
let p2 = sem.clone().try_acquire_owned(1).unwrap();
assert_eq!(sem.available_permits(), 0);
let p3 = sem.try_acquire_owned(1);
assert!(p3.is_none());
Sourcepub fn try_acquire_owned_and_forget(self: Arc<Self>, permits: usize) -> bool
pub fn try_acquire_owned_and_forget(self: Arc<Self>, permits: usize) -> bool
Attempts to acquire n
permits from the semaphore without blocking.
The semaphore must be wrapped in an Arc
to call this method.
This method performs as a combinator of Semaphore::try_acquire_owned
and
Semaphore::forget
.
Sourcepub async fn acquire_owned(
self: Arc<Self>,
permits: usize,
) -> OwnedSemaphorePermit
pub async fn acquire_owned( self: Arc<Self>, permits: usize, ) -> OwnedSemaphorePermit
Acquires n
permits from the semaphore.
The semaphore must be wrapped in an Arc
to call this method.
If the permits are not immediately available, this method will wait until they become
available. Returns a OwnedSemaphorePermit
that will release the permits when dropped.
§Cancel safety
This method uses a queue to fairly distribute permits in the order they were requested.
Cancelling a call to acquire_owned
makes you lose your place in the queue.
§Examples
use std::sync::Arc;
use mea::semaphore::Semaphore;
let sem = Arc::new(Semaphore::new(3));
let mut join_handles = Vec::new();
for _ in 0..5 {
let permit = sem.clone().acquire_owned(1).await;
join_handles.push(tokio::spawn(async move {
// perform task...
// explicitly own `permit` in the task
drop(permit);
}));
}
for handle in join_handles {
handle.await.unwrap();
}
Sourcepub async fn acquire_owned_and_forget(self: Arc<Self>, permits: usize)
pub async fn acquire_owned_and_forget(self: Arc<Self>, permits: usize)
Acquires n
permits from the semaphore.
The semaphore must be wrapped in an Arc
to call this method.
This method performs as a combinator of Semaphore::acquire_owned
and
Semaphore::forget
.