pub struct Semaphore<P: Priority, Q: SemaphoreQueue<P> = DefaultSemaphoreQueue<P>>(/* private fields */);Expand description
An async semaphore where queued waiters are granted permits by order of priority.
With the evict flag enabled, existing handles will be requested to return their permits back
to the queue (which may be echecked / waited for via evicted)
Note that to minimize waiting, requesters with the same priority will additionally be sorted by permit count (lowest first). If this isn’t desireable, use a Priority wraper like FIFO or LIFO. This makes it so requesters won’t be blocked by larger requests with the same priority.
The default queue used may change, however its characteristics will remain the same, notably:
Implementations§
Source§impl<P: Priority, Q: SemaphoreQueue<P>> Semaphore<P, Q>
impl<P: Priority, Q: SemaphoreQueue<P>> Semaphore<P, Q>
Sourcepub const fn const_new(permits: usize) -> Selfwhere
Q: ConstDefault,
pub const fn const_new(permits: usize) -> Selfwhere
Q: ConstDefault,
Create a new semaphore with permits permits available. Usable for const if the
underlying queue is ConstDefault and the const-default feature is enabled.
All builtin queues impl ConstDefault.
Sourcepub fn acquire(
&self,
priority: P,
) -> impl Future<Output = SemaphorePermit<'_, P, Q>>
pub fn acquire( &self, priority: P, ) -> impl Future<Output = SemaphorePermit<'_, P, Q>>
Acquire a single permit, waiting if necessary. Permits will be issued by order of priority.
Sourcepub fn acquire_from(
&self,
priority: impl Into<P>,
) -> impl Future<Output = SemaphorePermit<'_, P, Q>>
pub fn acquire_from( &self, priority: impl Into<P>, ) -> impl Future<Output = SemaphorePermit<'_, P, Q>>
Acquire a single permit, waiting if necessary.
Shorthand for acquire(priority.into()).
Cancel Safety: This function is cancel safe.
Sourcepub fn acquire_default(&self) -> impl Future<Output = SemaphorePermit<'_, P, Q>>where
P: Default,
pub fn acquire_default(&self) -> impl Future<Output = SemaphorePermit<'_, P, Q>>where
P: Default,
Acquire a permit with the Default priority.
Shorthand for acquire with Default::default().
Cancel Safety: This function is cancel safe.
Sourcepub async fn acquire_many(
&self,
priority: P,
count: usize,
) -> SemaphorePermit<'_, P, Q>
pub async fn acquire_many( &self, priority: P, count: usize, ) -> SemaphorePermit<'_, P, Q>
Acquire multiple permits, waiting if necessary. Permits will be issued by order of priority. Lower priority waiters will be blocked until all requested permits are acquired (and subsequently released).
Panics if count >= MAX_PERMITS (usize::MAX >> 1).
Cancel Safety: This function is cancel safe.
Sourcepub async fn acquire_many_default(
&self,
count: usize,
) -> impl Future<Output = SemaphorePermit<'_, P, Q>>where
P: Default,
pub async fn acquire_many_default(
&self,
count: usize,
) -> impl Future<Output = SemaphorePermit<'_, P, Q>>where
P: Default,
Acquire multiple permits with the Default priority.
Panics if count >= MAX_PERMITS (usize::MAX >> 1).
Shorthand for acquire_many with Default::default().
Cancel Safety: This function is cancel safe.
Sourcepub async fn acquire_many_from(
&self,
count: usize,
priority: impl Into<P>,
) -> impl Future<Output = SemaphorePermit<'_, P, Q>>where
P: Default,
pub async fn acquire_many_from(
&self,
count: usize,
priority: impl Into<P>,
) -> impl Future<Output = SemaphorePermit<'_, P, Q>>where
P: Default,
Acquire multiple permits with the .
Panics if count >= MAX_PERMITS (usize::MAX >> 1).
Shorthand for acquire_many with priority.into().
Cancel Safety: This function is cancel safe.
Sourcepub async fn acquire_within_total(
&self,
priority: P,
count: usize,
) -> Result<SemaphorePermit<'_, P, Q>, InsufficientPermitsError>
pub async fn acquire_within_total( &self, priority: P, count: usize, ) -> Result<SemaphorePermit<'_, P, Q>, InsufficientPermitsError>
Acquire count permits without blocking the queue if the requested count of permits is
more than the total associated. If the semaphore lacks sufficient associated permits or loses
them while waiting, this returns an InsufficientPermitsError.
Example:
let sem = Semaphore::<usize>::new(10);
let permit = sem.acquire(0).await;
// try to acquire 10 permits
let mut many_permits_fut = pin!(sem.acquire_within_total(1, 10));
tokio::select! {
_ = tokio::time::sleep(Duration::from_secs(1)) => {},
// can't happen
_ = many_permits_fut.as_mut() => { panic!("total of 11 tokens held")},
};
// remove 1 permit from the semaphore
permit.forget();
assert!(many_permits_fut.await.is_err());Cancel Safety: This function is cancel safe.
Sourcepub fn add_permits(&self, count: usize) -> usize
pub fn add_permits(&self, count: usize) -> usize
Add permits to the semaphore.
Panics if:
- The count of permits to add would overflow available
- (if the
semaphore-totalfeature is enabled) The count of permits plus the current total would overflow.
Use try_add_permits if overflows may occur.
Note that if the semaphore-total feature isn’t enabled, the sum of permits issued + permits
available can exceed the max usize and overflow. If an owned permit is dropped and would cause an
overflow when adding held permits back to available, it will panic. The semaphore itself
will remain usable, however the permits will be discarded.
For compatibility, it’s best to assume that it’s unsafe to exceed usize::MAX permits
associated with a semaphore, even if the semaphore-total flag isn’t enabled (as other
crates may require it) (associated permi.ts being available + sum of permits issued)
Sourcepub fn total_permits(&self) -> usize
pub fn total_permits(&self) -> usize
Returns the capacity / total count of permits associated with the semaphore..
Sourcepub fn available_permits(&self) -> usize
pub fn available_permits(&self) -> usize
Returns the amount of currently available permits.
Sourcepub fn try_add_permits(&self, count: usize) -> Result<usize, ()>
pub fn try_add_permits(&self, count: usize) -> Result<usize, ()>
Try adding permits, returning an error if adding the permits would overflow. See the notes on add_permits for more details.
Sourcepub fn forget_permits(&self, count: usize) -> usize
pub fn forget_permits(&self, count: usize) -> usize
Forget up to count permits, up to the currently available amount. Returns the amount of permits forgotten.
If n permits need to be removed, calling acquire_many with the highest priority then
calling forget on the returned guard may be a better choice.
(if the semaphore-total flag is enabled, acquire_within_total may be a safer choice
than acquire_many - if it’s possible for any permits to be forgotten elsewhere)
Trait Implementations§
Source§impl<P: Priority, Q: ConstDefault + SemaphoreQueue<P>> ConstDefault for Semaphore<P, Q>
Available on crate feature const-default only.
impl<P: Priority, Q: ConstDefault + SemaphoreQueue<P>> ConstDefault for Semaphore<P, Q>
const-default only.