Struct Semaphore

Source
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

Source

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
Source

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);
Source

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);
Source

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
Source

pub fn release(&self, permits: usize)

Adds n new permits to the semaphore.

§Panics

Panics if adding the permits would cause the total number of permits to overflow.

§Examples
use mea::semaphore::Semaphore;

let sem = Semaphore::new(0);
sem.release(2); // Adds 2 permits
assert_eq!(sem.available_permits(), 2);
Source

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());
Source

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.

Source

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();
Source

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.

Source

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());
Source

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.

Source

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();
}
Source

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.

Trait Implementations§

Source§

impl Debug for Semaphore

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.