summaryrefslogtreecommitdiff
path: root/comphelper/source
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-11-26 15:05:16 +0100
committerLuboš Luňák <l.lunak@collabora.com>2020-12-01 11:15:22 +0100
commitebd9e833fab5a26a137bef6c0e7bce2b3c9e0cf9 (patch)
treecdeeb7a46ea0ac7b4b190e5cd44664a447335767 /comphelper/source
parentba8156d5a1dd2d37c7daef15f48b988bf6ded7a7 (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> (cherry picked from commit 583b0612696f42571ac97b66c159570ea452fe17) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106824
Diffstat (limited to 'comphelper/source')
-rw-r--r--comphelper/source/misc/threadpool.cxx21
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)