respin QTBUG-51767 patch

This commit is contained in:
Rex Dieter 2016-03-15 13:12:07 -05:00
parent cf904fea3a
commit c722cef915
3 changed files with 86 additions and 40 deletions

View File

@ -0,0 +1,81 @@
From 42e14c187f7b2eedb5be7b7a49efb4031f12a02e Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
Date: Tue, 15 Mar 2016 11:00:20 -0700
Subject: [PATCH] Fix QtDBus deadlock inside kded/kiod
Whenever a message spy was installed, we failed to actually process
looped-back messages by queueing them for processing by the spy. That
had as a consequence that the caller got an error reply and the message,
later, we attempted to deliver the message. Since that message still was
isLocal==true, bad things happened inside the manager thread.
The correct solution is not to queue the message for the filter. We could
have filtered the message directly, but instead this commit opts not to
filter looped-back messages. That implies kded/kiod must not attempt to
load its modules by way of a looped-back message.
Task-number: QTBUG-51676
Change-Id: I1dc112894cde7121e8ce302ae51b438ade1ff612
---
src/dbus/qdbusintegrator.cpp | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index cd44861..6052766 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -509,7 +509,12 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
{
if (!ref.load())
return false;
- if (!dispatchEnabled && !QDBusMessagePrivate::isLocal(amsg)) {
+
+ // local message are always delivered, regardless of filtering
+ // or whether the dispatcher is enabled
+ bool isLocal = QDBusMessagePrivate::isLocal(amsg);
+
+ if (!dispatchEnabled && !isLocal) {
// queue messages only, we'll handle them later
qDBusDebug() << this << "delivery is suspended";
pendingMessages << amsg;
@@ -524,7 +529,7 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
return false;
case QDBusMessage::MethodCallMessage:
// run it through the spy filters (if any) before the regular processing
- if (Q_UNLIKELY(qDBusSpyHookList.exists()) && qApp) {
+ if (Q_UNLIKELY(qDBusSpyHookList.exists()) && !isLocal && qApp) {
const QDBusSpyHookList &list = *qDBusSpyHookList;
qDBusDebug() << this << "invoking message spies";
QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this),
@@ -1451,9 +1456,9 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
// that means the dispatchLock mutex is locked
// must not call out to user code in that case
//
- // however, if the message is internal, handleMessage was called
- // directly and no lock is in place. We can therefore call out to
- // user code, if necessary
+ // however, if the message is internal, handleMessage was called directly
+ // (user's thread) and no lock is in place. We can therefore call out to
+ // user code, if necessary.
ObjectTreeNode result;
int usedLength;
QThread *objThread = 0;
@@ -1492,12 +1497,14 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
usedLength, msg));
return;
} else if (objThread != QThread::currentThread()) {
- // synchronize with other thread
+ // looped-back message, targeting another thread:
+ // synchronize with it
postEventToThread(HandleObjectCallPostEventAction, result.obj,
new QDBusActivateObjectEvent(QDBusConnection(this), this, result,
usedLength, msg, &sem));
semWait = true;
} else {
+ // looped-back message, targeting current thread
semWait = false;
}
} // release the lock
--
2.5.0

View File

@ -1,37 +0,0 @@
From d011c92b47f95554fe639ad9c0542768d802666b Mon Sep 17 00:00:00 2001
From: Weng Xuetian <wengxt@gmail.com>
Date: Fri, 4 Mar 2016 10:53:46 -0800
Subject: [PATCH] QtDBus: do not synchrnoize local message in daemon thread
When qDBusAddSpyHook is used and there is a local message, the
handleObjectCall on this message will be deferred to daemon thread. It
would cause dead lock if dbus daemon thread wait for this message and
there is no point to wait for the reply since daemon thread is not same
as the message sender thread.
Task-number: QTBUG-51676
Change-Id: I1dc112894cde7121e8ce302ae51b438ade1ff612
---
src/dbus/qdbusintegrator.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index cd44861..caf2e92 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -1484,8 +1484,10 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
return;
}
- if (!QDBusMessagePrivate::isLocal(msg)) {
- // external incoming message
+ if (!QDBusMessagePrivate::isLocal(msg) || QThread::currentThread() == QDBusConnectionManager::instance()) {
+ // two cases:
+ // 1. external incoming message
+ // 2. local message deferred by spy hook
// post it and forget
postEventToThread(HandleObjectCallPostEventAction, result.obj,
new QDBusActivateObjectEvent(QDBusConnection(this), this, result,
--
2.5.0

View File

@ -48,7 +48,7 @@
Summary: Qt5 - QtBase components
Name: qt5-qtbase
Version: 5.6.0
Release: 1%{?prerelease:.${prerelease}}%{?dist}
Release: 2%{?prerelease:.%{prerelease}}%{?dist}
# See LGPL_EXCEPTIONS.txt, for exception details
License: LGPLv2 with exceptions or GPLv3 with exceptions
@ -99,8 +99,7 @@ Patch55: QTBUG-51648-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch
Patch56: QTBUG-51649-QtDBus-finish-all-pending-call-with-error-if-disconn.patch
# https://codereview.qt-project.org/#/c/151459/
Patch57: QTBUG-51676-QtDBus-do-not-synchrnoize-local-message-in-daemon-th.patch
Patch57: QTBUG-51676-Fix-QtDBus-deadlock-inside-kded-kiod.patch
# Epel patches
Patch100: qt5-qtbase-5.6.0-el6-sqrt.patch
@ -960,6 +959,9 @@ fi
%changelog
* Tue Mar 15 2016 Rex Dieter <rdieter@fedoraproject.org> 5.6.0-2
- respin QTBUG-51767 patch
* Mon Mar 14 2016 Helio Chissini de Castro <helio@kde.org> - 5.6.0-1
- 5.6.0 release