comphelper/Library_comphelper.mk | 1 comphelper/source/misc/threadpool.cxx | 182 ++++++++++++++++++++++++++++++ include/comphelper/threadpool.hxx | 69 +++++++++++ sc/Library_scfilt.mk | 1 sc/source/filter/oox/threadpool.cxx | 164 --------------------------- sc/source/filter/oox/threadpool.hxx | 53 -------- sc/source/filter/oox/workbookfragment.cxx | 11 - 7 files changed, 258 insertions(+), 223 deletions(-)
New commits: commit 593a44a12dbdc00a9f116efc754e3e17dff5dec6 Author: Michael Meeks <[email protected]> Date: Thu Oct 30 21:58:36 2014 +0000 thread-pool: re-work termination semantics to avoid problems. We want a pre-spun-up, shared thread-pool that doesn't get its workers created & joined frequently. Change-Id: I29081e3a3e3849ca30e63fd080ee3315d99cbe8d diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx index d2101ad..236a314 100644 --- a/comphelper/source/misc/threadpool.cxx +++ b/comphelper/source/misc/threadpool.cxx @@ -92,7 +92,7 @@ ThreadPool::ThreadPool( sal_Int32 nWorkers ) : ThreadPool::~ThreadPool() { - waitUntilWorkersDone(); + waitAndCleanupWorkers(); } struct ThreadPoolStatic : public rtl::StaticWithInit< boost::shared_ptr< ThreadPool >, @@ -109,9 +109,7 @@ ThreadPool& ThreadPool::getSharedOptimalPool() return *ThreadPoolStatic::get().get(); } -/// wait until all the workers have completed and -/// terminate all threads -void ThreadPool::waitUntilWorkersDone() +void ThreadPool::waitAndCleanupWorkers() { waitUntilEmpty(); @@ -169,7 +167,6 @@ void ThreadPool::waitUntilEmpty() pTask->doWork(); delete pTask; } - mbTerminate = true; } else { diff --git a/include/comphelper/threadpool.hxx b/include/comphelper/threadpool.hxx index ae103f1..2e51719 100644 --- a/include/comphelper/threadpool.hxx +++ b/include/comphelper/threadpool.hxx @@ -39,14 +39,19 @@ public: 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(); - void waitUntilWorkersDone(); private: class ThreadWorker; friend class ThreadWorker; + /// wait until all work is completed, then join all threads + void waitAndCleanupWorkers(); + ThreadTask *waitForWork( osl::Condition &rNewWork ); ThreadTask *popWork(); diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx index 62ea5bb..8488b46 100644 --- a/sc/source/filter/oox/workbookfragment.cxx +++ b/sc/source/filter/oox/workbookfragment.cxx @@ -336,8 +336,9 @@ void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVect // bar updating. Application::Yield(); } - // join all the threads: - aPool.waitUntilWorkersDone(); + aPool.waitUntilEmpty(); + + // threads joined in ThreadPool destructor } else // single threaded iteration { commit 62090f65b804a08a66ca26675ae610ed07c7c341 Author: Michael Meeks <[email protected]> Date: Thu Oct 30 18:37:42 2014 +0000 Move thread-pool down into comphelper for re-use elsewhere. Change-Id: Ib27b8b1ccc07ff194035d6c2ef3d45c429e3cea1 diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk index cfe48f6..84bf698 100644 --- a/comphelper/Library_comphelper.mk +++ b/comphelper/Library_comphelper.mk @@ -114,6 +114,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\ comphelper/source/misc/string \ comphelper/source/misc/synchronousdispatch \ comphelper/source/misc/syntaxhighlight \ + comphelper/source/misc/threadpool \ comphelper/source/misc/types \ comphelper/source/misc/weak \ comphelper/source/misc/weakeventlistener \ diff --git a/sc/source/filter/oox/threadpool.cxx b/comphelper/source/misc/threadpool.cxx similarity index 84% rename from sc/source/filter/oox/threadpool.cxx rename to comphelper/source/misc/threadpool.cxx index 3fcfa75..d2101ad 100644 --- a/sc/source/filter/oox/threadpool.cxx +++ b/comphelper/source/misc/threadpool.cxx @@ -7,17 +7,22 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "threadpool.hxx" +#include <comphelper/threadpool.hxx> +#include <rtl/instance.hxx> +#include <boost/shared_ptr.hpp> +#include <thread> #include <algorithm> +namespace comphelper { + class ThreadPool::ThreadWorker : public salhelper::Thread { ThreadPool *mpPool; osl::Condition maNewWork; public: ThreadWorker( ThreadPool *pPool ) : - salhelper::Thread("sheet-import-thread-pool"), + salhelper::Thread("thread-pool"), mpPool( pPool ) {} virtual void execute() SAL_OVERRIDE @@ -90,6 +95,20 @@ ThreadPool::~ThreadPool() waitUntilWorkersDone(); } +struct ThreadPoolStatic : public rtl::StaticWithInit< boost::shared_ptr< ThreadPool >, + ThreadPoolStatic > +{ + boost::shared_ptr< ThreadPool > operator () () { + sal_Int32 nThreads = std::max( std::thread::hardware_concurrency(), 1U ); + return boost::shared_ptr< ThreadPool >( new ThreadPool( nThreads ) ); + }; +}; + +ThreadPool& ThreadPool::getSharedOptimalPool() +{ + return *ThreadPoolStatic::get().get(); +} + /// wait until all the workers have completed and /// terminate all threads void ThreadPool::waitUntilWorkersDone() @@ -161,4 +180,6 @@ void ThreadPool::waitUntilEmpty() assert( maTasks.empty() ); } +} // namespace comphelper + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/oox/threadpool.hxx b/include/comphelper/threadpool.hxx similarity index 73% rename from sc/source/filter/oox/threadpool.hxx rename to include/comphelper/threadpool.hxx index 19b524c..ae103f1 100644 --- a/sc/source/filter/oox/threadpool.hxx +++ b/include/comphelper/threadpool.hxx @@ -7,8 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_SC_SOURCE_FILTER_OOX_THREADPOOL_HXX -#define INCLUDED_SC_SOURCE_FILTER_OOX_THREADPOOL_HXX +#ifndef INCLUDED_COMPHELPER_THREADPOOL_HXX +#define INCLUDED_COMPHELPER_THREADPOOL_HXX #include <sal/config.h> #include <salhelper/thread.hxx> @@ -16,8 +16,12 @@ #include <osl/conditn.hxx> #include <rtl/ref.hxx> #include <vector> +#include <comphelper/comphelperdllapi.h> -class ThreadTask +namespace comphelper +{ + +class COMPHELPER_DLLPUBLIC ThreadTask { public: virtual ~ThreadTask() {} @@ -25,11 +29,16 @@ public: }; /// A very basic thread pool implementation -class ThreadPool +class COMPHELPER_DLLPUBLIC ThreadPool { public: + /// returns a pointer to a shared pool with optimal thread + /// count for the CPU + static ThreadPool& getSharedOptimalPool(); + ThreadPool( sal_Int32 nWorkers ); virtual ~ThreadPool(); + void pushTask( ThreadTask *pTask /* takes ownership */ ); void waitUntilEmpty(); void waitUntilWorkersDone(); @@ -48,6 +57,8 @@ private: std::vector< ThreadTask * > maTasks; }; -#endif // INCLUDED_SC_SOURCE_FILTER_OOX_THREADPOOL_HXX +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_THREADPOOL_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/Library_scfilt.mk b/sc/Library_scfilt.mk index 00d32da..77c8486 100644 --- a/sc/Library_scfilt.mk +++ b/sc/Library_scfilt.mk @@ -214,7 +214,6 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\ sc/source/filter/oox/tablebuffer \ sc/source/filter/oox/tablefragment \ sc/source/filter/oox/themebuffer \ - sc/source/filter/oox/threadpool \ sc/source/filter/oox/unitconverter \ sc/source/filter/oox/viewsettings \ sc/source/filter/oox/workbookfragment \ diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx index 26bf3b4..62ea5bb 100644 --- a/sc/source/filter/oox/workbookfragment.cxx +++ b/sc/source/filter/oox/workbookfragment.cxx @@ -46,7 +46,6 @@ #include "worksheethelper.hxx" #include "worksheetfragment.hxx" #include "sheetdatacontext.hxx" -#include "threadpool.hxx" #include "officecfg/Office/Common.hxx" #include "document.hxx" @@ -58,6 +57,7 @@ #include <oox/core/fastparser.hxx> #include <salhelper/thread.hxx> +#include <comphelper/threadpool.hxx> #include <osl/conditn.hxx> #include <algorithm> @@ -207,7 +207,7 @@ namespace { typedef std::pair<WorksheetGlobalsRef, FragmentHandlerRef> SheetFragmentHandler; typedef std::vector<SheetFragmentHandler> SheetFragmentVector; -class WorkerThread : public ThreadTask +class WorkerThread : public comphelper::ThreadTask { sal_Int32 &mrSheetsLeft; WorkbookFragment& mrWorkbookHandler; @@ -311,7 +311,7 @@ void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVect // test sequential read in this mode if( nThreads < 0) nThreads = 0; - ThreadPool aPool( nThreads ); + comphelper::ThreadPool aPool( nThreads ); sal_Int32 nSheetsLeft = 0; ProgressBarTimer aProgressUpdater; _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
