diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2023-01-08 21:31:55 +0100 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2023-01-14 23:08:37 +0100 |
commit | 9ac0b00342c559cc4ad50061176ce2fd10482caa (patch) | |
tree | 3e91bb773884361b4a8eac314ef43138ad6801f3 | |
parent | e788bba4bfcb6cb7d21f607bb5bf93213fb1a334 (diff) |
FRP: support recursive locking with BhvCurTime
-rw-r--r-- | src/frp.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/src/frp.cpp b/src/frp.cpp index a16950c..1d377dd 100644 --- a/src/frp.cpp +++ b/src/frp.cpp @@ -2,6 +2,7 @@ #include <condition_variable> #include <mutex> +#include <thread> using namespace erebos; @@ -9,33 +10,50 @@ using std::condition_variable; using std::move; using std::mutex; using std::nullopt; +using std::thread; using std::unique_lock; +namespace { + mutex bhvTimeMutex; condition_variable bhvTimeCond; -bool bhvTimeRunning = false; +optional<thread::id> bhvTimeRunning = nullopt; +uint64_t bhvTimeCount = 0; uint64_t bhvTimeLast = 0; +} + BhvTime::BhvTime(const BhvCurTime & ct): BhvTime(ct.time()) {} BhvCurTime::BhvCurTime() { + auto tid = std::this_thread::get_id(); unique_lock lock(bhvTimeMutex); - bhvTimeCond.wait(lock, []{ return !bhvTimeRunning; }); + bhvTimeCond.wait(lock, [tid]{ + return !bhvTimeRunning || bhvTimeRunning == tid; + }); - bhvTimeRunning = true; - t = BhvTime(++bhvTimeLast); + if (bhvTimeRunning != tid) { + bhvTimeRunning = tid; + bhvTimeLast++; + } + t = BhvTime(bhvTimeLast); + bhvTimeCount++; } BhvCurTime::~BhvCurTime() { if (t) { unique_lock lock(bhvTimeMutex); - bhvTimeRunning = false; - lock.unlock(); - bhvTimeCond.notify_one(); + bhvTimeCount--; + + if (bhvTimeCount == 0) { + bhvTimeRunning.reset(); + lock.unlock(); + bhvTimeCond.notify_one(); + } } } |