summaryrefslogtreecommitdiff
path: root/comphelper
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2017-03-22 10:47:06 +0100
committerMichael Stahl <mstahl@redhat.com>2017-03-22 11:39:32 +0100
commit64c09371d6feed6e87aaa54cde081f001dcfca10 (patch)
tree281eaeedf500cc40f092bbc573d5e00134c0a01d /comphelper
parent3b2863596f26a8d32a5bc322bbbf51cad403c9fb (diff)
comphelper::ThreadPool: guard against concurrent shutdown/pushTask
To join a thread, the mutex must be released - another thread in pushTask() could add a new thread to maWorkers at that point, which must of course not be deleted. Avoid the problem by transferring ownership of the to-be-deleted threads to the calling thread. (regression from bdaa13a87744e424d3c210fc7f3f9e4f199d8279) Change-Id: I9d4fcfe4cb46a336586b5663934a12d47b2d8ccb
Diffstat (limited to 'comphelper')
-rw-r--r--comphelper/source/misc/threadpool.cxx16
1 files changed, 9 insertions, 7 deletions
diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx
index 3aaf344c3ba8..2c8a116c4e56 100644
--- a/comphelper/source/misc/threadpool.cxx
+++ b/comphelper/source/misc/threadpool.cxx
@@ -157,18 +157,20 @@ void ThreadPool::shutdownLocked(std::unique_lock<std::mutex>& aGuard)
maTasksChanged.notify_all();
- while( !maWorkers.empty() )
+ decltype(maWorkers) aWorkers;
+ std::swap(maWorkers, aWorkers);
+ aGuard.unlock();
+
+ while (!aWorkers.empty())
{
- rtl::Reference< ThreadWorker > xWorker = maWorkers.back();
- maWorkers.pop_back();
- assert(std::find(maWorkers.begin(), maWorkers.end(), xWorker)
- == maWorkers.end());
- aGuard.unlock();
+ rtl::Reference<ThreadWorker> xWorker = aWorkers.back();
+ aWorkers.pop_back();
+ assert(std::find(aWorkers.begin(), aWorkers.end(), xWorker)
+ == aWorkers.end());
{
xWorker->join();
xWorker.clear();
}
- aGuard.lock();
}
}