From ad66dbe305cff72443f4d3484191872d56e6dfbb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 27 Apr 2016 22:34:26 -0700 Subject: Disconnect signals from each QObject only once in QDBusConnectionPrivate Because the moment we disconnect from the object's destroyed() signal, it may get destroyed in another thread. If the same object appears more than once in the object tree or in the signal hook table, we could be accessing a dangling pointer. Task-number: QTBUG-52988 Change-Id: Ifea6e497f11a461db432ffff14496f0f83889104 Reviewed-by: Weng Xuetian Reviewed-by: Thiago Macieira --- src/dbus/qdbusconnection_p.h | 2 +- src/dbus/qdbusintegrator.cpp | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) (limited to 'src/dbus') diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index b733a68856..fff9f29b03 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -254,7 +254,7 @@ private: const QVector &metaTypes, int slotIdx); SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it); - void disconnectObjectTree(ObjectTreeNode &node); + void collectAllObjects(ObjectTreeNode &node, QSet &set); bool isServiceRegisteredByThread(const QString &serviceName); 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 &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 allObjects; + collectAllObjects(rootNode, allObjects); + SignalHookHash::const_iterator sit = signalHooks.constBegin(); + while (sit != signalHooks.constEnd()) { + allObjects.insert(sit.value().obj); + ++sit; + } + + // now disconnect ourselves + QSet::const_iterator oit = allObjects.constBegin(); + while (oit != allObjects.constEnd()) { + (*oit)->disconnect(this); + ++oit; } - - disconnectObjectTree(rootNode); - rootNode.children.clear(); // free resources } void QDBusConnectionPrivate::handleDBusDisconnection() -- cgit v1.2.3 From 72e3fcce387d72043dd0b9fbe06d6b720861c1e7 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 10 May 2016 14:54:24 +0200 Subject: Doc: Remove repository name from examplesinstallpath Examples in binary packages now directly match the install path. Change-Id: Ic1487bc766cfd3b0a0a340cc4ae4ba49d953eaa6 Task-number: QTBUG-52953 Reviewed-by: Oswald Buddenhagen --- src/dbus/doc/qtdbus.qdocconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/dbus') 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 -- cgit v1.2.3