diff options
author | Sven Gothel <[email protected]> | 2021-12-05 22:03:51 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2021-12-05 22:03:51 +0100 |
commit | 4d67b951ef9a119c1610c4faf1b9ab9c79a69167 (patch) | |
tree | ff6b5a2c5de44fcc01d9b7459e1d7b301302673b /include/jau | |
parent | bc725a14656be03cd68c771e519ed54dde4f62ee (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.hpp | 7 |
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); |