diff options
Diffstat (limited to 'src/dbus')
-rw-r--r-- | src/dbus/dbus.pro | 2 | ||||
-rw-r--r-- | src/dbus/doc/qtdbus.qdocconf | 2 | ||||
-rw-r--r-- | src/dbus/qdbusconnection_p.h | 2 | ||||
-rw-r--r-- | src/dbus/qdbusintegrator.cpp | 31 |
4 files changed, 24 insertions, 13 deletions
diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro index 445ff48482..c50f0b6b9c 100644 --- a/src/dbus/dbus.pro +++ b/src/dbus/dbus.pro @@ -23,6 +23,8 @@ win32 { -luser32 } +DEFINES += QT_NO_FOREACH + QMAKE_DOCS = $$PWD/doc/qtdbus.qdocconf PUB_HEADERS = qdbusargument.h \ diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf index fc8921ff35..ff46cc5961 100644 --- a/src/dbus/doc/qtdbus.qdocconf +++ b/src/dbus/doc/qtdbus.qdocconf @@ -19,7 +19,7 @@ sourcedirs += .. \ ../../../examples/dbus/doc/src excludedirs += ../../../examples/widgets/doc -examplesinstallpath = qtbase/dbus +examplesinstallpath = dbus depends += qtdoc qtcore diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index f00988c05f..b710bfd2aa 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -259,7 +259,7 @@ private: const QVector<int> &metaTypes, int slotIdx); SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it); - void disconnectObjectTree(ObjectTreeNode &node); + void collectAllObjects(ObjectTreeNode &node, QSet<QObject *> &set); bool isServiceRegisteredByThread(const QString &serviceName); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index c73f808485..54418c213a 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1076,17 +1076,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() @@ -1115,15 +1116,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() |