Hi,
from a thread safety point of view, how safe is to change a global variable inside the OnSyncCallback() function of a Ledger? In case I want to read this variable from loop(), for instance.
Thanks!
Hi,
from a thread safety point of view, how safe is to change a global variable inside the OnSyncCallback() function of a Ledger? In case I want to read this variable from loop(), for instance.
Thanks!
At worst, the ledger callback will be called from a thread, as it's not an ISR.
As such, you can safely access integral types like int, bool, etc. between threads.
If you are using a complex type like String
, Variant
, etc. you should use a lock to prevent accessing a partially written variable between two threads.
You should also use a lock, or atomic data types, if you do things like increment or decrement from one thread from two threads.
It's better to use a mutex lock for thread safety. Disabling interrupts should be avoided whenever possible.
Thanks.
So if my class parsing the ledger is a singleton and has these functions+mutex:
public:
void lock() { os_mutex_lock(mutex); };
bool tryLock() { return os_mutex_trylock(mutex); };
void unlock() { os_mutex_unlock(mutex); };
protected:
os_mutex_t mutex = 0;
Would I use WITH_LOCK(*this) like in the below example?
Variant cmdVariant;
WITH_LOCK(*this)
{
// Retrieve data from the ledger
LedgerData ld = ledgerCloudCmd.get();
const char *key = "cmd";
// Check if the key exists
if (!ld.has(key))
{
logcc.warn("Key '%s' not found in the ledger", key);
return false;
}
// Get the value
cmdVariant = ld.get(key);
}
Thanks!
That should work, but I would probably only put the line where you copy the ledger data into your class member variable in the locked section.
Good point, I will go with this, then:
LedgerData ld;
WITH_LOCK(*this)
{
// Retrieve data from the ledger
ld = ledgerCloudCmd.get();
}
Thank you,