summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2023-01-08 21:31:55 +0100
committerRoman Smrž <roman.smrz@seznam.cz>2023-01-14 23:08:37 +0100
commit9ac0b00342c559cc4ad50061176ce2fd10482caa (patch)
tree3e91bb773884361b4a8eac314ef43138ad6801f3 /src
parente788bba4bfcb6cb7d21f607bb5bf93213fb1a334 (diff)
FRP: support recursive locking with BhvCurTime
Diffstat (limited to 'src')
-rw-r--r--src/frp.cpp32
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();
+ }
}
}