SynchronizedValue< T, LOCKTYPE > Class Template Reference

#include <synchronized.h>

Detailed Description

template<typename T, typename LOCKTYPE>
class maxon::SynchronizedValue< T, LOCKTYPE >

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.

Template Parameters
TType of the contained value.
LOCKTYPEType 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)
 
SynchronizedValueoperator= (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)
 
SynchronizedValueoperator= (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

_value
 
LOCKTYPE _lock
 

Member Typedef Documentation

◆ ValueType

using ValueType = T

◆ LockType

using LockType = LOCKTYPE

Constructor & Destructor Documentation

◆ SynchronizedValue() [1/8]

SynchronizedValue ( const SynchronizedValue< T, LOCKTYPE > &  src,
U &&   
)
private

◆ SynchronizedValue() [2/8]

SynchronizedValue ( SynchronizedValue< T, LOCKTYPE > &&  src,
U &&   
)
private

◆ SynchronizedValue() [3/8]

SynchronizedValue ( )
default

Default constructor. Creates an Synchronized with a default constructed value.

◆ SynchronizedValue() [4/8]

SynchronizedValue ( const T &  v)
explicit

Copy-from-value constructor. Initializes the contained value with a copy of v.

◆ SynchronizedValue() [5/8]

SynchronizedValue ( T &&  v)
explicit

Move-from-value constructor. Initializes the contained value by moving from v.

◆ SynchronizedValue() [6/8]

SynchronizedValue ( IN_PLACE_TYPE  ,
ARGS &&...  args 
)
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() [7/8]

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() [8/8]

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.

Member Function Documentation

◆ operator=() [1/2]

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.

◆ CopyFrom()

Result<void> CopyFrom ( const typename std::conditional< TestForCopyFromMember< T >::isSupported, SynchronizedValue< T, LOCKTYPE >, DummyParamType >::type &  src)

◆ operator=() [2/2]

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.

◆ Write() [1/3]

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:

Synchronized<String> v;
// ...
*v.Write() = "Hello"_s;
v.Write()->Flush();

Note that for each temporary pointer, the lock is acquired and released again. You may also store the locked pointer to chain multiple operations:

Synchronized<BaseArray<Int>> v;
// ...
{
auto p = v.Write();
p->Append(1) iferr_return;
p->Append(2) iferr_return;
}

This is equivalent to using ScopedLock.

◆ Write() [2/3]

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

Result<void> func(T&);

Example:

Synchronized<BaseArray<Int>> v;
// ...
v.Write([] (auto& t)
{
t.Append(1) iferr_return;
t.Append(2) iferr_return;
return OK;
}
Parameters
[in]funcFunction that gets write access to the contained value.

◆ Write() [3/3]

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

Result<void> func(T&, U&);

Example:

Synchronized<Int> v1;
Synchronized<Int> v2;
// ...
v1.Write([] (v2, auto& t1, auto& t2)
{
t1 = 1;
t2 = 2;
return OK;
}
Parameters
[in]otherAnother synchronized value.
[in]funcFunction that gets write access to the contained value.

◆ Read() [1/3]

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

const T*

.

◆ Read() [2/3]

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> func(const T&);

◆ Read() [3/3]

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

Result<void> func(const T&, const U&);

◆ AcquireLockPair()

static void AcquireLockPair ( L1 &  sg1,
L2 &  sg2 
)
staticprivate

Member Data Documentation

◆ _value

T _value
private

◆ _lock

LOCKTYPE _lock
mutableprivate
maxon::OK
return OK
Definition: apibase.h:2532
iferr_return
#define iferr_return
Definition: resultbase.h:1434
DiagnosticOutput
#define DiagnosticOutput(formatString,...)
Definition: debugdiagnostics.h:166
iferr_scope
#define iferr_scope
Definition: resultbase.h:1343
MAXON_SCOPE
#define MAXON_SCOPE
Definition: apibase.h:2645