diff options
author | Michael Stahl <mstahl@redhat.com> | 2017-03-22 10:47:06 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2017-03-22 11:39:32 +0100 |
commit | 64c09371d6feed6e87aaa54cde081f001dcfca10 (patch) | |
tree | 281eaeedf500cc40f092bbc573d5e00134c0a01d /comphelper | |
parent | 3b2863596f26a8d32a5bc322bbbf51cad403c9fb (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.cxx | 16 |
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(); } } |