summaryrefslogtreecommitdiff
path: root/source/l/qt5/patches/qt5.qtbug-51648.patch
diff options
context:
space:
mode:
Diffstat (limited to 'source/l/qt5/patches/qt5.qtbug-51648.patch')
-rw-r--r--source/l/qt5/patches/qt5.qtbug-51648.patch88
1 files changed, 88 insertions, 0 deletions
diff --git a/source/l/qt5/patches/qt5.qtbug-51648.patch b/source/l/qt5/patches/qt5.qtbug-51648.patch
new file mode 100644
index 00000000..279839b0
--- /dev/null
+++ b/source/l/qt5/patches/qt5.qtbug-51648.patch
@@ -0,0 +1,88 @@
+From b024fbe83863fc57364a52c717d5b43d654bdb5d Mon Sep 17 00:00:00 2001
+From: Weng Xuetian <wengxt@gmail.com>
+Date: Sat, 5 Mar 2016 12:23:21 -0800
+Subject: [PATCH] QtDBus: clean up signal hooks and object tree in
+ closeConnection
+
+If a QObject is added or passed as receiver to QDBusConnection::connect()
+and it is managed by Q_GLOBAL_STATIC or similar mechanism, it is
+possible that when that its destructor is called after the dbus daemon
+thread ends. In that case, QObject::destroyed connected via
+Qt::BlockingQueuedConnection to QDBusConnectionPrivate will cause dead
+lock since the thread is no longer processing events.
+
+Task-number: QTBUG-51648
+Change-Id: I1a1810a6d6d0234af0269d5f3fc1f54101bf1547
+---
+ src/dbus/qdbusconnection_p.h | 1 +
+ src/dbus/qdbusintegrator.cpp | 28 +++++++++++++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
+index c77daf7..565eb83 100644
+--- a/src/dbus/qdbusconnection_p.h
++++ b/src/dbus/qdbusconnection_p.h
+@@ -254,6 +254,7 @@ private:
+ const QVector<int> &metaTypes, int slotIdx);
+
+ SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it);
++ void disconnectObjectTree(ObjectTreeNode &node);
+
+ bool isServiceRegisteredByThread(const QString &serviceName);
+
+diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
+index cd44861..a3cd47b 100644
+--- a/src/dbus/qdbusintegrator.cpp
++++ b/src/dbus/qdbusintegrator.cpp
+@@ -1030,7 +1030,6 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate()
+ qPrintable(name));
+
+ closeConnection();
+- rootNode.children.clear(); // free resources
+ qDeleteAll(cachedMetaObjects);
+
+ if (mode == ClientMode || mode == PeerMode) {
+@@ -1052,6 +1051,20 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate()
+ }
+ }
+
++void QDBusConnectionPrivate::disconnectObjectTree(QDBusConnectionPrivate::ObjectTreeNode &haystack)
++{
++ QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin();
++
++ while (it != haystack.children.end()) {
++ disconnectObjectTree(*it);
++ it++;
++ }
++
++ if (haystack.obj) {
++ haystack.obj->disconnect(this);
++ }
++}
++
+ void QDBusConnectionPrivate::closeConnection()
+ {
+ QDBusWriteLocker locker(CloseConnectionAction, this);
+@@ -1075,6 +1088,19 @@ void QDBusConnectionPrivate::closeConnection()
+ }
+
+ qDeleteAll(pendingCalls);
++
++ // clean up all signal hook and object tree, to avoid QObject::destroyed
++ // being activated to dbus daemon thread which already quits.
++ // dbus connection is already closed, so there is nothing we could do be clean
++ // up everything here.
++ SignalHookHash::iterator sit = signalHooks.begin();
++ while (sit != signalHooks.end()) {
++ sit.value().obj->disconnect(this);
++ sit++;
++ }
++
++ disconnectObjectTree(rootNode);
++ rootNode.children.clear(); // free resources
+ }
+
+ void QDBusConnectionPrivate::checkThread()
+--
+2.7.1
+