Skip to main content

ChainLockGuard

Struct ChainLockGuard 

Source
pub struct ChainLockGuard<'a, T: Transaction> { /* private fields */ }
Expand description

RAII-style acquire/release guard for ChainLock.

Implementations§

Source§

impl<'a, T: Transaction> ChainLockGuard<'a, T>

Source

pub fn new( lock: &'a ChainLock<T>, token: &'a ChainLockTransactionToken<T>, ) -> Self

Unconditionally acquires the given chain lock as the first lock in the chain.

Source

pub const fn adopt( lock: &'a ChainLock<T>, _token: &'a ChainLockTransactionToken<T>, ) -> Self

Adopts the given chain lock that is already acquired via some other mechanism.

Source

pub const fn defer( lock: &'a ChainLock<T>, _token: &'a ChainLockTransactionToken<T>, ) -> Self

Associates the given lock capability with this scoped guard, but does not acquire it. This is useful in conjunction with the conditional acquire methods below.

§Example
ⓘ
let mut guard = ChainLockGuard::defer(&lock, token);
if guard.acquire_or_backoff() {
    // Lock is acquired and guarded. It will be released when guard goes out of scope.
} else {
    // Lock is not acquired or guarded. It will not be released when guard goes out of
    // scope.
}
Source

pub fn from_taken(other: Self, lock: &'a ChainLock<T>) -> Self

Takes responsibility for lock from other. This is useful for moving the scope of a lock acquisition deeper into the call stack in certain locking patterns.

Asserts in debug builds that other actually holds lock.

Source

pub fn take(self) -> Self

Releases the capability guarded by this instance without actually releasing the lock, returning a moved guard intended to be passed to Self::from_taken or a callee.

Asserts in debug builds that this guard currently holds the lock.

Source

pub fn acquire_or_backoff(&mut self) -> bool

Conditionally acquires the lock or returns false because of backoff.

Asserts in debug builds that the lock is not already held by this guard.

Source

pub fn try_acquire(&mut self) -> bool

Conditionally acquires the lock with default options (AllowFinalized::No, RecordBackoff::Yes) or returns false if failed.

Asserts in debug builds that the lock is not already held by this guard.

Source

pub fn try_acquire_with_options( &mut self, allow_finalized: AllowFinalized, record_backoff: RecordBackoff, ) -> bool

Conditionally acquires the lock with the specified options or returns false if failed.

Asserts in debug builds that the lock is not already held by this guard.

Source

pub fn try_acquire_with<F>(&mut self, callable: F) -> bool
where F: FnOnce(&'a ChainLock<T>) -> bool,

Conditionally acquires the lock using the given callable, or returns false if failed. This is useful in certain locking patterns where an additional predicate needs to be injected into the lock condition.

Asserts in debug builds that the lock is not already held by this guard.

Source

pub fn release(&mut self)

Releases the guarded lock and its capability.

Asserts in debug builds that the lock is currently held by this guard.

Source

pub fn unguard(&mut self)

Prevents this guard from releasing the lock when it goes out of scope, but does not release the lock or its capability. This is a temporary workaround to allow guards to be used in scopes that will release the guarded lock in a function or method called in the guarded scope.

§Example
ⓘ
{
    let mut guard = ChainLockGuard::new(object.get_lock(), token);

    // Validation with lock held ...

    guard.unguard(); // Avoid double release when guard destructs.
    do_operation_and_release_lock(object, token);
}

Possible alternatives to explore that could replace this workaround:

  1. Move the guard into the callee that will release the lock:
ⓘ
do_operation_and_release_lock(object, guard.take());
  1. Make the guard destructor check that the lock is actually held to avoid the double release:
ⓘ
impl<T: Transaction> Drop for ChainLockGuard<'_, T> {
    fn drop(&mut self) {
        if self.held && self.lock.is_held(&self.token) {
            self.lock.release(&self.token);
        }
    }
}

All of these approaches have potential advantages and disadvantages that need to be considered.

Asserts in debug builds that the lock is currently held by this guard.

Source

pub const fn is_held(&self) -> bool

Returns true if this guard currently holds the lock.

Source

pub const fn lock(&self) -> &'a ChainLock<T>

Returns a reference to the underlying ChainLock.

Trait Implementations§

Source§

impl<T: Transaction> Drop for ChainLockGuard<'_, T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<'a, T> !Send for ChainLockGuard<'a, T>

§

impl<'a, T> !Sync for ChainLockGuard<'a, T>

§

impl<'a, T> Freeze for ChainLockGuard<'a, T>

§

impl<'a, T> RefUnwindSafe for ChainLockGuard<'a, T>
where <T as Transaction>::ContentionState: RefUnwindSafe, T: RefUnwindSafe,

§

impl<'a, T> Unpin for ChainLockGuard<'a, T>

§

impl<'a, T> UnsafeUnpin for ChainLockGuard<'a, T>

§

impl<'a, T> UnwindSafe for ChainLockGuard<'a, T>
where <T as Transaction>::ContentionState: RefUnwindSafe, T: RefUnwindSafe,

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

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> ToMutPtr for T
where T: ?Sized,

Source§

type Target = T

The target type of the pointer.
Source§

fn to_mut_ptr(&self) -> *mut T

Casts the reference to a mutable raw pointer.
§

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

§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
§

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

§

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

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

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

Performs the conversion.