prevent race condition in isIdle
This commit is contained in:
parent
2f3c407944
commit
83481c54e0
@ -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();
|
||||
|
@ -17,6 +17,13 @@ template <typename T>
|
||||
class SafePriorityQueue {
|
||||
|
||||
public:
|
||||
/*
|
||||
* Default value for functor-taking methods.
|
||||
*/
|
||||
struct no_op {
|
||||
constexpr void operator()() const { }
|
||||
};
|
||||
|
||||
void push(int priority, T& obj)
|
||||
{
|
||||
push(priority, std::forward<T>(obj));
|
||||
@ -41,7 +48,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 = no_op>
|
||||
std::optional<T> pop(F&& callback = no_op())
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> lock(mtx);
|
||||
|
||||
@ -51,10 +66,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
|
||||
|
Loading…
Reference in New Issue
Block a user