From kde-commits Thu Oct 31 22:58:28 2013 From: Mirko Boehm (Endocode) Date: Thu, 31 Oct 2013 22:58:28 +0000 To: kde-commits Subject: [kdelibs/frameworks] tier1/threadweaver/src/Weaver: Add convenience API for queueing and creating jo Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=138326031808330 Git commit da4da04f5a2c341cbe246a96b8f21fa178c98152 by Mirko Boehm (Endocod= e). Committed on 31/10/2013 at 21:18. Pushed by mirko into branch 'frameworks'. Add convenience API for queueing and creating job objects. Move Weaver class into it=C2=B4s own file. Make ThreadWeaver.h the catch-all header to include the most important ThreadWeaver components. M +4 -2 tier1/threadweaver/src/Weaver/CMakeLists.txt A +101 -0 tier1/threadweaver/src/Weaver/Queueing.h [License: UNKNO= WN] * M +0 -190 tier1/threadweaver/src/Weaver/ThreadWeaver.cpp M +7 -86 tier1/threadweaver/src/Weaver/ThreadWeaver.h C +2 -29 tier1/threadweaver/src/Weaver/Weaver.cpp [from: tier1/thread= weaver/src/Weaver/ThreadWeaver.cpp - 082% similarity] C +5 -3 tier1/threadweaver/src/Weaver/Weaver.h [from: tier1/threadwe= aver/src/Weaver/ThreadWeaver.h - 097% similarity] [License: UNKNOWN] * The files marked with a * at the end have a non valid license. Please read:= http://techbase.kde.org/Policies/Licensing_Policy and use the headers whic= h are listed at that page. http://commits.kde.org/kdelibs/da4da04f5a2c341cbe246a96b8f21fa178c98152 diff --git a/tier1/threadweaver/src/Weaver/CMakeLists.txt b/tier1/threadwea= ver/src/Weaver/CMakeLists.txt index cb37999..ce20785 100644 --- a/tier1/threadweaver/src/Weaver/CMakeLists.txt +++ b/tier1/threadweaver/src/Weaver/CMakeLists.txt @@ -3,7 +3,7 @@ set(ThreadWeaver_LIB_SRCS Queue.cpp QueueAPI.cpp - ThreadWeaver.cpp + Weaver.cpp WeaverImpl.cpp DebuggingAids.cpp Thread.cpp @@ -46,8 +46,10 @@ set_target_properties(ThreadWeaver PROPERTIES install(TARGETS ThreadWeaver EXPORT ThreadWeaverTargets ${INSTALL_TARGETS_= DEFAULT_ARGS}) = install(FILES - WeaverInterface.h ThreadWeaver.h + Queueing.h + WeaverInterface.h + Weaver.h DebuggingAids.h Thread.h JobInterface.h diff --git a/tier1/threadweaver/src/Weaver/Queueing.h b/tier1/threadweaver/= src/Weaver/Queueing.h new file mode 100644 index 0000000..919d4f6 --- /dev/null +++ b/tier1/threadweaver/src/Weaver/Queueing.h @@ -0,0 +1,101 @@ +#ifndef THREADWEAVER_QUEUEING_H +#define THREADWEAVER_QUEUEING_H + +#include "JobPointer.h" +#include "ManagedJobPointer.h" +#include "JobInterface.h" +#include "JobCollection.h" +#include "Lambda.h" +#include "QObjectDecorator.h" +#include "Weaver.h" + +namespace ThreadWeaver { +namespace Queueing { + +// make a job that calls a functor, anything that responds to operator[] +template +JobPointer make_job(T t) { + JobPointer ret(new Lambda(t)); + return ret; +} + +// make a job pointer holding a pointer to a Job(Interface) +template<> +inline JobPointer make_job(JobInterface* job) { + return JobPointer(job); +} + +// enqueue any functor type to the specified queue: +template +JobPointer enqueue(Weaver* weaver, T t) { + JobPointer ret =3D make_job(t); + weaver->enqueue(ret); + return ret; +} + +// specialise for QObjectDecorator: +template<> +inline JobPointer enqueue(Weaver* weaver, QObjectDecora= tor* q) { + JobPointer ret(q); + weaver->enqueue(ret); + return ret; +} + +// specialise for JobPointer: +template<> +inline JobPointer enqueue(Weaver* weaver, JobPointer job) { + weaver->enqueue(job); + return job; +} + +//// specialise for JobInterface: +//template<> +//JobPointer enqueue(Weaver* weaver, JobInterface* job) { +// return enqueue(weaver, make_job(job)); +//} + +//// specialise for Collection: +//template<> +//JobPointer enqueue(Weaver* weaver, JobCollection* job) { +// return enqueue(weaver, make_job(job)); +//} + +//// specialise for Sequence: +//template<> +//JobPointer enqueue(Weaver* weaver, JobSequence* job) { +// return enqueue(weaver, make_job(job)); +//} + +// convenience overload: enqueue the functor to the global queue: +template +JobPointer enqueue(T t) { + return enqueue(Weaver::instance(), t); +} + +// enqueue a raw pointer with no memory management +template +JobPointer enqueue_raw(Weaver* weaver, T* t) { + ManagedJobPointer ret(t); + weaver->enqueue(ret); + return ret; +} + +// create a QObjectDecorator decorating the job +inline QObjectDecorator* decorate_q(JobInterface* job) { + return new QObjectDecorator(job); +} + +} +} + +inline ThreadWeaver::JobCollection& operator<<(ThreadWeaver::JobCollection= & collection, ThreadWeaver::JobInterface* job) { + collection.addJob(ThreadWeaver::Queueing::make_job(job)); + return collection; +} + +inline ThreadWeaver::JobCollection& operator<<(ThreadWeaver::JobCollection= & collection, const ThreadWeaver::JobPointer& job) { + collection.addJob(job); + return collection; +} + +#endif // THREADWEAVER_QUEUEING_H diff --git a/tier1/threadweaver/src/Weaver/ThreadWeaver.cpp b/tier1/threadw= eaver/src/Weaver/ThreadWeaver.cpp index 6704a59..65442d0 100644 --- a/tier1/threadweaver/src/Weaver/ThreadWeaver.cpp +++ b/tier1/threadweaver/src/Weaver/ThreadWeaver.cpp @@ -27,193 +27,3 @@ http://creative-destruction.me $ = #include "ThreadWeaver.h" = -#include -#include - -#include "WeaverImpl.h" -#include "WeaverObserver.h" - -using namespace ThreadWeaver; - -class Weaver::Private -{ -public: - Private () - : implementation(0) - {} - - Queue* implementation; -}; - -Weaver::Weaver(QObject* parent) - : Queue(parent) - , d(new Private) -{ - d->implementation =3D makeWeaverImpl(); - //FIXME move to makeWeaverImpl(), so that implementations can be repla= ced - connect(d->implementation, SIGNAL (finished()), SIGNAL (finished())); - connect(d->implementation, SIGNAL (suspended()), SIGNAL (suspended())); - connect(d->implementation, SIGNAL (jobDone(ThreadWeaver::JobPointer)), - SIGNAL(jobDone(ThreadWeaver::JobPointer))); -} - -Weaver::~Weaver() -{ - if (d->implementation->state()->stateId()!=3DDestructed) { - d->implementation->shutDown(); - } - delete d->implementation; - delete d; -} - -Queue *Weaver::makeWeaverImpl() -{ - Q_ASSERT_X(qApp!=3D0, Q_FUNC_INFO, "Cannot create global ThreadWeaver = instance before QApplication!"); - Queue *queue =3D new WeaverImpl(this); - return queue; -} - -void Weaver::shutDown() -{ - d->implementation->shutDown(); -} - -const State* Weaver::state() const -{ - return d->implementation->state(); -} - -void Weaver::registerObserver ( WeaverObserver *ext ) -{ - d->implementation->registerObserver ( ext ); -} - -namespace { - -class StaticThreadWeaverInstanceGuard : public QObject { - Q_OBJECT -public: - explicit StaticThreadWeaverInstanceGuard(QAtomicPointer& insta= nce, QCoreApplication* app) - : QObject(app) - , instance_(instance) - { - Q_ASSERT_X(app!=3D0, Q_FUNC_INFO, "Calling ThreadWeaver::Weaver::i= nstance() requires a QCoreApplication!"); - QObject* impl =3D instance.load()->findChild(); - Q_ASSERT(impl); - impl->setObjectName(tr("GlobalQueue")); - qAddPostRoutine(shutDownGlobalQueue); - } - - ~StaticThreadWeaverInstanceGuard() { - instance_.fetchAndStoreOrdered(0); - } -private: - static void shutDownGlobalQueue() { - Weaver::instance()->shutDown(); - Q_ASSERT(Weaver::instance()->state()->stateId() =3D=3D Destructed); - } - - QAtomicPointer& instance_; -}; - -} - -/** @brief The application-global Weaver instance. - * This instance will only be created if this method is actually called i= n the lifetime of the application. - * The method will create the Weaver instance on first call. The Q(Core)Ap= plication object must exist at that time. - * The instance will be deleted when Q(Core)Application is destructed. Aft= er that, the instance() method returns zero. */ -Weaver* Weaver::instance() -{ - static QAtomicPointer s_instance(new Weaver(qApp)); - //Order is of importance here: - //When s_instanceGuard is destructed (first, before s_instance), it se= ts the value of s_instance to zero. Next, qApp will delete - //the object s_instance pointed to. - static StaticThreadWeaverInstanceGuard* s_instanceGuard =3D new Static= ThreadWeaverInstanceGuard(s_instance, qApp); - Q_UNUSED(s_instanceGuard); - Q_ASSERT_X(s_instance.load() =3D=3D 0 || s_instance.load()->thread() = =3D=3D QCoreApplication::instance()->thread(), - Q_FUNC_INFO, - "The global ThreadWeaver queue needs to be instantiated (ac= cessed first) from the main thread!"); - return s_instance.loadAcquire(); -} - -void Weaver::enqueue(const JobPointer &job) -{ - d->implementation->enqueue(job); -} - -void Weaver::enqueueRaw(JobInterface *job) -{ - d->implementation->enqueueRaw(job); -} - -bool Weaver::dequeue(const JobPointer& job) -{ - return d->implementation->dequeue(job); -} - -bool Weaver::dequeueRaw(JobInterface* job) -{ - return d->implementation->dequeueRaw(job); -} - -void Weaver::dequeue () -{ - return d->implementation->dequeue(); -} - -void Weaver::finish () -{ - return d->implementation->finish (); -} - -void Weaver::suspend () -{ - return d->implementation->suspend(); -} - -void Weaver::resume () -{ - return d->implementation->resume(); -} - -bool Weaver::isEmpty() const -{ - return d->implementation->isEmpty(); -} - -bool Weaver::isIdle() const -{ - return d->implementation->isIdle(); -} - -int Weaver::queueLength() const -{ - return d->implementation->queueLength(); -} - -void Weaver::setMaximumNumberOfThreads( int cap ) -{ - d->implementation->setMaximumNumberOfThreads( cap ); -} - -int Weaver::currentNumberOfThreads() const -{ - return d->implementation->currentNumberOfThreads(); -} - -int Weaver::maximumNumberOfThreads() const -{ - return d->implementation->maximumNumberOfThreads(); -} - -void Weaver::requestAbort() -{ - d->implementation->requestAbort(); -} - -void Weaver::reschedule() -{ - d->implementation->reschedule(); -} - -#include "ThreadWeaver.moc" diff --git a/tier1/threadweaver/src/Weaver/ThreadWeaver.h b/tier1/threadwea= ver/src/Weaver/ThreadWeaver.h index c6d5d7f..72c965f 100644 --- a/tier1/threadweaver/src/Weaver/ThreadWeaver.h +++ b/tier1/threadweaver/src/Weaver/ThreadWeaver.h @@ -29,91 +29,12 @@ #ifndef THREADWEAVER_H #define THREADWEAVER_H = -#include - -#include "Queue.h" - -namespace ThreadWeaver { - -class Job; -class State; -class WeaverObserver; - -/** The Weaver class provides the public implementation of the WeaverInter= face. - - Weaver provides a static instance that can be used to perform jobs= in - threads without managing a weaver object. The static instance will - only be created when it is first accessed. Also, Weaver objects wi= ll - create the threads only when the first jobs are queued. Therefore,= the - creation of a Weaver object is a rather cheap operation. - - The WeaverImpl class provides two parts of API - one for the threa= ds - that are handled by it, and one for the ThreadWeaver users - (application developers). To separate those two different API part= s, - Weaver only provides the interface supposed to be used by develope= rs - of multithreaded applications. - - Weaver creates and destroys WeaverImpl objects. It hides the - implementation details of the WeaverImpl class. It is strongly - discouraged to use the WeaverImpl class in programs, as its API wi= ll - be changed without notice. - Also, Weaver provides a factory method for this purpose that can b= e overloaded to create - derived WeaverImpl objects. - - */ -// Note: All member documentation is in the WeaverInterface class. -class THREADWEAVER_EXPORT Weaver : public Queue -{ - Q_OBJECT -public: - /** Construct a Weaver object. */ - explicit Weaver ( QObject* parent=3D0 ); - - /** Destruct a Weaver object. */ - virtual ~Weaver (); - - const State* state() const; - - void setMaximumNumberOfThreads(int cap) Q_DECL_OVERRIDE; - int maximumNumberOfThreads() const Q_DECL_OVERRIDE; - int currentNumberOfThreads() const Q_DECL_OVERRIDE; - - - void registerObserver ( WeaverObserver* ); - - /** Return the global Weaver instance. - In some cases, a global Weaver object per application is - sufficient for the applications purpose. If this is the case, - query instance() to get a pointer to a global instance. - If instance is never called, a global Weaver object will not be - created. - */ - static ThreadWeaver::Weaver* instance(); - void enqueue(const JobPointer&) Q_DECL_OVERRIDE; - void enqueueRaw(JobInterface* job) Q_DECL_OVERRIDE; - bool dequeue(const JobPointer&) Q_DECL_OVERRIDE; - bool dequeueRaw(JobInterface* job) Q_DECL_OVERRIDE; - void dequeue() Q_DECL_OVERRIDE; - void finish() Q_DECL_OVERRIDE; - void suspend() Q_DECL_OVERRIDE; - void resume() Q_DECL_OVERRIDE; - bool isEmpty() const Q_DECL_OVERRIDE; - bool isIdle() const Q_DECL_OVERRIDE; - int queueLength () const Q_DECL_OVERRIDE; - void requestAbort() Q_DECL_OVERRIDE; - void reschedule() Q_DECL_OVERRIDE; - void shutDown() Q_DECL_OVERRIDE; - -protected: - /** The factory method to create the actual Weaver implementation. - Overload this method to use a different or adapted implementation. - */ - virtual Queue* makeWeaverImpl (); - -private: - class Private; - Private* const d; -}; -} +#include "Weaver.h" +#include "Queueing.h" +#include "JobInterface.h" +#include "JobPointer.h" +#include "Job.h" +#include "JobCollection.h" +#include "JobSequence.h" = #endif // THREADWEAVER_H diff --git a/tier1/threadweaver/src/Weaver/ThreadWeaver.cpp b/tier1/threadw= eaver/src/Weaver/Weaver.cpp similarity index 82% copy from tier1/threadweaver/src/Weaver/ThreadWeaver.cpp copy to tier1/threadweaver/src/Weaver/Weaver.cpp index 6704a59..8b0db15 100644 --- a/tier1/threadweaver/src/Weaver/ThreadWeaver.cpp +++ b/tier1/threadweaver/src/Weaver/Weaver.cpp @@ -1,31 +1,4 @@ -/* -*- C++ -*- - -This file implements the Weaver class. - -$ Author: Mirko Boehm $ -$ Copyright: (C) 2005-2013 Mirko Boehm $ -$ Contact: mirko@kde.org -http://www.kde.org -http://creative-destruction.me $ - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public Licen= se - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "ThreadWeaver.h" +#include "Weaver.h" = #include #include @@ -216,4 +189,4 @@ void Weaver::reschedule() d->implementation->reschedule(); } = -#include "ThreadWeaver.moc" +#include "Weaver.moc" diff --git a/tier1/threadweaver/src/Weaver/ThreadWeaver.h b/tier1/threadwea= ver/src/Weaver/Weaver.h similarity index 97% copy from tier1/threadweaver/src/Weaver/ThreadWeaver.h copy to tier1/threadweaver/src/Weaver/Weaver.h index c6d5d7f..96c93c3 100644 --- a/tier1/threadweaver/src/Weaver/ThreadWeaver.h +++ b/tier1/threadweaver/src/Weaver/Weaver.h @@ -26,8 +26,9 @@ Boston, MA 02110-1301, USA. = */ -#ifndef THREADWEAVER_H -#define THREADWEAVER_H + +#ifndef THREADWEAVER_WEAVER_H +#define THREADWEAVER_WEAVER_H = #include = @@ -114,6 +115,7 @@ private: class Private; Private* const d; }; + } = -#endif // THREADWEAVER_H +#endif // THREADWEAVER_WEAVER_H