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_type | The 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
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.