====== Thread Safety ======
In EEROS, blocks are basically accessed by multiple threads. EEROS blocks feature thread safety by providing exclusive access to critical memory locations by a mutex.
Concurrency can not be tested by Google Test framework. Therefore, test executables are needed which can be executed manually or via bash scripts.
To provide an example, a test program testing the Gain block is described below. The full source code is available on GitHub at: https://github.com/eeros-project/eeros-framework/blob/master/examples/devel/multithreading.cpp
===== The problem =====
The following code snipped and image show the issue simulated in the test program. The main thread calls **g1.run()** on the gain object. This method is doing a long calculation. Thread t2 is unfortunately changing the gain by calling **g1.setGain(gM2)** during the main threads calculation. This will finally lead to an unexpected result.
Matrix gM1;
Matrix gM2;
Gain, Matrix,true> g1{gM1};
Constant> c1{m2};
std::thread t2{[&] {
g1.setGain(gM2);
}};
g1.run();
Matrix res = g1.getOut().getSignal().getValue();
// Note: The above code is simplified for a better understanding.
{{:for_developers:concurrencyissue.jpg?800|}}
===== The solution =====
The Gain block is now implemented thread safe by using the class [[https://en.cppreference.com/w/cpp/thread/lock_guard|lock_guard]] and a [[https://en.cppreference.com/w/cpp/thread/mutex|mutex]]. The code snipped below shows the **setGain()** method as an example.
virtual void setGain(Tgain c) {
std::lock_guard lock(mtx);
gain = c;
}
The test program will not show an unexpected result anymore. To see the unexpected result, the locking mechanism must be removed (//comment std::lock_guard lock(mtx);//).