From 09685e8b37519820cc9750ea5c2eca3e1d03a4f6 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Sun, 12 Oct 2014 20:25:35 +0100 Subject: [PATCH] refs #336 Delete CLogCategoryHandler when it is no longer used, and thread safety. --- src/blackmisc/loghandler.cpp | 10 ++++++++++ src/blackmisc/loghandler.h | 22 +++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/blackmisc/loghandler.cpp b/src/blackmisc/loghandler.cpp index bfb36eb7c..7b7887200 100644 --- a/src/blackmisc/loghandler.cpp +++ b/src/blackmisc/loghandler.cpp @@ -48,9 +48,17 @@ namespace BlackMisc CLogCategoryHandler *CLogHandler::handlerForCategoryPrefix(const QString &category) { + Q_ASSERT(thread() == QThread::currentThread()); + if (! m_categoryPrefixHandlers.contains(category)) { m_categoryPrefixHandlers[category] = new CLogCategoryHandler(this, m_enableFallThrough); + + connect(m_categoryPrefixHandlers[category], &CLogCategoryHandler::ps_canBeDeleted, [this](CLogCategoryHandler *handler) + { + m_categoryPrefixHandlers.remove(m_categoryPrefixHandlers.key(handler)); + QMetaObject::invokeMethod(handler, "deleteLater"); + }); } return m_categoryPrefixHandlers[category]; @@ -71,6 +79,8 @@ namespace BlackMisc void CLogHandler::enableConsoleOutput(bool enable) { + Q_ASSERT(thread() == QThread::currentThread()); + m_enableFallThrough = enable; for (auto *handler : m_categoryPrefixHandlers.values()) { diff --git a/src/blackmisc/loghandler.h b/src/blackmisc/loghandler.h index ecb4c15d6..8c335de13 100644 --- a/src/blackmisc/loghandler.h +++ b/src/blackmisc/loghandler.h @@ -42,9 +42,11 @@ namespace BlackMisc void install(); //! Return a category handler for subscribing to all messages with a category starting with the given prefix. + //! \warning This must only be called from the main thread. CLogCategoryHandler *handlerForCategoryPrefix(const QString &prefix); //! Enable or disable the default Qt handler. + //! \warning This must only be called from the main thread. void enableConsoleOutput(bool enable); signals: @@ -82,15 +84,33 @@ namespace BlackMisc /*! * Enable or disable the default Qt handler for messages in relevant categories. * This can override the setting of the parent CLogHandler. + * \warning This must only be called from the main thread. */ - void enableConsoleOutput(bool enable) { m_enableFallThrough = enable; } + void enableConsoleOutput(bool enable) { Q_ASSERT(thread() == QThread::currentThread()); m_enableFallThrough = enable; } signals: /*! * Emitted when a message is logged in a relevant category. + * + * When all slots are disconnected from this signal, the CLogCategoryHandler is allowed to delete itself. */ void messageLogged(const CStatusMessage &message); + /*! + * Emitted when there are no more slots connected to the messageLogged signal. + */ + void ps_canBeDeleted(CLogCategoryHandler *handler); + + protected: + /*! + * \copydoc QObject::disconnectNotify + */ + virtual void disconnectNotify(const QMetaMethod &) override + { + static const QMetaMethod signal = QMetaMethod::fromSignal(&CLogCategoryHandler::messageLogged); + if (! isSignalConnected(signal)) { emit ps_canBeDeleted(this); } + } + private: friend class CLogHandler; CLogCategoryHandler(QObject *parent, bool enableFallThrough) : QObject(parent), m_enableFallThrough(enableFallThrough) {}