template <typename Transaction>
class ChainLockGuard
Defined at line 21 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
ChainLockGuard is a RAII style acquire/release guard for chain locks.
TODO(eieio): Figure out if this type can be merged with lockdep::Guard to provide some level of
runtime consistency analysis between chain locks and other lock classes. Chain locks are
essentially externally ordered locks, where the acquisition of any number of chain locks behaves
as acquiring a single lock class, having its order dependencies with other lock classes tracked.
Public Methods
void ChainLockGuard<Transaction> (ChainLock<Transaction> & lock)
Unconditionally acquires the given chain lock.
Defined at line 24 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
void ChainLockGuard<Transaction> (ChainLock<Transaction> & lock, AdoptTag )
Defined at line 31 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
void ChainLockGuard<Transaction> (ChainLock<Transaction> & lock, DeferTag )
Defined at line 53 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
void ChainLockGuard<Transaction> (ChainLockGuard<Transaction> && other, ChainLock<Transaction> & lock, TakeTag )
Defined at line 62 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
void ChainLockGuard<Transaction> (const ChainLockGuard<Transaction> & )
Defined at line 70 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
ChainLockGuard<Transaction> & operator= (const ChainLockGuard<Transaction> & )
Defined at line 71 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
void ChainLockGuard<Transaction> (ChainLockGuard<Transaction> && )
Defined at line 72 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
ChainLockGuard<Transaction> & operator= (ChainLockGuard<Transaction> && )
Defined at line 73 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
ChainLockGuard<Transaction> && take ()
Releases the capability guarded by this instance without actually releasing the lock. This is
intended to be used with the Take constructor, which acquires the capability, to move
responsibility for the lock to another guard.
Defined at line 78 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
bool AcquireOrBackoff ()
Conditionally acquires the lock or returns false because of backoff.
Defined at line 84 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
bool TryAcquire (AllowFinalized allow_finalized, RecordBackoff record_backoff)
Conditionally acquires the lock or returns false if failed.
Defined at line 94 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
template <typename Callable>
bool TryAcquireWith (Callable && callable)
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.
Defined at line 105 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
void Release ()
Releases the guarded lock and its capability.
Defined at line 112 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
void Unguard ()
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:
{
ChainLockGuard guard{object->get_lock()};
// Validation with lock held ...
guard.Unguard(); // Avoid double release when guard destructs.
DoOperationAndReleaseLock(object);
}
Possible alternatives to explore that could replace this workaround:
1. Move the guard into the callee that will release the lock:
DoOperationAndReleaseLock(object, guard.take());
2. Make the guard destructor check that that lock is actually held to avoid the double release:
~ChainLockGuard() __TA_RELEASE() {
if (held_
&
&
lock_.is_held()) {
lock_.Release();
}
}
All of these approaches have potential advantages and disadvantages that need to be considered.
Defined at line 149 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
void ~ChainLockGuard<Transaction> ()
Releases the lock if currently held.
Defined at line 155 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
Enumerations
enum AdoptTag
| Name | Value |
|---|---|
| Adopt | 0 |
Adopts the given chain lock that is already acquired via some other mechanism.
Defined at line 30 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
enum DeferTag
| Name | Value |
|---|---|
| Defer | 0 |
Associates the given lock capability with this scoped capability, but does not acquire it. This
is useful in conjunction with the conditional acquire methods below.
Example:
ChainLockGuard guard{lock, ChainLockGuard::Defer};
if (guard.AcquireOrBackoff()) {
// 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.
}
NOTE: This method is correctly annotated for static analysis to understand when this scoped
capability does and does not hold the lock. The excludes annotation on the constructor tells
static analysis which capability to associate with the scoped capability instance in the "not
held" state. Later, methods annotated with acquire or release can change the state to "held"
and back to "not held", respectively.
Defined at line 52 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h
enum TakeTag
| Name | Value |
|---|---|
| Take | 0 |
Takes responsibility for the given lock from the given guard. This is useful for moving the
scope of a lock acquisition deeper into the call stack in certain locking patterns.
Asserts that the given guard actually holds the given lock.
Defined at line 61 of file ../../zircon/system/ulib/concurrent/include/lib/concurrent/chainlock_guard.h