EtcPal  HEAD (unstable)
ETC Platform Abstraction Layer (EtcPal)
View other versions:
synchronized_value (Synchronized Values)

Overview

A value bundled with a lock, where access requires holding the lock.

SynchronizedValue wraps a value of type T together with a lock and only hands out access to the value through RAII handles that hold that lock. This makes it impossible to touch the value without synchronization, in the style of Rust's Mutex<T>.

The value is reached either transiently with operator-> (locked for one call), for a scope via a handle returned from Synchronize(), through a callable with Apply(), or without blocking via TryToSynchronize(). By default the lock is an etcpal::Mutex.

Example usage:

list->push_back(42); // locked for the duration of this single call
{
auto locked = list.Synchronize(); // locked for the scope of `locked`
locked->push_back(1);
locked->push_back(2);
}
auto count = list.Apply([](std::vector<int>& v) { return v.size(); }); // locked during the call
if (auto locked = list.TryToSynchronize()) // populated only if the lock was acquired
locked->push_back(3);
A value bundled with a lock that guards all access to it.
Definition: synchronized_value.h:443
StrictLockPtr< T, LockType > Synchronize()
Lock the value, returning a handle that holds the lock until it is destroyed.
Definition: synchronized_value.h:483

An API that requires an already-locked value can take a StrictLockPtr&, which owns its lock unless it has been moved from. A UniqueLockPtr that owns its lock can be converted into one, either directly (StrictLockPtr<T>{std::move(unique)}) or Boost-style via Release() and an AdoptLockTag constructor.

Note
With a non-recursive lock, two handles alive on the same thread deadlock — including two created in the same full expression, e.g. func(*v.Synchronize(), *v.Synchronize()) or v->Append(v->GetPrefix()), since each handle lives until the end of the full expression.

Data Structures

struct  AdoptLockTag
 Tag requesting that a lock already held by the calling thread be adopted rather than acquired. More...
 
struct  DeferLockTag
 Tag requesting that the lock be left unacquired on construction, to be acquired later with ConstUniqueLockPtr::Lock() or ConstUniqueLockPtr::TryLock(). More...
 
struct  TryToLockTag
 Tag requesting that the lock be acquired with a poll or optional timed wait, never failing with an exception; check OwnsLock() for the result. More...
 
struct  SupportsTimedLock< LockType >
 Trait reporting whether SynchronizedValue::TryToSynchronize() honors its timeout for LockType on the target platform. More...
 
class  ConstStrictLockPtr< T, LockType >
 An RAII handle holding a SynchronizedValue's lock and granting read-only access to the value. More...
 
class  StrictLockPtr< T, LockType >
 An RAII handle holding a SynchronizedValue's lock and granting mutable access to the value. More...
 
class  ConstUniqueLockPtr< T, LockType >
 An RAII handle for read-only access whose lock may or may not be held. More...
 
class  UniqueLockPtr< T, LockType >
 An RAII handle for mutable access whose lock may or may not be held. More...
 
class  SynchronizedValue< T, LockType >
 A value bundled with a lock that guards all access to it. More...