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 /src | |
| parent | e788bba4bfcb6cb7d21f607bb5bf93213fb1a334 (diff) | |
FRP: support recursive locking with BhvCurTime
Diffstat (limited to 'src')
| -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(); +		}  	}  } |