summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--comphelper/source/misc/threadpool.cxx149
-rw-r--r--drawinglayer/source/primitive2d/sceneprimitive2d.cxx9
-rw-r--r--include/comphelper/threadpool.hxx19
-rw-r--r--package/inc/ZipOutputStream.hxx4
-rw-r--r--package/source/zipapi/ZipOutputStream.cxx6
-rw-r--r--package/source/zippackage/ZipPackageStream.cxx7
-rw-r--r--sc/source/filter/excel/xetable.cxx9
-rw-r--r--sc/source/filter/oox/workbookfragment.cxx76
-rw-r--r--sw/source/core/ole/ndole.cxx59
-rw-r--r--vcl/source/bitmap/bitmapscalesuper.cxx8
10 files changed, 224 insertions, 122 deletions
diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx
index 8680e00e6e34..32170a1a0cd1 100644
--- a/comphelper/source/misc/threadpool.cxx
+++ b/comphelper/source/misc/threadpool.cxx
@@ -9,6 +9,7 @@
#include <comphelper/threadpool.hxx>
+#include <com/sun/star/uno/Exception.hpp>
#include <rtl/instance.hxx>
#include <rtl/string.hxx>
#include <algorithm>
@@ -17,6 +18,26 @@
namespace comphelper {
+/** prevent waiting for a task from inside a task */
+#if defined DBG_UTIL && defined LINUX
+static thread_local bool gbIsWorkerThread;
+#endif
+
+// used to group thread-tasks for waiting in waitTillDone()
+class COMPHELPER_DLLPUBLIC ThreadTaskTag
+{
+ oslInterlockedCount mnTasksWorking;
+ osl::Condition maTasksComplete;
+
+public:
+ ThreadTaskTag();
+ bool isDone();
+ void waitUntilDone();
+ void onTaskWorkerDone();
+ void onTaskPushed();
+};
+
+
class ThreadPool::ThreadWorker : public salhelper::Thread
{
ThreadPool *mpPool;
@@ -33,11 +54,36 @@ public:
virtual void execute() override
{
+#if defined DBG_UTIL && defined LINUX
+ gbIsWorkerThread = true;
+#endif
ThreadTask *pTask;
while ( ( pTask = waitForWork() ) )
{
- pTask->doWork();
- delete pTask;
+ std::shared_ptr<ThreadTaskTag> pTag(pTask->getTag());
+ try {
+ pTask->doWork();
+ }
+ catch (const std::exception &e)
+ {
+ SAL_WARN("comphelper", "exception in thread worker while calling doWork(): " << e.what());
+ }
+ catch (const css::uno::Exception &e)
+ {
+ SAL_WARN("comphelper", "exception in thread worker while calling doWork(): " << e.Message);
+ }
+ try {
+ delete pTask;
+ }
+ catch (const std::exception &e)
+ {
+ SAL_WARN("comphelper", "exception in thread worker while deleting task: " << e.what());
+ }
+ catch (const css::uno::Exception &e)
+ {
+ SAL_WARN("comphelper", "exception in thread worker while deleting task: " << e.Message);
+ }
+ pTag->onTaskWorkerDone();
}
}
@@ -149,9 +195,27 @@ sal_Int32 ThreadPool::getPreferredConcurrency()
void ThreadPool::waitAndCleanupWorkers()
{
- waitUntilEmpty();
-
osl::ResettableMutexGuard aGuard( maGuard );
+
+ if( maWorkers.empty() )
+ { // no threads at all -> execute the work in-line
+ ThreadTask *pTask;
+ while ( ( pTask = popWork() ) )
+ {
+ std::shared_ptr<ThreadTaskTag> pTag(pTask->getTag());
+ pTask->doWork();
+ delete pTask;
+ pTag->onTaskWorkerDone();
+ }
+ }
+ else
+ {
+ aGuard.clear();
+ maTasksComplete.wait();
+ aGuard.reset();
+ }
+ assert( maTasks.empty() );
+
mbTerminate = true;
while( !maWorkers.empty() )
@@ -173,6 +237,7 @@ void ThreadPool::waitAndCleanupWorkers()
void ThreadPool::pushTask( ThreadTask *pTask )
{
osl::MutexGuard aGuard( maGuard );
+ pTask->mpTag->onTaskPushed();
maTasks.insert( maTasks.begin(), pTask );
// horrible beyond belief:
@@ -205,8 +270,11 @@ void ThreadPool::stopWork()
maTasksComplete.set();
}
-void ThreadPool::waitUntilEmpty()
+void ThreadPool::waitUntilDone(const std::shared_ptr<ThreadTaskTag>& rTag)
{
+#if defined DBG_UTIL && defined LINUX
+ assert(!gbIsWorkerThread && "cannot wait for tasks from inside a task");
+#endif
osl::ResettableMutexGuard aGuard( maGuard );
if( maWorkers.empty() )
@@ -214,17 +282,78 @@ void ThreadPool::waitUntilEmpty()
ThreadTask *pTask;
while ( ( pTask = popWork() ) )
{
+ std::shared_ptr<ThreadTaskTag> pTag(pTask->getTag());
pTask->doWork();
delete pTask;
+ pTag->onTaskWorkerDone();
}
}
- else
+ aGuard.clear();
+ rTag->waitUntilDone();
+}
+
+std::shared_ptr<ThreadTaskTag> ThreadPool::createThreadTaskTag()
+{
+ return std::make_shared<ThreadTaskTag>();
+}
+
+bool ThreadPool::isTaskTagDone(const std::shared_ptr<ThreadTaskTag>& pTag)
+{
+ return pTag->isDone();
+}
+
+
+ThreadTask::ThreadTask(const std::shared_ptr<ThreadTaskTag>& pTag)
+ : mpTag(pTag)
+{
+}
+
+ThreadTaskTag::ThreadTaskTag() : mnTasksWorking(0)
+{
+ maTasksComplete.set();
+}
+
+void ThreadTaskTag::onTaskPushed()
+{
+ oslInterlockedCount n = osl_atomic_increment(&mnTasksWorking);
+ assert( n < 65536 ); // sanity checking
+ (void)n; // avoid -Wunused-variable in release build
+ maTasksComplete.reset();
+}
+
+void ThreadTaskTag::onTaskWorkerDone()
+{
+ sal_Int32 nCount = osl_atomic_decrement(&mnTasksWorking);
+ assert(nCount >= 0);
+ if (nCount == 0)
+ maTasksComplete.set();
+}
+
+void ThreadTaskTag::waitUntilDone()
+{
+#if defined DBG_UTIL && defined LINUX
+ assert(!gbIsWorkerThread && "cannot wait for tasks from inside a task");
+#endif
+
+#ifdef DBG_UTIL
+ // 2 minute timeout in debug mode so our tests fail sooner rather than later
+ osl::Condition::Result rv = maTasksComplete.wait(TimeValue { 2*60, 0 });
+ assert(rv != osl_cond_result_timeout);
+#else
+ // 10 minute timeout in production so the app eventually throws some kind of error
+ if (maTasksComplete.wait(TimeValue { 10*60, 0 }) == osl_cond_result_timeout)
{
- aGuard.clear();
- maTasksComplete.wait();
- aGuard.reset();
+ SAL_DEBUG_TRACE("comphelper::ThreadTaskTag::waitUntilDone() "
+ << "tasksWorking " << mnTasksWorking
+ << "noThreads " << ThreadPool::getPreferredConcurrency());
+ throw std::runtime_error("timeout waiting for threadpool tasks");
}
- assert( maTasks.empty() );
+#endif
+}
+
+bool ThreadTaskTag::isDone()
+{
+ return mnTasksWorking == 0;
}
} // namespace comphelper
diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
index 68acb57ff5d6..b87df2739280 100644
--- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
@@ -400,9 +400,11 @@ namespace drawinglayer
public:
explicit Executor(
+ std::shared_ptr<comphelper::ThreadTaskTag>& rTag,
processor3d::ZBufferProcessor3D* pZBufferProcessor3D,
const primitive3d::Primitive3DContainer& rChildren3D)
- : mpZBufferProcessor3D(pZBufferProcessor3D),
+ : comphelper::ThreadTask(rTag),
+ mpZBufferProcessor3D(pZBufferProcessor3D),
mrChildren3D(rChildren3D)
{
}
@@ -417,6 +419,7 @@ namespace drawinglayer
std::vector< processor3d::ZBufferProcessor3D* > aProcessors;
const sal_uInt32 nLinesPerThread(aBZPixelRaster.getHeight() / nThreadCount);
+ std::shared_ptr<comphelper::ThreadTaskTag> aTag = comphelper::ThreadPool::createThreadTaskTag();
for(sal_Int32 a(0); a < nThreadCount; a++)
{
@@ -432,11 +435,11 @@ namespace drawinglayer
nLinesPerThread * a,
a + 1 == nThreadCount ? aBZPixelRaster.getHeight() : nLinesPerThread * (a + 1));
aProcessors.push_back(pNewZBufferProcessor3D);
- Executor* pExecutor = new Executor(pNewZBufferProcessor3D, getChildren3D());
+ Executor* pExecutor = new Executor(aTag, pNewZBufferProcessor3D, getChildren3D());
rThreadPool.pushTask(pExecutor);
}
- rThreadPool.waitUntilEmpty();
+ rThreadPool.waitUntilDone(aTag);
}
else
{
diff --git a/include/comphelper/threadpool.hxx b/include/comphelper/threadpool.hxx
index 2f726f0b406f..93f6b59ee9de 100644
--- a/include/comphelper/threadpool.hxx
+++ b/include/comphelper/threadpool.hxx
@@ -15,17 +15,24 @@
#include <osl/mutex.hxx>
#include <osl/conditn.hxx>
#include <rtl/ref.hxx>
-#include <vector>
#include <comphelper/comphelperdllapi.h>
+#include <vector>
+#include <memory>
namespace comphelper
{
+class ThreadTaskTag;
+class ThreadPool;
class COMPHELPER_DLLPUBLIC ThreadTask
{
+friend class ThreadPool;
+ std::shared_ptr<ThreadTaskTag> mpTag;
public:
+ ThreadTask(const std::shared_ptr<ThreadTaskTag>& pTag);
virtual ~ThreadTask() {}
virtual void doWork() = 0;
+ const std::shared_ptr<ThreadTaskTag>& getTag() { return mpTag; }
};
/// A very basic thread pool implementation
@@ -36,20 +43,24 @@ public:
/// count for the CPU
static ThreadPool& getSharedOptimalPool();
+ static std::shared_ptr<ThreadTaskTag> createThreadTaskTag();
+
+ static bool isTaskTagDone(const std::shared_ptr<ThreadTaskTag>&);
+
/// returns a configurable max-concurrency
/// limit to avoid spawning an unnecessarily
/// large number of threads on high-core boxes.
/// MAX_CONCURRENCY envar controls the cap.
static sal_Int32 getPreferredConcurrency();
- ThreadPool( sal_Int32 nWorkers );
+ ThreadPool( sal_Int32 nWorkers );
virtual ~ThreadPool();
/// push a new task onto the work queue
void pushTask( ThreadTask *pTask /* takes ownership */ );
- /// wait until all queued tasks are completed
- void waitUntilEmpty();
+ /// wait until all queued tasks associated with the tag are completed
+ void waitUntilDone(const std::shared_ptr<ThreadTaskTag>&);
/// return the number of live worker threads
sal_Int32 getWorkerCount() const { return maWorkers.size(); }
diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
index 136bc72b249d..1fc41661d186 100644
--- a/package/inc/ZipOutputStream.hxx
+++ b/package/inc/ZipOutputStream.hxx
@@ -35,10 +35,10 @@ class ZipOutputStream
{
css::uno::Reference< css::io::XOutputStream > m_xStream;
::std::vector < ZipEntry * > m_aZipList;
+ std::shared_ptr<comphelper::ThreadTaskTag> mpThreadTaskTag;
ByteChucker m_aChucker;
ZipEntry *m_pCurrentEntry;
- comphelper::ThreadPool &m_rSharedThreadPool;
std::vector< ZipOutputEntry* > m_aEntries;
::css::uno::Any m_aDeflateException;
@@ -80,6 +80,8 @@ public:
void reduceScheduledThreadsToGivenNumberOrLess(
sal_Int32 nThreads,
sal_Int32 nWaitTimeInTenthSeconds);
+
+ const std::shared_ptr<comphelper::ThreadTaskTag>& getThreadTaskTag() { return mpThreadTaskTag; }
};
#endif
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
index 41f78b414879..7e9ffe5bfc1a 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -42,9 +42,9 @@ using namespace com::sun::star::packages::zip::ZipConstants;
*/
ZipOutputStream::ZipOutputStream( const uno::Reference < io::XOutputStream > &xOStream )
: m_xStream(xOStream)
+, mpThreadTaskTag( comphelper::ThreadPool::createThreadTaskTag() )
, m_aChucker(xOStream)
, m_pCurrentEntry(nullptr)
-, m_rSharedThreadPool(comphelper::ThreadPool::getSharedOptimalPool())
{
}
@@ -70,7 +70,7 @@ void ZipOutputStream::setEntry( ZipEntry *pEntry )
void ZipOutputStream::addDeflatingThread( ZipOutputEntry *pEntry, comphelper::ThreadTask *pThread )
{
- m_rSharedThreadPool.pushTask(pThread);
+ comphelper::ThreadPool::getSharedOptimalPool().pushTask(pThread);
m_aEntries.push_back(pEntry);
}
@@ -178,7 +178,7 @@ void ZipOutputStream::finish()
assert(!m_aZipList.empty() && "Zip file must have at least one entry!");
// Wait for all threads to finish & write
- m_rSharedThreadPool.waitUntilEmpty();
+ comphelper::ThreadPool::getSharedOptimalPool().waitUntilDone(mpThreadTaskTag);
// consume all processed entries
consumeAllScheduledThreadEntries();
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 5efb145fd9f7..e72c3999c9f5 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -466,9 +466,10 @@ class DeflateThread: public comphelper::ThreadTask
uno::Reference< io::XInputStream > mxInStream;
public:
- DeflateThread( ZipOutputEntry *pEntry,
+ DeflateThread( const std::shared_ptr<comphelper::ThreadTaskTag>& pTag, ZipOutputEntry *pEntry,
const uno::Reference< io::XInputStream >& xInStream )
- : mpEntry(pEntry)
+ : comphelper::ThreadTask(pTag)
+ , mpEntry(pEntry)
, mxInStream(xInStream)
{}
@@ -849,7 +850,7 @@ bool ZipPackageStream::saveChild(
// Start a new thread deflating this zip entry
ZipOutputEntry *pZipEntry = new ZipOutputEntry(
m_xContext, *pTempEntry, this, bToBeEncrypted);
- rZipOut.addDeflatingThread( pZipEntry, new DeflateThread(pZipEntry, xStream) );
+ rZipOut.addDeflatingThread( pZipEntry, new DeflateThread(rZipOut.getThreadTaskTag(), pZipEntry, xStream) );
}
else
{
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index 29f636ed75e0..f7cba244e577 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -2116,8 +2116,10 @@ class RowFinalizeTask : public comphelper::ThreadTask
const ScfUInt16Vec& mrColXFIndexes;
std::vector< XclExpRow * > maRows;
public:
- RowFinalizeTask( const ScfUInt16Vec& rColXFIndexes,
+ RowFinalizeTask( const std::shared_ptr<comphelper::ThreadTaskTag> pTag,
+ const ScfUInt16Vec& rColXFIndexes,
bool bProgress ) :
+ comphelper::ThreadTask( pTag ),
mbProgress( bProgress ),
mrColXFIndexes( rColXFIndexes ) {}
virtual ~RowFinalizeTask() {}
@@ -2152,9 +2154,10 @@ void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt
else
{
comphelper::ThreadPool &rPool = comphelper::ThreadPool::getSharedOptimalPool();
+ std::shared_ptr<comphelper::ThreadTaskTag> pTag = comphelper::ThreadPool::createThreadTaskTag();
std::vector<RowFinalizeTask*> aTasks(nThreads, nullptr);
for ( size_t i = 0; i < nThreads; i++ )
- aTasks[ i ] = new RowFinalizeTask( rColXFIndexes, i == 0 );
+ aTasks[ i ] = new RowFinalizeTask( pTag, rColXFIndexes, i == 0 );
RowMap::iterator itr, itrBeg = maRowMap.begin(), itrEnd = maRowMap.end();
size_t nIdx = 0;
@@ -2167,7 +2170,7 @@ void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt
// Progress bar updates must be synchronous to avoid deadlock
aTasks[0]->doWork();
- rPool.waitUntilEmpty();
+ rPool.waitUntilDone(pTag);
}
// *** Default row format *** ---------------------------------------------
diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index 6e6e101f0c48..88f694853e0a 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -225,9 +225,11 @@ class WorkerThread : public comphelper::ThreadTask
rtl::Reference<FragmentHandler> mxHandler;
public:
- WorkerThread( WorkbookFragment& rWorkbookHandler,
+ WorkerThread( const std::shared_ptr<comphelper::ThreadTaskTag> pTag,
+ WorkbookFragment& rWorkbookHandler,
const rtl::Reference<FragmentHandler>& xHandler,
sal_Int32 &rSheetsLeft ) :
+ comphelper::ThreadTask( pTag ),
mrSheetsLeft( rSheetsLeft ),
mrWorkbookHandler( rWorkbookHandler ),
mxHandler( xHandler )
@@ -309,54 +311,38 @@ public:
void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVector& rSheets )
{
- sal_Int32 nThreads = std::min( rSheets.size(), (size_t) comphelper::ThreadPool::getPreferredConcurrency() );
-
Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
- const char *pEnv;
- if( ( pEnv = getenv( "SC_IMPORT_THREADS" ) ) )
- nThreads = rtl_str_toInt32( pEnv, 10 );
-
- if( nThreads != 0 )
- {
- // test sequential read in this mode
- if( nThreads < 0)
- nThreads = 0;
- comphelper::ThreadPool aPool( nThreads );
-
- sal_Int32 nSheetsLeft = 0;
- ProgressBarTimer aProgressUpdater;
- SheetFragmentVector::iterator it = rSheets.begin(), itEnd = rSheets.end();
- for( ; it != itEnd; ++it )
- {
- // getting at the WorksheetGlobals is rather unpleasant
- IWorksheetProgress *pProgress = WorksheetHelper::getWorksheetInterface( it->first );
- pProgress->setCustomRowProgress(
- aProgressUpdater.wrapProgress(
- pProgress->getRowProgress() ) );
- aPool.pushTask( new WorkerThread( rWorkbookHandler, it->second,
- /* ref */ nSheetsLeft ) );
- nSheetsLeft++;
- }
-
- // coverity[loop_top] - this isn't an infinite loop where nSheetsLeft gets decremented by the above threads
- while( nSheetsLeft > 0)
- {
- // This is a much more controlled re-enterancy hazard than
- // allowing a yield deeper inside the filter code for progress
- // bar updating.
- Application::Yield();
- }
- aPool.waitUntilEmpty();
+ // test sequential read in this mode
+ comphelper::ThreadPool &rSharedPool = comphelper::ThreadPool::getSharedOptimalPool();
+ std::shared_ptr<comphelper::ThreadTaskTag> pTag = comphelper::ThreadPool::createThreadTaskTag();
- // threads joined in ThreadPool destructor
- }
- else // single threaded iteration
+ sal_Int32 nSheetsLeft = 0;
+ ProgressBarTimer aProgressUpdater;
+ SheetFragmentVector::iterator it = rSheets.begin(), itEnd = rSheets.end();
+ for( ; it != itEnd; ++it )
{
- SheetFragmentVector::iterator it = rSheets.begin(), itEnd = rSheets.end();
- for( ; it != itEnd; ++it )
- rWorkbookHandler.importOoxFragment( it->second );
- }
+ // getting at the WorksheetGlobals is rather unpleasant
+ IWorksheetProgress *pProgress = WorksheetHelper::getWorksheetInterface( it->first );
+ pProgress->setCustomRowProgress(
+ aProgressUpdater.wrapProgress(
+ pProgress->getRowProgress() ) );
+ rSharedPool.pushTask( new WorkerThread( pTag, rWorkbookHandler, it->second,
+ /* ref */ nSheetsLeft ) );
+ nSheetsLeft++;
+ }
+
+ // coverity[loop_top] - this isn't an infinite loop where nSheetsLeft gets decremented by the above threads
+ while( nSheetsLeft > 0)
+ {
+ // This is a much more controlled re-enterancy hazard than
+ // allowing a yield deeper inside the filter code for progress
+ // bar updating.
+ Application::Yield();
+ }
+ rSharedPool.waitUntilDone(pTag);
+
+ // threads joined in ThreadPool destructor
}
}
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index 9863cc93f5a8..416089205b48 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -643,38 +643,9 @@ bool SwOLENode::IsChart() const
return bIsChart;
}
-// due to some problems in test cases with the SharedOptimalPool, use
-// an own instance of comphelper::ThreadPool. Problem is that other
-// usages of getSharedOptimalPool() may interfere if more than one
-// pool user calls waitUntilEmpty().
-//
-// It gets created on-demand and will be available during LO's
-// lifetime for loading chart models used in writer in parallel. It
-// would be possible to add a usage count, then trigger a timer and
-// clean it up (due to lifetime issues), but that's probably overkill.
-// It gets created on demand, is ready for global reuse and makes no
-// harm (not much ressources needed)
-static comphelper::ThreadPool* pLocalPool = nullptr;
-
-comphelper::ThreadPool* getLocalThreadPool()
-{
- if (pLocalPool)
- {
- return pLocalPool;
- }
-
- if (0 == comphelper::ThreadPool::getSharedOptimalPool().getWorkerCount())
- {
- return nullptr;
- }
-
- pLocalPool = new comphelper::ThreadPool(comphelper::ThreadPool::getSharedOptimalPool().getWorkerCount());
- return pLocalPool;
-}
-
namespace { class DeflateThread; }
-/// Holder for local data for a parallely-executed task to load a chart model
+/// Holder for local data for a parallel-executed task to load a chart model
class DeflateData
{
private:
@@ -685,21 +656,20 @@ private:
drawinglayer::primitive2d::Primitive2DContainer maPrimitive2DSequence;
basegfx::B2DRange maRange;
- // set from the WorkerThread when done
- std::atomic< bool> mbFinished;
-
// evtl.set from the SwOLEObj destructor when a WorkerThread is still active
// since it is not possible to kill it - let it terminate and delete the
// data working on itself
std::atomic< bool> mbKilled;
+ std::shared_ptr<comphelper::ThreadTaskTag> mpTag;
+
public:
DeflateData(const uno::Reference< frame::XModel >& rXModel)
: maXModel(rXModel),
maPrimitive2DSequence(),
maRange(),
- mbFinished(false),
- mbKilled(false)
+ mbKilled(false),
+ mpTag( comphelper::ThreadPool::createThreadTaskTag() )
{
}
@@ -715,12 +685,12 @@ public:
bool isFinished() const
{
- return mbFinished;
+ return comphelper::ThreadPool::isTaskTagDone(mpTag);
}
void waitFinished()
{
- while(!mbFinished && !mbKilled)
+ while(!isFinished() && !mbKilled)
{
// need to wait until the load in progress is finished.
// to do so, Application::Yield() is needed since the execution
@@ -729,6 +699,7 @@ public:
// the running import
Application::Yield();
}
+ comphelper::ThreadPool::getSharedOptimalPool().waitUntilDone(mpTag);
}
};
@@ -742,7 +713,7 @@ class DeflateThread : public comphelper::ThreadTask
public:
DeflateThread(DeflateData& rDeflateData)
- : mrDeflateData(rDeflateData)
+ : comphelper::ThreadTask(rDeflateData.mpTag), mrDeflateData(rDeflateData)
{
}
@@ -758,7 +729,6 @@ private:
// model no longer needed and done
mrDeflateData.maXModel.clear();
- mrDeflateData.mbFinished = true;
}
catch (const uno::Exception&)
{
@@ -1081,16 +1051,11 @@ drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAs
if(aXModel.is())
{
- // loaded using own instance of comphelper::ThreadPool,
- // see getLocalThreadPool(). Disable via bool below if
- // trouble surfaces somewhere
-
// disabled fro now, need to check deeper
- static bool bAnynchronousLoadingAllowed = false;
+ static bool bAsynchronousLoadingAllowed = false;
if(bSynchron ||
- !bAnynchronousLoadingAllowed ||
- nullptr == getLocalThreadPool())
+ !bAsynchronousLoadingAllowed)
{
// load chart synchron in this Thread
m_aPrimitive2DSequence = ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
@@ -1106,7 +1071,7 @@ drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAs
{
m_pDeflateData = new DeflateData(aXModel);
DeflateThread* pNew = new DeflateThread(*m_pDeflateData);
- getLocalThreadPool()->pushTask(pNew);
+ comphelper::ThreadPool::getSharedOptimalPool().pushTask(pNew);
}
}
}
diff --git a/vcl/source/bitmap/bitmapscalesuper.cxx b/vcl/source/bitmap/bitmapscalesuper.cxx
index 9fb1f44a0f9c..ff01aaebdab5 100644
--- a/vcl/source/bitmap/bitmapscalesuper.cxx
+++ b/vcl/source/bitmap/bitmapscalesuper.cxx
@@ -89,7 +89,8 @@ class ScaleTask : public comphelper::ThreadTask
ScaleRangeFn mpFn;
std::vector< ScaleRangeContext > maStrips;
public:
- explicit ScaleTask( ScaleRangeFn pFn ) : mpFn( pFn ) {}
+ explicit ScaleTask( const std::shared_ptr<comphelper::ThreadTaskTag>& pTag, ScaleRangeFn pFn )
+ : comphelper::ThreadTask(pTag), mpFn( pFn ) {}
void push( ScaleRangeContext &aRC ) { maStrips.push_back( aRC ); }
virtual void doWork() override
{
@@ -1000,6 +1001,7 @@ bool BitmapScaleSuper::filter(Bitmap& rBitmap)
{
// partition and queue work
comphelper::ThreadPool &rShared = comphelper::ThreadPool::getSharedOptimalPool();
+ std::shared_ptr<comphelper::ThreadTaskTag> pTag = comphelper::ThreadPool::createThreadTaskTag();
sal_uInt32 nThreads = rShared.getWorkerCount();
assert( nThreads > 0 );
sal_uInt32 nStrips = ((nEndY - nStartY) + SCALE_THREAD_STRIP - 1) / SCALE_THREAD_STRIP;
@@ -1008,7 +1010,7 @@ bool BitmapScaleSuper::filter(Bitmap& rBitmap)
long nStripY = nStartY;
for ( sal_uInt32 t = 0; t < nThreads - 1; t++ )
{
- ScaleTask *pTask = new ScaleTask( pScaleRangeFn );
+ ScaleTask *pTask = new ScaleTask( pTag, pScaleRangeFn );
for ( sal_uInt32 j = 0; j < nStripsPerThread; j++ )
{
ScaleRangeContext aRC( &aContext, nStripY );
@@ -1020,7 +1022,7 @@ bool BitmapScaleSuper::filter(Bitmap& rBitmap)
// finish any remaining bits here
pScaleRangeFn( aContext, nStripY, nEndY );
- rShared.waitUntilEmpty();
+ rShared.waitUntilDone(pTag);
SAL_INFO("vcl.gdi", "All threaded scaling tasks complete");
}