prevent race condition in isIdle

This commit is contained in:
Erik Bročko 2022-05-30 15:36:50 +02:00
parent 2f3c407944
commit f9c6570e3b
Signed by: ericek111
GPG Key ID: 414DED726771329C
2 changed files with 19 additions and 5 deletions

View File

@ -119,9 +119,13 @@ private:
return;
}
auto callable = std::move(queue.pop());
if (callable.has_value()) {
// Prevent possible race condition in isIdle().
// Perhaps can be reworked, e. g. by having each worker track its progress individually?
auto callable = std::move(queue.pop([&] {
threadsWorking++;
}));
if (callable.has_value()) {
callable.value()();
threadsWorking--;
poolCond.notify_all();

View File

@ -41,7 +41,15 @@ public:
queueLength++;
}
std::optional<T> pop()
/**
* Pop (and return) the top-most item in the stack.
* @tparam F
* @param callback Will be executed after (and only after) an element is popped off the queue,
* but before the mutex is released -- good for count-keeping.
* @return If the queue is empty, std::nullopt is returned.
*/
template <typename F = void(void)>
std::optional<T> pop(F&& callback = [](){})
{
std::unique_lock<std::shared_mutex> lock(mtx);
@ -51,10 +59,12 @@ public:
queueLength--;
auto ret = std::move(queue.front());
auto ret = std::move(queue.front().second);
queue.pop_front();
return ret.second;
callback();
return ret;
}
std::optional<T> peek() const