|
|
@@ -59,7 +59,8 @@ bool Critical::isLocked() const
|
|
|
}
|
|
|
|
|
|
Synchronizer::Synchronizer()
|
|
|
- : numWaiting(0),
|
|
|
+ : storedNotifications(0),
|
|
|
+ numWaiting(0),
|
|
|
skip(0)
|
|
|
{}
|
|
|
|
|
|
@@ -83,6 +84,11 @@ bool Synchronizer::wait()
|
|
|
{
|
|
|
std::unique_lock<std::mutex> lk(mutex);
|
|
|
if (skip) return false;
|
|
|
+ if (storedNotifications > 0)
|
|
|
+ {
|
|
|
+ storedNotifications--;
|
|
|
+ return !skip;
|
|
|
+ }
|
|
|
numWaiting++;
|
|
|
block.wait(lk);
|
|
|
numWaiting--;
|
|
|
@@ -93,6 +99,11 @@ bool Synchronizer::wait(int milisec)
|
|
|
{
|
|
|
std::unique_lock<std::mutex> lk(mutex);
|
|
|
if (skip) return false;
|
|
|
+ if (storedNotifications > 0)
|
|
|
+ {
|
|
|
+ storedNotifications--;
|
|
|
+ return !skip;
|
|
|
+ }
|
|
|
numWaiting++;
|
|
|
std::cv_status status
|
|
|
= block.wait_for(lk, std::chrono::milliseconds(milisec));
|
|
|
@@ -100,19 +111,48 @@ bool Synchronizer::wait(int milisec)
|
|
|
return !skip && status == std::cv_status::no_timeout;
|
|
|
}
|
|
|
|
|
|
-void Synchronizer::notify()
|
|
|
+void Synchronizer::notify(bool storedNotifications)
|
|
|
{
|
|
|
+ std::unique_lock<std::mutex> lk(mutex);
|
|
|
+ if (numWaiting == 0)
|
|
|
+ {
|
|
|
+ if (storedNotifications)
|
|
|
+ {
|
|
|
+ this->storedNotifications++;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
block.notify_one();
|
|
|
}
|
|
|
|
|
|
-void Synchronizer::notify(int amount)
|
|
|
+void Synchronizer::notify(int amount, bool storedNotifications)
|
|
|
{
|
|
|
+ std::unique_lock<std::mutex> lk(mutex);
|
|
|
+ if (numWaiting < amount)
|
|
|
+ {
|
|
|
+ if (storedNotifications)
|
|
|
+ {
|
|
|
+ this->storedNotifications += numWaiting - amount;
|
|
|
+ }
|
|
|
+ amount = numWaiting;
|
|
|
+ }
|
|
|
while (amount--)
|
|
|
+ {
|
|
|
block.notify_one();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-void Synchronizer::notifyAll()
|
|
|
+void Synchronizer::notifyAll(bool storedNotifications)
|
|
|
{
|
|
|
+ std::unique_lock<std::mutex> lk(mutex);
|
|
|
+ if (numWaiting == 0)
|
|
|
+ {
|
|
|
+ if (storedNotifications)
|
|
|
+ {
|
|
|
+ this->storedNotifications++;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
block.notify_all();
|
|
|
}
|
|
|
|
|
|
@@ -335,7 +375,7 @@ void Framework::ReadWriteLock::unlockRead()
|
|
|
}
|
|
|
if (readerThreadCount == 0 && waitingWriters > 0)
|
|
|
{
|
|
|
- writerBlock.notify();
|
|
|
+ writerBlock.notify(true);
|
|
|
}
|
|
|
currentThreadLockCount--;
|
|
|
cs.unlock();
|
|
|
@@ -354,11 +394,11 @@ void Framework::ReadWriteLock::unlockWrite()
|
|
|
{
|
|
|
if (waitingWriters > 0)
|
|
|
{
|
|
|
- writerBlock.notify();
|
|
|
+ writerBlock.notify(true);
|
|
|
}
|
|
|
else if (waitingReaders > 0)
|
|
|
{
|
|
|
- readerBlock.notify(waitingReaders);
|
|
|
+ readerBlock.notify(waitingReaders, true);
|
|
|
}
|
|
|
}
|
|
|
currentThreadLockCount--;
|