diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2020-11-26 15:05:16 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2020-11-30 13:16:53 +0100 |
commit | 583b0612696f42571ac97b66c159570ea452fe17 (patch) | |
tree | e370a37e6a6ed6b019f8be78d62a676d89e0c7c5 /comphelper/source | |
parent | af361b464b46dcc39a1bb4ab098a6ddf6ff40a53 (diff) |
add ThreadPool::isIdle() to avoid incorrect detection of "no tasks"
Tasks that are being worked on but are not yet finished are removed
from maTasks, so maTasks.empty() does not mean "idle". I fixed one
case already in 2ad4e77a0f266ae6e6fccaebb1d080d2880bdac3, this one
fixes joinAll() which has a similar problem and triggers
https://gerrit.libreoffice.org/c/core/+/69473/3/sc/source/core/data/documen2.cxx#312
Also rename joinAll() to joinThreadsIfIdle(), as that's what it really is.
Change-Id: I8129cfadb81be968575ea8718de9ae997b877a4e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106701
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'comphelper/source')
-rw-r--r-- | comphelper/source/misc/threadpool.cxx | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx index 4ff7bac3aede..1ef0eeaaba5c 100644 --- a/comphelper/source/misc/threadpool.cxx +++ b/comphelper/source/misc/threadpool.cxx @@ -76,6 +76,7 @@ public: std::unique_ptr<ThreadTask> pTask = mpPool->popWorkLocked( aGuard, true ); if( pTask ) { + std::shared_ptr<ThreadTaskTag> pTag(pTask->mpTag); mpPool->incBusyWorker(); aGuard.unlock(); @@ -84,6 +85,7 @@ public: aGuard.lock(); mpPool->decBusyWorker(); + pTag->onTaskWorkerDone(); } } } @@ -162,7 +164,11 @@ void ThreadPool::shutdownLocked(std::unique_lock<std::mutex>& aGuard) { // no threads at all -> execute the work in-line std::unique_ptr<ThreadTask> pTask; while ( ( pTask = popWorkLocked(aGuard, false) ) ) + { + std::shared_ptr<ThreadTaskTag> pTag(pTask->mpTag); pTask->exec(); + pTag->onTaskWorkerDone(); + } } else { @@ -250,7 +256,7 @@ void ThreadPool::decBusyWorker() --mnBusyWorkers; } -void ThreadPool::waitUntilDone(const std::shared_ptr<ThreadTaskTag>& rTag, bool bJoinAll) +void ThreadPool::waitUntilDone(const std::shared_ptr<ThreadTaskTag>& rTag, bool bJoin) { #if defined DBG_UTIL && (defined LINUX || defined _WIN32) assert(!gbIsWorkerThread && "cannot wait for tasks from inside a task"); @@ -265,21 +271,23 @@ void ThreadPool::waitUntilDone(const std::shared_ptr<ThreadTaskTag>& rTag, bool std::unique_ptr<ThreadTask> pTask = popWorkLocked(aGuard, false); if (!pTask) break; + std::shared_ptr<ThreadTaskTag> pTag(pTask->mpTag); pTask->exec(); + pTag->onTaskWorkerDone(); } } } rTag->waitUntilDone(); - if (bJoinAll) - joinAll(); + if (bJoin) + joinThreadsIfIdle(); } -void ThreadPool::joinAll() +void ThreadPool::joinThreadsIfIdle() { std::unique_lock< std::mutex > aGuard( maMutex ); - if (maTasks.empty()) // check if there are still tasks from another tag + if (isIdle()) // check if there are still tasks from another tag { shutdownLocked(aGuard); } @@ -302,7 +310,6 @@ ThreadTask::ThreadTask(const std::shared_ptr<ThreadTaskTag>& pTag) void ThreadTask::exec() { - std::shared_ptr<ThreadTaskTag> pTag(mpTag); try { doWork(); } @@ -318,8 +325,6 @@ void ThreadTask::exec() { SAL_WARN("comphelper", "unknown exception in thread worker while calling doWork()"); } - - pTag->onTaskWorkerDone(); } ThreadTaskTag::ThreadTaskTag() : mnTasksWorking(0) |