Boboter
Loading...
Searching...
No Matches
protected_struct< struct_type > Class Template Reference

A RAII type used to make structs thread-safe for FreeRTOS via mutexes. More...

#include <protected_struct.h>

Public Member Functions

 protected_struct ()
 ~protected_struct ()
 protected_struct (const protected_struct &)=delete
protected_structoperator= (const protected_struct &)=delete
proxy operator-> () const
 Overload of the get value from dereferenced pointer operator to make it possible to get a value using it.
proxy operator* () const
 Overload of the dereference operator to make it possible to pass the whole struct to something.

Detailed Description

template<typename struct_type>
class protected_struct< struct_type >

A RAII type used to make structs thread-safe for FreeRTOS via mutexes.

Template Parameters
struct_typeThe struct to make thread-safe

This class gives you the ability to make a struct thread-safe and then access it with an automatically managed FreeRTOS mutex, which automatically locks on construction and unlocks on destruction (RAII-Principle)

Ways to access members of the protected struct:
1) Single Access: Get from dereferenced pointer operator

data->value = 5;

Accesses and locks the struct for only one code line, very inefficient if you have lots of operations on the struct, but convenient when you only need one quick access without blocking for too long

2) Full Scope Access: Dereference Operator

const auto ldata = *data;
ldata->value = 5;

Locks the struct for the full lifetime of the current scope, lets you interact with the locked struct via the newly created variable (in this case: ldata)

3) Passing protected struct to function: Dereference Operator

void process(my_struct& s) {
s.value = 5;
}
process(*data);

Locks the struct, passes the locked struct to the function, executes the function and unlocks the struct again.
IMPORTANT: Here, we use s.value instead of s->value in the function, as we're getting a struct reference instead of a struct pointer.

Attention
If you try to do something like this:
const auto ldata = *data;
void process(my_struct& s) {
s.value = 5;
}
process(*data);
The firmware will get caught in a race condition which is known as a deadlock, meaning it will try double-locking the mutex, which leads to it permanently hanging as soon as process(*data); is called. This happens because when you first create the ldata object, data gets locked. If you now also pass data to the process() function using the dereference operator (*data), the mutex will try to lock for a second time and wait forever until it's released for the first time, which can't happen, because the code flow to the end of scope is blocked by the mutex waiting for its own release.
To fix this issue, instead of passing *data, just pass the already locked ldata object.

Constructor & Destructor Documentation

◆ protected_struct() [1/2]

template<typename struct_type>
protected_struct< struct_type >::protected_struct ( )
inlineexplicit

◆ ~protected_struct()

template<typename struct_type>
protected_struct< struct_type >::~protected_struct ( )
inline

◆ protected_struct() [2/2]

template<typename struct_type>
protected_struct< struct_type >::protected_struct ( const protected_struct< struct_type > & )
delete

Member Function Documentation

◆ operator*()

template<typename struct_type>
proxy protected_struct< struct_type >::operator* ( ) const
inline

Overload of the dereference operator to make it possible to pass the whole struct to something.

Returns
A temporary proxy object to hold the mutex and return the value

◆ operator->()

template<typename struct_type>
proxy protected_struct< struct_type >::operator-> ( ) const
inline

Overload of the get value from dereferenced pointer operator to make it possible to get a value using it.

Returns
A temporary proxy object to hold the mutex and return the value

◆ operator=()

template<typename struct_type>
protected_struct & protected_struct< struct_type >::operator= ( const protected_struct< struct_type > & )
delete

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