summaryrefslogtreecommitdiffstats
path: root/include/jau
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2021-12-05 22:03:51 +0100
committerSven Gothel <[email protected]>2021-12-05 22:03:51 +0100
commit4d67b951ef9a119c1610c4faf1b9ab9c79a69167 (patch)
treeff6b5a2c5de44fcc01d9b7459e1d7b301302673b /include/jau
parentbc725a14656be03cd68c771e519ed54dde4f62ee (diff)
jau::latch: Using condition_variable requires us to hold same mutex lock on modifying count_down() and synchronizing wait*()
Using condition_variable requires us to hold same mutex lock on modifying count_down() and synchronizing wait*(). This is required to not slip the modification of shared variable in count_down() while synchronizing in wait(). This fixed bug lead to sporadic maximum timouts within latch::wait_for(..), even though the condition has been reached beforehand, incl. notification. Notable: The mutex lock shall only be held during modification and the corresponding condition_variable wait-loop. The notify*() still shall be issued w/o lock, i.e. out of mutex scope, to avoid inefficient double-lock at wait*().
Diffstat (limited to 'include/jau')
-rw-r--r--include/jau/latch.hpp7
1 files changed, 3 insertions, 4 deletions
diff --git a/include/jau/latch.hpp b/include/jau/latch.hpp
index ee26393..f07dc6b 100644
--- a/include/jau/latch.hpp
+++ b/include/jau/latch.hpp
@@ -41,7 +41,6 @@ namespace jau {
class latch {
private:
mutable std::mutex mtx_cd;
- mutable std::mutex mtx_cv;
mutable std::condition_variable cv;
jau::sc_atomic_size_t count;
@@ -90,7 +89,7 @@ namespace jau {
void count_down(const size_t n = 1) noexcept {
bool notify;
{
- std::unique_lock<std::mutex> lock(mtx_cd); // Avoid data-race on concurrent count_down() calls
+ std::unique_lock<std::mutex> lock(mtx_cd); // Avoid data-race on concurrent count_down() and wait*() calls
if( n < count ) {
count = count - n;
notify = false;
@@ -122,7 +121,7 @@ namespace jau {
*/
void wait() const noexcept {
if( 0 < count ) {
- std::unique_lock<std::mutex> lock(mtx_cv);
+ std::unique_lock<std::mutex> lock(mtx_cd);
while( 0 < count ) {
cv.wait(lock);
}
@@ -160,7 +159,7 @@ namespace jau {
template<typename Rep, typename Period>
bool wait_for(const std::chrono::duration<Rep, Period>& timeout_duration) const noexcept {
if( 0 < count ) {
- std::unique_lock<std::mutex> lock(mtx_cv);
+ std::unique_lock<std::mutex> lock(mtx_cd);
while( 0 < count ) {
std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
std::cv_status s = cv.wait_until(lock, t0 + timeout_duration);