summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--comphelper/source/misc/threadpool.cxx16
-rw-r--r--include/comphelper/threadpool.hxx9
-rw-r--r--sc/source/core/data/documen2.cxx4
-rw-r--r--sc/source/core/data/formulacell.cxx6
4 files changed, 25 insertions, 10 deletions
diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx
index d0178e9aa9a7..89d80298432b 100644
--- a/comphelper/source/misc/threadpool.cxx
+++ b/comphelper/source/misc/threadpool.cxx
@@ -213,7 +213,7 @@ std::unique_ptr<ThreadTask> ThreadPool::popWorkLocked( std::unique_lock< std::mu
return nullptr;
}
-void ThreadPool::waitUntilDone(const std::shared_ptr<ThreadTaskTag>& rTag)
+void ThreadPool::waitUntilDone(const std::shared_ptr<ThreadTaskTag>& rTag, bool bJoinAll)
{
#if defined DBG_UTIL && (defined LINUX || defined _WIN32)
assert(!gbIsWorkerThread && "cannot wait for tasks from inside a task");
@@ -232,12 +232,16 @@ void ThreadPool::waitUntilDone(const std::shared_ptr<ThreadTaskTag>& rTag)
rTag->waitUntilDone();
+ if (bJoinAll)
+ joinAll();
+}
+
+void ThreadPool::joinAll()
+{
+ std::unique_lock< std::mutex > aGuard( maMutex );
+ if (maTasks.empty()) // check if there are still tasks from another tag
{
- std::unique_lock< std::mutex > aGuard( maMutex );
- if (maTasks.empty()) // check if there are still tasks from another tag
- {
- shutdownLocked(aGuard);
- }
+ shutdownLocked(aGuard);
}
}
diff --git a/include/comphelper/threadpool.hxx b/include/comphelper/threadpool.hxx
index 092078199981..1cb9441cfdd1 100644
--- a/include/comphelper/threadpool.hxx
+++ b/include/comphelper/threadpool.hxx
@@ -63,8 +63,13 @@ public:
/// push a new task onto the work queue
void pushTask( std::unique_ptr<ThreadTask> pTask);
- /// wait until all queued tasks associated with the tag are completed
- void waitUntilDone(const std::shared_ptr<ThreadTaskTag>&);
+ /** Wait until all queued tasks associated with the tag are completed
+ @param bJoinAll - if set it joins all threads at the end if no other tasks from other tags.
+ */
+ void waitUntilDone(const std::shared_ptr<ThreadTaskTag>&, bool bJoinAll = true);
+
+ /// join all threads if there are no tasks presently.
+ void joinAll();
/// return the number of live worker threads
sal_Int32 getWorkerCount() const { return mnWorkers; }
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 321c4535e10b..0892025b242a 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -32,6 +32,7 @@
#include <tools/urlobj.hxx>
#include <rtl/crc.h>
#include <basic/basmgr.hxx>
+#include <comphelper/threadpool.hxx>
#include <sal/log.hxx>
#include <document.hxx>
@@ -307,6 +308,9 @@ ScDocument::~ScDocument()
{
OSL_PRECOND( !bInLinkUpdate, "bInLinkUpdate in dtor" );
+ // Join any pending(recalc) threads in global threadpool
+ comphelper::ThreadPool::getSharedOptimalPool().joinAll();
+
bInDtorClear = true;
// first of all disable all refresh timers by deleting the control
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 17dc29811ae5..9edddf0bfc54 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -4758,8 +4758,10 @@ bool ScFormulaCell::InterpretFormulaGroupThreading(sc::FormulaLogger::GroupScope
nStartOffset, nEndOffset));
}
- SAL_INFO("sc.threaded", "Joining threads");
- rThreadPool.waitUntilDone(aTag);
+ SAL_INFO("sc.threaded", "Waiting for threads to finish work");
+ // Do not join the threads here. They will get joined in ScDocument destructor
+ // if they don't get joined from elsewhere before (via ThreadPool::waitUntilDone).
+ rThreadPool.waitUntilDone(aTag, false);
pDocument->SetThreadedGroupCalcInProgress(false);