From a72fdb9ca2a71c57ab3f0b3d7aec0608307eea04 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 12 Mar 2021 12:57:25 +0200 Subject: [PATCH] ConcurrentQueue::cancelPending: don't reset jobsLeft to 0 Worker threads may well be executing jobs while this function is being called. If ConcurrentQueue::waitAll() is called soon enough after cancelPending(), the worker threads may still be running, but waitAll() would return immediately as jobsLeft would be nonpositive. Subtracting _queue.size() from jobsLeft sets this variable to the number of worker threads that are executing jobs at the moment. ConcurrentQueueTest::cancelPending1UserThread() passes most of the time now. But it still fails occasionally because it depends on the timing of thread scheduling, which is unreliable. --- common/concurrent_queue.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/concurrent_queue.h b/common/concurrent_queue.h index c983b277..300f783d 100644 --- a/common/concurrent_queue.h +++ b/common/concurrent_queue.h @@ -47,8 +47,8 @@ public: { std::unique_lock lockQueue(queueMutex); std::unique_lock lockJobsLeft(jobsLeftMutex); - _queue = std::queue>(); - jobsLeft = 0; + jobsLeft -= _queue.size(); + _queue = {}; } void waitAll()