#include <synchronized.h>
A SynchronizedValue<T, LOCKTYPE> stores a value of type T, protected by a lock of type LOCKTYPE. Aliases exist for the common lock types, so SynchronizedValue should not be used directly. Instead, use Synchronized<T> (Spinlock), RWSynchronized<T> (ARWLock).
Access to the value is enabled through the Read() and Write() functions. If possible, prefer using Synchronized over manually pairing locks with values, because there's less room for mistakes.
T | Type of the contained value. |
LOCKTYPE | Type of the lock value. |
Classes | |
class | LockedReadPtr |
class | LockedWritePtr |
Public Types | |
using | ValueType = T |
using | LockType = LOCKTYPE |
Public Member Functions | |
SynchronizedValue ()=default | |
SynchronizedValue (const T &v) | |
SynchronizedValue (T &&v) | |
template<typename ... ARGS> | |
SynchronizedValue (IN_PLACE_TYPE, ARGS &&... args) | |
SynchronizedValue (const typename std::conditional< TestForCopyFromMember< T >::isSupported, DummyParamType, SynchronizedValue >::type &src) | |
SynchronizedValue (SynchronizedValue &&src) | |
SynchronizedValue & | operator= (const typename std::conditional< TestForCopyFromMember< T >::isSupported, DummyParamType, SynchronizedValue >::type &src) |
Result< void > | CopyFrom (const typename std::conditional< TestForCopyFromMember< T >::isSupported, SynchronizedValue, DummyParamType >::type &src) |
SynchronizedValue & | operator= (SynchronizedValue &&src) |
LockedWritePtr | Write () |
template<typename F > | |
Result< void > | Write (F &&func) |
template<typename U , typename F > | |
Result< void > | Write (U &other, F &&func) |
LockedReadPtr | Read () const |
template<typename F > | |
Result< void > | Read (F &&func) const |
template<typename U , typename F > | |
Result< void > | Read (U &other, F &&func) |
Private Member Functions | |
template<typename U > | |
SynchronizedValue (const SynchronizedValue &src, U &&) | |
template<typename U > | |
SynchronizedValue (SynchronizedValue &&src, U &&) | |
Static Private Member Functions | |
template<typename L1 , typename L2 > | |
static void | AcquireLockPair (L1 &sg1, L2 &sg2) |
Private Attributes | |
T | _value |
LOCKTYPE | _lock |
using ValueType = T |
using LockType = LOCKTYPE |
|
private |
|
private |
|
default |
Default constructor. Creates an Synchronized with a default constructed value.
|
explicit |
Copy-from-value constructor. Initializes the contained value with a copy of v.
|
explicit |
Move-from-value constructor. Initializes the contained value by moving from v.
|
explicit |
Emplace constructor. Constructs the contained value in-place with given arguments, i.e. T thisValue(std::forward<ARGS>(args) ...). For complex types that cannot be moved or copied.
SynchronizedValue | ( | const typename std::conditional< TestForCopyFromMember< T >::isSupported, DummyParamType, SynchronizedValue< T, LOCKTYPE > >::type & | src | ) |
Copy constructor. Initializes the contained value with a copy of the value of src. src is locked for reading during the operation.
SynchronizedValue | ( | SynchronizedValue< T, LOCKTYPE > && | src | ) |
Move constructor. Initializes the contained value by moving from the value of src. src is locked for writing during the operation.
SynchronizedValue& operator= | ( | const typename std::conditional< TestForCopyFromMember< T >::isSupported, DummyParamType, SynchronizedValue< T, LOCKTYPE > >::type & | src | ) |
Copy assignment. Assigns the contained value to a copy of the value of src. During this operation, this is locked for writing and src is locked for reading.
Result<void> CopyFrom | ( | const typename std::conditional< TestForCopyFromMember< T >::isSupported, SynchronizedValue< T, LOCKTYPE >, DummyParamType >::type & | src | ) |
SynchronizedValue& operator= | ( | SynchronizedValue< T, LOCKTYPE > && | src | ) |
Move assignment. Assigns the contained value by moving from the value of src. During this operation, this and src are locked for writing.
LockedWritePtr Write | ( | ) |
Returns a locked write pointer to the synchronized value. On creation, the respective lock is acquired. This may involve waiting, if the lock is already taken. During the lifetime of the pointer, the lock remains taken. The synchronized value can be accessed through the pointer. On destruction, the lock is released.
Example:
Note that for each temporary pointer, the lock is acquired and released again. You may also store the locked pointer to chain multiple operations:
This is equivalent to using ScopedLock
.
Result<void> Write | ( | F && | func | ) |
Executes a given function that can safely modify the inner value. It 1. acquires the lock, 2. calls the function and passes a reference to the value as argument, 3. releases the lock. The function should have a signature equivalent to
Example:
[in] | func | Function that gets write access to the contained value. |
Result<void> Write | ( | U & | other, |
F && | func | ||
) |
A variant of Write that takes a second synchronized value. It 1. acquires both locks in order of their addresses, 2. calls the function and passes reference to both values as arguments, 3. releases the locks. This ensures no deadlocks can occur when trying to acquire two locks manually in different orders. The function should have a signature equivalent to
Example:
[in] | other | Another synchronized value. |
[in] | func | Function that gets write access to the contained value. |
LockedReadPtr Read | ( | ) | const |
Similar to Write
, but only provides read-access to the contained value. In other words, the value the locked pointer can access is of type
.
Result<void> Read | ( | F && | func | ) | const |
Similar to Write
, but only provides read-access to the contained value. The function should have a signature equivalent to
Result<void> Read | ( | U & | other, |
F && | func | ||
) |
Similar to Write
, but only provides read-access to the contained values. The function should have a signature equivalent to
|
staticprivate |
|
private |
|
mutableprivate |