summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@qt.io>2017-12-07 13:10:36 +0100
committerTobias Hunger <tobias.hunger@qt.io>2017-12-08 10:37:32 +0000
commit7df3bff07ad07913744f0dcf4bddf3905bb3d9ba (patch)
treecae6433dae15dd1a5d06272ce0e3ec1e72c3f797
parent1ddee692009975d89b36c51cf5e30808776e38e3 (diff)
downloadqt-creator-7df3bff07ad07913744f0dcf4bddf3905bb3d9ba.tar.gz
ProjectExplorer: Make subscriptions more robust
Make sure not to continue to connect after the receiver was destructed and make sure to disconnect from everything when that happens. Task-number: QTCREATORBUG-19391 Change-Id: I4d09a7dca2a5260c3d4744607dccbde5964a0623 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r--src/plugins/projectexplorer/subscription.cpp54
-rw-r--r--src/plugins/projectexplorer/subscription.h4
2 files changed, 44 insertions, 14 deletions
diff --git a/src/plugins/projectexplorer/subscription.cpp b/src/plugins/projectexplorer/subscription.cpp
index b878bdacdc..6049fea02a 100644
--- a/src/plugins/projectexplorer/subscription.cpp
+++ b/src/plugins/projectexplorer/subscription.cpp
@@ -30,6 +30,7 @@
#include "target.h"
#include <utils/asconst.h>
+#include <utils/qtcassert.h>
namespace ProjectExplorer {
namespace Internal {
@@ -37,42 +38,42 @@ namespace Internal {
Subscription::Subscription(const Subscription::Connector &s, const QObject *receiver, QObject *parent) :
QObject(parent), m_subscriber(s)
{
- if (receiver != parent)
- connect(receiver, &QObject::destroyed, this, &QObject::deleteLater);
+ if (receiver != parent) {
+ connect(receiver, &QObject::destroyed, this, [this]() {
+ unsubscribeAll();
+ m_subscriber = Connector(); // Reset subscriber
+ deleteLater();
+ });
+ }
}
Subscription::~Subscription()
{
- for (const auto &c : Utils::asConst(m_connections))
- disconnect(c);
+ unsubscribeAll();
}
void Subscription::subscribe(ProjectConfiguration *pc)
{
if (!m_subscriber)
return;
- QMetaObject::Connection conn = m_subscriber(pc);
- if (conn)
- m_connections.insert(pc, conn);
+
+ connectTo(pc);
if (auto p = qobject_cast<Project *>(pc)) {
for (Target *t : p->targets()) {
for (ProjectConfiguration *pc : t->projectConfigurations())
- m_subscriber(pc);
+ connectTo(pc);
}
} else if (auto t = qobject_cast<Target *>(pc)) {
for (ProjectConfiguration *pc : t->projectConfigurations())
- m_subscriber(pc);
+ connectTo(pc);
}
}
void Subscription::unsubscribe(ProjectConfiguration *pc)
{
- auto c = m_connections.value(pc);
- if (c) {
- disconnect(c);
- m_connections.remove(pc);
- }
+ disconnectFrom(pc);
+
if (auto p = qobject_cast<Project *>(pc)) {
for (Target *t : p->targets()) {
for (ProjectConfiguration *pc : t->projectConfigurations())
@@ -82,7 +83,32 @@ void Subscription::unsubscribe(ProjectConfiguration *pc)
for (ProjectConfiguration *pc : t->projectConfigurations())
unsubscribe(pc);
}
+}
+
+void Subscription::unsubscribeAll()
+{
+ for (const auto &c : Utils::asConst(m_connections))
+ disconnect(c);
+ m_connections.clear();
+}
+
+void Subscription::connectTo(ProjectConfiguration *pc)
+{
+ QTC_ASSERT(!m_connections.contains(pc), return);
+
+ QMetaObject::Connection conn = m_subscriber(pc);
+ if (conn)
+ m_connections.insert(pc, conn);
+}
+
+void Subscription::disconnectFrom(ProjectConfiguration *pc)
+{
+ auto c = m_connections.value(pc);
+ if (!c)
+ return;
+ disconnect(c);
+ m_connections.remove(pc);
}
ProjectSubscription::ProjectSubscription(const Subscription::Connector &s, const QObject *r,
diff --git a/src/plugins/projectexplorer/subscription.h b/src/plugins/projectexplorer/subscription.h
index 5c1e0ec1a4..819a11d1f1 100644
--- a/src/plugins/projectexplorer/subscription.h
+++ b/src/plugins/projectexplorer/subscription.h
@@ -53,6 +53,10 @@ protected:
void subscribe(ProjectConfiguration *pc);
void unsubscribe(ProjectConfiguration *pc);
+ void unsubscribeAll();
+ void connectTo(ProjectConfiguration *pc);
+ void disconnectFrom(ProjectConfiguration *pc);
+
Connector m_subscriber;
QHash<ProjectConfiguration *, QMetaObject::Connection> m_connections;
};