From 7b352c907a152f4cc43ad2482191ddd5718391ec Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Thu, 13 Nov 2014 16:02:24 +0000 Subject: [PATCH] refs #334 Refactored CWorker parts relating to finished() signal into new base class CWorkerBase. --- src/blackmisc/worker.cpp | 5 +--- src/blackmisc/worker.h | 56 +++++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/blackmisc/worker.cpp b/src/blackmisc/worker.cpp index 034e22950..ed29ea299 100644 --- a/src/blackmisc/worker.cpp +++ b/src/blackmisc/worker.cpp @@ -32,10 +32,7 @@ namespace BlackMisc { m_task(); - QMutexLocker lock(&m_finishedMutex); - m_finished = true; - emit finished(); - lock.unlock(); + setFinished(); auto *ownThread = thread(); moveToThread(ownThread->thread()); // move worker back to the thread which constructed it, so there is no race on deletion diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index d25e2855a..6ec9180cc 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -89,24 +89,13 @@ namespace BlackMisc }; /*! - * Class for doing some arbitrary task in its own thread. - * - * The task is exposed as a function object, so could be a lambda or a hand-written closure. - * CWorker can not be subclassed, instead it can be extended with rich callable task objects. + * Base class for CWorker and CContinuousWorker. */ - class CWorker final : public QObject + class CWorkerBase : public QObject { Q_OBJECT public: - /*! - * Returns a new worker object which lives in a new thread. - * \param owner Will be the parent of the new thread (the worker has no parent). - * \param name A name for the task, which will be used to create a name for the thread. - * \param task A function object which will be run by the worker in its thread. - */ - static CWorker *fromTask(QObject *owner, const QString &name, std::function task); - //! Connects to a slot which will be called when the task is finished. //! \threadsafe template @@ -114,7 +103,7 @@ namespace BlackMisc { Q_ASSERT(receiver->thread() == QThread::currentThread()); QMutexLocker lock(&m_finishedMutex); - connect(this, &CWorker::finished, receiver, slot); + connect(this, &CWorkerBase::finished, receiver, slot); if (m_finished) { (receiver->*slot)(); } } @@ -125,7 +114,7 @@ namespace BlackMisc { Q_ASSERT(context->thread() == QThread::currentThread()); QMutexLocker lock(&m_finishedMutex); - connect(this, &CWorker::finished, context, functor); + connect(this, &CWorkerBase::finished, context, functor); if (m_finished) { functor(); } } @@ -135,7 +124,7 @@ namespace BlackMisc void then(F functor) { QMutexLocker lock(&m_finishedMutex); - connect(this, &CWorker::finished, functor); + connect(this, &CWorkerBase::finished, functor); if (m_finished) { functor(); } } @@ -178,6 +167,39 @@ namespace BlackMisc //! Emitted when the task is finished. void finished(); + protected: + //! Mark the task as finished. + void setFinished() + { + QMutexLocker lock(&m_finishedMutex); + m_finished = true; + emit finished(); + } + + private: + bool m_finished = false; + mutable QMutex m_finishedMutex { QMutex::Recursive }; + }; + + /*! + * Class for doing some arbitrary parcel of work in its own thread. + * + * The task is exposed as a function object, so could be a lambda or a hand-written closure. + * CWorker can not be subclassed, instead it can be extended with rich callable task objects. + */ + class CWorker final : public CWorkerBase + { + Q_OBJECT + + public: + /*! + * Returns a new worker object which lives in a new thread. + * \param owner Will be the parent of the new thread (the worker has no parent). + * \param name A name for the task, which will be used to create a name for the thread. + * \param task A function object which will be run by the worker in its thread. + */ + static CWorker *fromTask(QObject *owner, const QString &name, std::function task); + private slots: //! Called when the worker has been moved into its new thread. void ps_runTask(); @@ -185,8 +207,6 @@ namespace BlackMisc private: CWorker(std::function task) : m_task(task) {} - bool m_finished = false; - mutable QMutex m_finishedMutex { QMutex::Recursive }; std::function m_task; };