pub struct BatchSemaphore { /* private fields */ }Expand description
Counting semaphore
Implementations§
Source§impl BatchSemaphore
impl BatchSemaphore
Sourcepub fn new(num_permits: usize, fairness: Fairness) -> Self
pub fn new(num_permits: usize, fairness: Fairness) -> Self
Creates a new semaphore with the initial number of permits.
pub fn new_with_signature( num_permits: usize, fairness: Fairness, signature: ResourceSignature, ) -> Self
Sourcepub const fn const_new(num_permits: usize, fairness: Fairness) -> Self
pub const fn const_new(num_permits: usize, fairness: Fairness) -> Self
Creates a new semaphore with the initial number of permits.
pub const fn const_new_with_signature( num_permits: usize, fairness: Fairness, signature: ResourceSignature, ) -> Self
Sourcepub fn available_permits(&self) -> usize
pub fn available_permits(&self) -> usize
Returns the current number of available permits.
Sourcepub fn close(&self)
pub fn close(&self)
Closes the semaphore. This prevents the semaphore from issuing new permits and notifies all pending waiters.
Sourcepub fn close_no_scheduling_point(&self)
pub fn close_no_scheduling_point(&self)
Closes the semaphore without invoking thread::switch
Sourcepub fn try_acquire(&self, num_permits: usize) -> Result<(), TryAcquireError>
pub fn try_acquire(&self, num_permits: usize) -> Result<(), TryAcquireError>
Try to acquire the specified number of permits from the Semaphore.
If the permits are available, returns Ok(())
If the semaphore is closed, returns Err(TryAcquireError::Closed)
If there aren’t enough permits, returns Err(TryAcquireError::NoPermits)
Sourcepub fn acquire(&self, num_permits: usize) -> Acquire<'_> ⓘ
pub fn acquire(&self, num_permits: usize) -> Acquire<'_> ⓘ
Acquire the specified number of permits (async API)
Sourcepub fn acquire_blocking(&self, num_permits: usize) -> Result<(), AcquireError>
pub fn acquire_blocking(&self, num_permits: usize) -> Result<(), AcquireError>
Acquire the specified number of permits (blocking API)
Sourcepub fn upgrade(
&self,
permits_currently_held: usize,
permits_to_be_held: usize,
) -> Acquire<'_> ⓘ
pub fn upgrade( &self, permits_currently_held: usize, permits_to_be_held: usize, ) -> Acquire<'_> ⓘ
Atomically upgrade from holding permits_currently_held permits to holding
permits_to_be_held, without ever dropping below permits_currently_held in between.
The motivating use case is parking_lot’s RwLockUpgradableReadGuard::upgrade, which must
take a read guard to a write guard without letting any writer in along the way.
This is implemented by acquiring only the missing permits
(permits_to_be_held - permits_currently_held), with priority over any waiter already
queued, so that the request overtakes the queue. Both halves of that matter:
- Keeping the held permits means no other task can claim the resource mid-upgrade. Releasing
them first (even for an instant) would hand the resource to a queued waiter, which for an
RwLockmeans a writer mutating the data an upgradable reader had already observed. - Overtaking the queue is what makes that safe rather than deadlock-prone. Since we hold
permits we will not release, a queued waiter ahead of us may be unsatisfiable (an
RwLockwriter wants all permits), so waiting our turn behind it could deadlock. Queued waiters hold no permits, so overtaking them costs nothing but their place in line – which is exactly the priority a real upgradable read lock gives an upgrade.
The upgrade therefore blocks only on tasks that currently hold permits, and is granted as
soon as they release. The returned future must be driven to completion; if it is dropped
first, the caller still holds permits_currently_held.
At most one upgrade may be in flight on a semaphore at a time. Two concurrent upgraders
could each be waiting for permits the other holds, which no queue discipline can resolve.
Callers are expected to enforce this (an RwLock does: there is only ever one upgradable
reader).
Sourcepub fn try_upgrade(
&self,
permits_currently_held: usize,
permits_to_be_held: usize,
) -> Result<(), TryAcquireError>
pub fn try_upgrade( &self, permits_currently_held: usize, permits_to_be_held: usize, ) -> Result<(), TryAcquireError>
The non-blocking analogue of BatchSemaphore::upgrade: succeeds only if the missing
permits are available right now, and never blocks or queues.
Like upgrade, this ignores queued waiters (they hold no permits, so they cannot be the
reason the upgrade is short of permits). A try_upgrade therefore fails only when some
other task actually holds permits the upgrade needs.
Source§impl BatchSemaphore
impl BatchSemaphore
Sourcepub fn signature(&self) -> &ResourceSignature
pub fn signature(&self) -> &ResourceSignature
Returns a reference to this semaphore’s resource signature.
Trait Implementations§
Source§impl Debug for BatchSemaphore
impl Debug for BatchSemaphore
Source§impl Default for BatchSemaphore
impl Default for BatchSemaphore
impl Send for BatchSemaphore
impl Sync for BatchSemaphore
Source§impl WithName for &BatchSemaphore
impl WithName for &BatchSemaphore
Auto Trait Implementations§
impl !Freeze for BatchSemaphore
impl !RefUnwindSafe for BatchSemaphore
impl Unpin for BatchSemaphore
impl UnsafeUnpin for BatchSemaphore
impl UnwindSafe for BatchSemaphore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.