userver: rcu::Variable< T, RcuTraits > Class Template Reference
Loading...
Searching...
No Matches
rcu::Variable< T, RcuTraits > Class Template Reference

#include <userver/rcu/rcu.hpp>

Detailed Description

template<typename T, typename RcuTraits>
class rcu::Variable< T, RcuTraits >

Read-Copy-Update variable.

See also
Based on ideas from http://www.drdobbs.com/lock-free-data-structures-with-hazard-po/184401890 with modified API.

A variable with MT-access pattern "very often reads, seldom writes". It is specially optimized for reads. On read, one obtains a ReaderPtr<T> from it and uses the obtained value as long as it wants to. On write, one obtains a WritablePtr<T> with a copy of the last version of the value, makes some changes to it, and commits the result to update current variable value (does Read-Copy-Update). Old version of the value is not freed on update, it will be eventually freed when a subsequent writer identifies that nobody works with this version.

Write transactions on the same rcu::Variable are mutually exclusive. With rcu::DefaultRcuTraits, rcu::SyncRcuTraits, and rcu::BlockingRcuTraits, concurrent writers wait and proceed one by one. rcu::Variable::StartWrite first acquires the writer mutex and then copies the latest committed value into its transaction, so a writer observes changes committed by preceding writers. The mutex is held until rcu::WritablePtr::Commit or rcu::WritablePtr destruction. The order in which concurrent writers acquire the mutex is unspecified. Readers don't acquire the writer mutex and may continue using older snapshots while a writer is active.

Note
rcu::ExclusiveRcuTraits requires the caller to guarantee that write operations on the same rcu::Variable never overlap. If another writer starts while a write transaction is active, an invariant violation is reported instead of waiting: debug builds abort, while release builds throw utils::InvariantError.
The writer mutex protects copying, construction, and publication of the internal RCU snapshot. It does not protect evaluation or copying of arguments before a write method is entered.
There is no way to create a "null" Variable.

Example usage:

constexpr int kOldValue = 1;
constexpr auto kOldString = "Old string";
constexpr int kNewValue = 2;
constexpr auto kNewString = "New string";
struct Data {
int x;
std::string s;
};
rcu::Variable<Data> data{Data{kOldValue, kOldString}};
{
auto ro_ptr = data.Read();
// We can use ro_ptr to access data.
// At this time, neither the writer nor the other readers are not blocked
// => you can hold a smart pointer without fear of blocking other users
ASSERT_EQ(ro_ptr->x, kOldValue);
ASSERT_EQ(ro_ptr->s, kOldString);
}
{
auto ptr = data.StartWrite();
// ptr stores a copy of the latest version of the data, now we can prepare
// a new version Readers continue to access the old version of the data
// via .Read()
ptr->x = kNewValue;
ptr->s = kNewString;
// After Commit(), the next reader in Read() gets the version of the data
// we just wrote. Old readers who did Read() before Commit() continue to
// work with the old version of the data.
ptr.Commit();
}
See also
Synchronization Primitives
Template Parameters
Tthe stored value
RcuTraitstraits, should inherit from rcu::DefaultRcuTraits
Examples
samples/config_service/main.cpp.

Definition at line 434 of file rcu.hpp.

Public Types

using MutexType = typename RcuTraits::MutexType
using DeleterType = typename RcuTraits::DeleterType

Public Member Functions

template<typename... Args>
 Variable (Args &&... initial_value_args)
 Create a new Variable with an in-place constructed initial value.
 Variable (const Variable &)=delete
 Variable (Variable &&)=delete
Variableoperator= (const Variable &)=delete
Variableoperator= (Variable &&)=delete
ReadablePtr< T, RcuTraits > Read () const
 Obtain a smart pointer which can be used to read the current value.
ReadCopy () const
 Obtain a copy of contained value.
WritablePtr< T, RcuTraits > StartWrite ()
template<typename... Args>
WritablePtr< T, RcuTraits > StartWriteEmplace (Args &&... args)
void Assign (T new_value)
template<typename... Args>
void Emplace (Args &&... args)
void Cleanup ()

Member Typedef Documentation

◆ DeleterType

template<typename T, typename RcuTraits>
using rcu::Variable< T, RcuTraits >::DeleterType = typename RcuTraits::DeleterType

Definition at line 442 of file rcu.hpp.

◆ MutexType

template<typename T, typename RcuTraits>
using rcu::Variable< T, RcuTraits >::MutexType = typename RcuTraits::MutexType

Definition at line 441 of file rcu.hpp.

Constructor & Destructor Documentation

◆ Variable()

template<typename T, typename RcuTraits>
template<typename... Args>
rcu::Variable< T, RcuTraits >::Variable ( Args &&... initial_value_args)
inline

Create a new Variable with an in-place constructed initial value.

Parameters
initial_value_argsarguments passed to the constructor of the initial value

Definition at line 449 of file rcu.hpp.

◆ ~Variable()

template<typename T, typename RcuTraits>
rcu::Variable< T, RcuTraits >::~Variable ( )
inline

Definition at line 458 of file rcu.hpp.

Member Function Documentation

◆ Assign()

template<typename T, typename RcuTraits>
void rcu::Variable< T, RcuTraits >::Assign ( T new_value)
inline

Replaces the Variable's value with the provided one. Construction of the new_value parameter happens before the writer mutex is acquired; moving it into the internal RCU snapshot and publishing it are serialized with other write operations.

Definition at line 504 of file rcu.hpp.

◆ Cleanup()

template<typename T, typename RcuTraits>
void rcu::Variable< T, RcuTraits >::Cleanup ( )
inline

Definition at line 514 of file rcu.hpp.

◆ Emplace()

template<typename T, typename RcuTraits>
template<typename... Args>
void rcu::Variable< T, RcuTraits >::Emplace ( Args &&... args)
inline

Replaces the Variable's value with an in-place constructed one. Function arguments are evaluated before the call; construction of the internal RCU snapshot and its publication are serialized with other write operations.

Definition at line 510 of file rcu.hpp.

◆ Read()

template<typename T, typename RcuTraits>
ReadablePtr< T, RcuTraits > rcu::Variable< T, RcuTraits >::Read ( ) const
inline

Obtain a smart pointer which can be used to read the current value.

Definition at line 475 of file rcu.hpp.

◆ ReadCopy()

template<typename T, typename RcuTraits>
T rcu::Variable< T, RcuTraits >::ReadCopy ( ) const
inline

Obtain a copy of contained value.

Definition at line 478 of file rcu.hpp.

◆ StartWrite()

template<typename T, typename RcuTraits>
WritablePtr< T, RcuTraits > rcu::Variable< T, RcuTraits >::StartWrite ( )
inline

Obtain a smart pointer that will copy the current value. First acquires the writer mutex, then copies the latest committed value into the transaction. The pointer can be used to make changes to the value and to set the Variable to the changed value. It owns the writer mutex until Commit or destruction.

Definition at line 488 of file rcu.hpp.

◆ StartWriteEmplace()

template<typename T, typename RcuTraits>
template<typename... Args>
WritablePtr< T, RcuTraits > rcu::Variable< T, RcuTraits >::StartWriteEmplace ( Args &&... args)
inline

Obtain a smart pointer to a newly in-place constructed value, but does not replace the current one yet (in contrast with regular Emplace). First acquires the writer mutex, then constructs the internal replacement value. Owns the mutex until Commit or destruction. Function arguments are evaluated before the call and are not protected by this mutex.

Definition at line 496 of file rcu.hpp.

◆ ReadablePtr< T, RcuTraits >

template<typename T, typename RcuTraits>
friend class ReadablePtr< T, RcuTraits >
friend

Definition at line 514 of file rcu.hpp.

◆ WritablePtr< T, RcuTraits >

template<typename T, typename RcuTraits>
friend class WritablePtr< T, RcuTraits >
friend

Definition at line 514 of file rcu.hpp.


The documentation for this class was generated from the following files: