diff options
author | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-05-12 11:17:22 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-05-12 11:17:23 +0200 |
commit | adf85c09b46eaf55dab362e17e3b0828fb509750 (patch) | |
tree | c079b2125611711a3dcd946894ad587af33e14d0 /src/dbus/qdbusintegrator.cpp | |
parent | 5dc421ec87eca15a72c82203319a9be7655cd56a (diff) | |
parent | 6bcd27b957a5ffcfe7665b0979679510e3b2ae3d (diff) |
Merge 5.6 into 5.6.1
Change-Id: I22003b840f1a7ac685a1ec3353d7e7dbd84c3953
Diffstat (limited to 'src/dbus/qdbusintegrator.cpp')
-rw-r--r-- | src/dbus/qdbusintegrator.cpp | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index d0468f4af0..147966b9b0 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1071,17 +1071,18 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() } } -void QDBusConnectionPrivate::disconnectObjectTree(QDBusConnectionPrivate::ObjectTreeNode &haystack) +void QDBusConnectionPrivate::collectAllObjects(QDBusConnectionPrivate::ObjectTreeNode &haystack, + QSet<QObject *> &set) { QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin(); while (it != haystack.children.end()) { - disconnectObjectTree(*it); + collectAllObjects(*it, set); it++; } if (haystack.obj) - haystack.obj->disconnect(this); + set.insert(haystack.obj); } void QDBusConnectionPrivate::closeConnection() @@ -1110,15 +1111,23 @@ void QDBusConnectionPrivate::closeConnection() // Disconnect all signals from signal hooks and from the object tree to // avoid QObject::destroyed being sent to dbus daemon thread which has - // already quit. - SignalHookHash::iterator sit = signalHooks.begin(); - while (sit != signalHooks.end()) { - sit.value().obj->disconnect(this); - sit++; + // already quit. We need to make sure we disconnect exactly once per + // object, because if we tried a second time, we might be hitting a + // dangling pointer. + QSet<QObject *> allObjects; + collectAllObjects(rootNode, allObjects); + SignalHookHash::const_iterator sit = signalHooks.constBegin(); + while (sit != signalHooks.constEnd()) { + allObjects.insert(sit.value().obj); + ++sit; + } + + // now disconnect ourselves + QSet<QObject *>::const_iterator oit = allObjects.constBegin(); + while (oit != allObjects.constEnd()) { + (*oit)->disconnect(this); + ++oit; } - - disconnectObjectTree(rootNode); - rootNode.children.clear(); // free resources } void QDBusConnectionPrivate::handleDBusDisconnection() |