From 2f1e3f47f983356c92864c3fc88a43378c4a01bb Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Sat, 28 Mar 2020 22:09:25 +0000 Subject: [PATCH] Track worker construction and destruction Added debug log messages in case a worker still exists when the `qApp` is destroyed. This would mean that a `quitAndWait` is missing or is being skipped somewhere. --- src/blackcore/application.cpp | 8 ++++++++ src/blackmisc/worker.cpp | 12 ++++++++++++ src/blackmisc/worker.h | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/src/blackcore/application.cpp b/src/blackcore/application.cpp index 20b153cd0..341098288 100644 --- a/src/blackcore/application.cpp +++ b/src/blackcore/application.cpp @@ -173,6 +173,14 @@ namespace BlackCore m_inputManager = new CInputManager(this); m_inputManager->createDevices(); } + + connect(this, &QObject::destroyed, [cat = CLogCategoryList(this)] + { + for (CWorkerBase *worker : CWorkerBase::allWorkers()) + { + CLogMessage(cat).debug(u"Worker named '%1' still exists after application destroyed") << worker->objectName(); + } + }); } } diff --git a/src/blackmisc/worker.cpp b/src/blackmisc/worker.cpp index 0536e0c5f..52ad1fc94 100644 --- a/src/blackmisc/worker.cpp +++ b/src/blackmisc/worker.cpp @@ -22,6 +22,8 @@ namespace BlackMisc { + QSet CWorkerBase::s_allWorkers; + void CRegularThread::run() { #ifdef Q_OS_WIN32 @@ -105,6 +107,16 @@ namespace BlackMisc // must not access the worker beyond this point, as it now lives in the owner's thread and could be deleted at any moment } + CWorkerBase::CWorkerBase() + { + s_allWorkers.insert(this); + } + + CWorkerBase::~CWorkerBase() + { + s_allWorkers.remove(this); + } + const CLogCategoryList &CWorkerBase::getLogCategories() { static const BlackMisc::CLogCategoryList cats { CLogCategory::worker() }; diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index 9f5af21a9..e6b70a382 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -163,6 +163,9 @@ namespace BlackMisc //! Convenience to call abandon() followed by waitForFinished(). void abandonAndWait() noexcept; + //! All workers currently existing. + static const QSet &allWorkers() { return s_allWorkers; } + signals: //! Emitted when the task is about to start. void aboutToStart(); @@ -172,6 +175,12 @@ namespace BlackMisc void finished(); protected: + //! Constructor. + CWorkerBase(); + + //! Destructor. + virtual ~CWorkerBase() override; + //! For the task to check whether it can finish early. //! \threadsafe bool isAbandoned() const; @@ -197,6 +206,7 @@ namespace BlackMisc bool m_started = false; bool m_finished = false; mutable QMutex m_finishedMutex { QMutex::Recursive }; + static QSet s_allWorkers; }; /*!