diff --git a/src/blackmisc/worker.cpp b/src/blackmisc/worker.cpp index 3c16ba52b..f232494eb 100644 --- a/src/blackmisc/worker.cpp +++ b/src/blackmisc/worker.cpp @@ -51,6 +51,23 @@ namespace BlackMisc promise.get_future().wait(); } + void CWorkerBase::abandon() Q_DECL_NOEXCEPT + { + thread()->requestInterruption(); + quit(); + } + + void CWorkerBase::abandonAndWait() Q_DECL_NOEXCEPT + { + thread()->requestInterruption(); + quitAndWait(); + } + + bool CWorkerBase::isAbandoned() const + { + return thread()->isInterruptionRequested(); + } + void CContinuousWorker::start(QThread::Priority priority) { if (m_name.isEmpty()) { m_name = metaObject()->className(); } diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index 744460f92..a3b382686 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -155,14 +155,25 @@ namespace BlackMisc } //! Blocks until the task is finished. - //! \threadsafe + //! \threadsafe Will deadlock if called by the worker thread. void waitForFinished() Q_DECL_NOEXCEPT; + //! Notify the task that its result is no longer needed, so it can finish early. + //! \threadsafe + void abandon() Q_DECL_NOEXCEPT; + + //! Convenience to call abandon() followed by waitForFinished(). + void abandonAndWait() Q_DECL_NOEXCEPT; + signals: //! Emitted when the task is finished. void finished(); protected: + //! For the task to check whether it can finish early. + //! \threadsafe + bool isAbandoned() const; + //! Mark the task as finished. void setFinished() { @@ -186,6 +197,9 @@ namespace BlackMisc } private: + virtual void quit() Q_DECL_NOEXCEPT {} + virtual void quitAndWait() Q_DECL_NOEXCEPT { waitForFinished(); } + bool m_finished = false; mutable QMutex m_finishedMutex { QMutex::Recursive }; }; @@ -276,11 +290,11 @@ namespace BlackMisc //! Stops the thread the next time around its event loop. //! The thread and the worker will then be deleted. //! \threadsafe - void quit() Q_DECL_NOEXCEPT; + virtual void quit() Q_DECL_NOEXCEPT final override; //! Calls quit() and blocks until the thread is finished. //! \threadsafe Will deadlock if called by the worker thread. - void quitAndWait() Q_DECL_NOEXCEPT; + virtual void quitAndWait() Q_DECL_NOEXCEPT final override; protected slots: //! Called when the thread is started. @@ -294,6 +308,8 @@ namespace BlackMisc void ps_finish(); private: + using CWorkerBase::setFinished; + QObject *m_owner = nullptr; QString m_name; };