From b467b86bbf53340abf0cbfc41e92c0942db85b32 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Fri, 6 May 2016 13:29:21 -0500 Subject: [PATCH] more goodies, FTBFS fixes - pull in final/upstream fixes for QTBUG-51648,QTBUG-51649 - disable examples/tests in bootstrap mode --- ...signal-hooks-and-object-tree-in-clos.patch | 29 ++- ...l-pending-call-with-error-if-disconn.patch | 171 +++++++++++------- qt5-qtbase.spec | 33 ++-- 3 files changed, 141 insertions(+), 92 deletions(-) rename QTBUG-51648-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch => 0415-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch (75%) rename QTBUG-51649-QtDBus-finish-all-pending-call-with-error-if-disconn.patch => 0537-QtDBus-finish-all-pending-call-with-error-if-disconn.patch (54%) diff --git a/QTBUG-51648-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch b/0415-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch similarity index 75% rename from QTBUG-51648-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch rename to 0415-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch index 26c15d0..3cac1ec 100644 --- a/QTBUG-51648-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch +++ b/0415-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch @@ -1,7 +1,7 @@ -From b024fbe83863fc57364a52c717d5b43d654bdb5d Mon Sep 17 00:00:00 2001 +From b77ef8a7e6e4104067d52824e29eadc8c66f5929 Mon Sep 17 00:00:00 2001 From: Weng Xuetian Date: Sat, 5 Mar 2016 12:23:21 -0800 -Subject: [PATCH] QtDBus: clean up signal hooks and object tree in +Subject: [PATCH 415/595] QtDBus: clean up signal hooks and object tree in closeConnection If a QObject is added or passed as receiver to QDBusConnection::connect() @@ -13,10 +13,11 @@ lock since the thread is no longer processing events. Task-number: QTBUG-51648 Change-Id: I1a1810a6d6d0234af0269d5f3fc1f54101bf1547 +Reviewed-by: Thiago Macieira --- src/dbus/qdbusconnection_p.h | 1 + - src/dbus/qdbusintegrator.cpp | 28 +++++++++++++++++++++++++++- - 2 files changed, 28 insertions(+), 1 deletion(-) + src/dbus/qdbusintegrator.cpp | 26 +++++++++++++++++++++++++- + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index c77daf7..565eb83 100644 @@ -31,10 +32,10 @@ index c77daf7..565eb83 100644 bool isServiceRegisteredByThread(const QString &serviceName); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp -index cd44861..a3cd47b 100644 +index 478a2c4..3be775d 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp -@@ -1030,7 +1030,6 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() +@@ -1050,7 +1050,6 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() qPrintable(name)); closeConnection(); @@ -42,7 +43,7 @@ index cd44861..a3cd47b 100644 qDeleteAll(cachedMetaObjects); if (mode == ClientMode || mode == PeerMode) { -@@ -1052,6 +1051,20 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() +@@ -1072,6 +1071,19 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() } } @@ -55,23 +56,21 @@ index cd44861..a3cd47b 100644 + it++; + } + -+ if (haystack.obj) { ++ if (haystack.obj) + haystack.obj->disconnect(this); -+ } +} + void QDBusConnectionPrivate::closeConnection() { QDBusWriteLocker locker(CloseConnectionAction, this); -@@ -1075,6 +1088,19 @@ void QDBusConnectionPrivate::closeConnection() +@@ -1095,6 +1107,18 @@ 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. ++ // 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); @@ -84,5 +83,5 @@ index cd44861..a3cd47b 100644 void QDBusConnectionPrivate::checkThread() -- -2.5.0 +2.7.4 diff --git a/QTBUG-51649-QtDBus-finish-all-pending-call-with-error-if-disconn.patch b/0537-QtDBus-finish-all-pending-call-with-error-if-disconn.patch similarity index 54% rename from QTBUG-51649-QtDBus-finish-all-pending-call-with-error-if-disconn.patch rename to 0537-QtDBus-finish-all-pending-call-with-error-if-disconn.patch index bf13f57..18fdfad 100644 --- a/QTBUG-51649-QtDBus-finish-all-pending-call-with-error-if-disconn.patch +++ b/0537-QtDBus-finish-all-pending-call-with-error-if-disconn.patch @@ -1,40 +1,117 @@ -From 136eeec876ed5b995e7c27bcdcefe0199f5f183d Mon Sep 17 00:00:00 2001 +From 9be4ee52021bbb3227611979319ab5e3106063b2 Mon Sep 17 00:00:00 2001 From: Weng Xuetian Date: Thu, 3 Mar 2016 21:56:53 -0800 -Subject: [PATCH] QtDBus: finish all pending call with error if disconnected +Subject: [PATCH 537/595] QtDBus: finish all pending call with error if + disconnected libdbus will send a local signal if connection gets disconnected. When this happens, end all pending calls with QDBusError::Disconnected. Task-number: QTBUG-51649 Change-Id: I5c7d2a468bb5da746d0c0e53e458c1e376f186a9 +Reviewed-by: Thiago Macieira --- - src/dbus/qdbusintegrator.cpp | 26 +++++++++++++++++----- - src/dbus/qdbusutil_p.h | 6 +++++ - .../dbus/qdbusconnection/tst_qdbusconnection.cpp | 22 ++++++++++++++++++ + src/dbus/dbus_minimal_p.h | 2 ++ + src/dbus/qdbusconnection_p.h | 3 ++ + src/dbus/qdbusintegrator.cpp | 41 ++++++++++++++++++---- + src/dbus/qdbusutil_p.h | 2 ++ + .../dbus/qdbusconnection/tst_qdbusconnection.cpp | 21 +++++++++++ .../dbus/qdbusconnection/tst_qdbusconnection.h | 1 + - 4 files changed, 49 insertions(+), 6 deletions(-) + 6 files changed, 64 insertions(+), 6 deletions(-) +diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h +index f0a2954..8f25b24 100644 +--- a/src/dbus/dbus_minimal_p.h ++++ b/src/dbus/dbus_minimal_p.h +@@ -99,9 +99,11 @@ typedef dbus_uint32_t dbus_bool_t; + /* dbus-shared.h */ + #define DBUS_SERVICE_DBUS "org.freedesktop.DBus" + #define DBUS_PATH_DBUS "/org/freedesktop/DBus" ++#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" + #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" + #define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" + #define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" ++#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local" + + #define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */ + #define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */ +diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h +index 565eb83..b733a68 100644 +--- a/src/dbus/qdbusconnection_p.h ++++ b/src/dbus/qdbusconnection_p.h +@@ -260,6 +260,8 @@ private: + + QString getNameOwnerNoCache(const QString &service); + ++ void watchForDBusDisconnection(); ++ + void _q_newConnection(QDBusConnectionPrivate *newConnection); + + protected: +@@ -279,6 +281,7 @@ private slots: + void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner); + void registerServiceNoLock(const QString &serviceName); + void unregisterServiceNoLock(const QString &serviceName); ++ void handleDBusDisconnection(); + + signals: + void dispatchStatusChanged(); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp -index cd44861..320419f 100644 +index 3be775d..d0468f4 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp -@@ -519,6 +519,14 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) - switch (amsg.type()) { - case QDBusMessage::SignalMessage: - handleSignal(amsg); -+ // Check local disconnected signal from libdbus -+ if (amsg.interface() == QDBusUtil::dbusInterfaceLocal() -+ && amsg.path() == QDBusUtil::dbusPathLocal() -+ && amsg.member() == QDBusUtil::disconnected() -+ && !QDBusMessagePrivate::isLocal(amsg)) { -+ while (!pendingCalls.isEmpty()) -+ processFinishedCall(pendingCalls.first()); -+ } - // if there are any other filters in this DBusConnection, - // let them see the signal too - return false; -@@ -1767,10 +1775,16 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) +@@ -1121,6 +1121,12 @@ void QDBusConnectionPrivate::closeConnection() + rootNode.children.clear(); // free resources + } + ++void QDBusConnectionPrivate::handleDBusDisconnection() ++{ ++ while (!pendingCalls.isEmpty()) ++ processFinishedCall(pendingCalls.first()); ++} ++ + void QDBusConnectionPrivate::checkThread() + { + Q_ASSERT(thread() == QDBusConnectionManager::instance()); +@@ -1646,6 +1652,19 @@ void QDBusConnectionPrivate::handleSignal(const QDBusMessage& msg) + handleSignal(key, msg); // third try + } + ++void QDBusConnectionPrivate::watchForDBusDisconnection() ++{ ++ SignalHook hook; ++ // Initialize the hook for Disconnected signal ++ hook.service.clear(); // org.freedesktop.DBus.Local.Disconnected uses empty service name ++ hook.path = QDBusUtil::dbusPathLocal(); ++ hook.obj = this; ++ hook.params << QMetaType::Void; ++ hook.midx = staticMetaObject.indexOfSlot("handleDBusDisconnection()"); ++ Q_ASSERT(hook.midx != -1); ++ signalHooks.insert(QLatin1String("Disconnected:" DBUS_INTERFACE_LOCAL), hook); ++} ++ + void QDBusConnectionPrivate::setServer(QDBusServer *object, DBusServer *s, const QDBusErrorInternal &error) + { + mode = ServerMode; +@@ -1711,6 +1730,8 @@ void QDBusConnectionPrivate::setPeer(DBusConnection *c, const QDBusErrorInternal + qDBusSignalFilter, + this, 0); + ++ watchForDBusDisconnection(); ++ + QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection); + } + +@@ -1787,6 +1808,8 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError + Q_ASSERT(hook.midx != -1); + signalHooks.insert(QLatin1String("NameOwnerChanged:" DBUS_INTERFACE_DBUS), hook); + ++ watchForDBusDisconnection(); ++ + qDBusDebug() << this << ": connected successfully"; + + // schedule a dispatch: +@@ -1813,10 +1836,16 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) QDBusMessage &msg = call->replyMessage; if (call->pending) { @@ -55,7 +132,7 @@ index cd44861..320419f 100644 } qDBusDebug() << connection << "got message reply:" << msg; -@@ -2070,8 +2084,8 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void * +@@ -2116,8 +2145,8 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void * pcall->pending = pending; q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0); @@ -67,7 +144,7 @@ index cd44861..320419f 100644 return; diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h -index 8f5ae92..ca70ff9 100644 +index 8f5ae92..f4ab9b9 100644 --- a/src/dbus/qdbusutil_p.h +++ b/src/dbus/qdbusutil_p.h @@ -155,6 +155,8 @@ namespace QDBusUtil @@ -79,42 +156,28 @@ index 8f5ae92..ca70ff9 100644 inline QString dbusInterface() { // it's the same string, but just be sure -@@ -165,8 +167,12 @@ namespace QDBusUtil - { return QStringLiteral(DBUS_INTERFACE_PROPERTIES); } - inline QString dbusInterfaceIntrospectable() - { return QStringLiteral(DBUS_INTERFACE_INTROSPECTABLE); } -+ inline QString dbusInterfaceLocal() -+ { return QStringLiteral(DBUS_INTERFACE_LOCAL); } - inline QString nameOwnerChanged() - { return QStringLiteral("NameOwnerChanged"); } -+ inline QString disconnected() -+ { return QStringLiteral("Disconnected"); } - inline QString disconnectedErrorMessage() - { return QStringLiteral("Not connected to D-Bus server"); } - } diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp -index e91f87d..6c7e6b1 100644 +index e91f87d..f378091 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp -@@ -1218,6 +1218,28 @@ void tst_QDBusConnection::callVirtualObjectLocal() +@@ -1218,6 +1218,27 @@ void tst_QDBusConnection::callVirtualObjectLocal() QCOMPARE(obj.replyArguments, subPathReply.arguments()); } +void tst_QDBusConnection::pendingCallWhenDisconnected() +{ ++ if (!QCoreApplication::instance()) ++ QSKIP("Test requires a QCoreApplication"); ++ + QDBusServer *server = new QDBusServer; + QDBusConnection con = QDBusConnection::connectToPeer(server->address(), "disconnect"); + QTestEventLoop::instance().enterLoop(2); -+ QVERIFY(!QTestEventLoop::instance().timeout()); -+ QVERIFY(con.isConnected()); -+ -+ delete server; -+ -+ // Make sure we call the method before we know it is disconnected. + QVERIFY(con.isConnected()); + QDBusMessage message = QDBusMessage::createMethodCall("", "/", QString(), "method"); + QDBusPendingCall reply = con.asyncCall(message); + ++ delete server; ++ + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!con.isConnected()); + QVERIFY(reply.isFinished()); @@ -138,19 +201,5 @@ index a53ba32..720e484 100644 public: QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; } -- -2.5.0 +2.7.4 -diff -up qtbase-opensource-src-5.6.0-rc/src/dbus/dbus_minimal_p.h.QTBUG-51649 qtbase-opensource-src-5.6.0-rc/src/dbus/dbus_minimal_p.h ---- qtbase-opensource-src-5.6.0-rc/src/dbus/dbus_minimal_p.h.QTBUG-51649 2016-02-18 01:24:38.000000000 -0600 -+++ qtbase-opensource-src-5.6.0-rc/src/dbus/dbus_minimal_p.h 2016-03-11 11:40:11.176244645 -0600 -@@ -99,8 +99,10 @@ typedef dbus_uint32_t dbus_bool_t; - /* dbus-shared.h */ - #define DBUS_SERVICE_DBUS "org.freedesktop.DBus" - #define DBUS_PATH_DBUS "/org/freedesktop/DBus" -+#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" - #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" - #define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" -+#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local" - #define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" - - #define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */ diff --git a/qt5-qtbase.spec b/qt5-qtbase.spec index 7eaf4d9..a5e7525 100644 --- a/qt5-qtbase.spec +++ b/qt5-qtbase.spec @@ -49,11 +49,10 @@ %if ! 0%{?bootstrap} %ifarch %{arm} %{ix86} x86_64 %{power64} s390 s390x aarch64 %global docs 1 +%endif +%global examples 1 %global tests 1 %endif -%endif - -%global examples 1 #define prerelease rc @@ -97,12 +96,6 @@ Patch52: qtbase-opensource-src-5.6.0-moc_WORDSIZE.patch # arm patch Patch54: qtbase-opensource-src-5.6.0-arm.patch -# https://codereview.qt-project.org/#/c/151496/ -Patch55: QTBUG-51648-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch - -# https://codereview.qt-project.org/#/c/151340/ -Patch56: QTBUG-51649-QtDBus-finish-all-pending-call-with-error-if-disconn.patch - # recently passed code review, not integrated yet # https://codereview.qt-project.org/126102/ Patch60: moc-get-the-system-defines-from-the-compiler-itself.patch @@ -118,6 +111,8 @@ Patch278: 0178-qt_common.prf-when-looking-for-GCC-4.6-match-GCC-6-t.patch Patch301: 0201-alsatest-Fix-the-check-to-treat-alsalib-1.1.x-as-cor.patch Patch321: 0221-QObject-fix-GCC-6-warning-about-qt_static_metacall-s.patch Patch393: 0293-Fix-QtDBus-deadlock-inside-kded-kiod.patch +Patch515: 0415-QtDBus-clean-up-signal-hooks-and-object-tree-in-clos.patch +Patch637: 0537-QtDBus-finish-all-pending-call-with-error-if-disconn.patch # macros, be mindful to keep sync'd with macros.qt5 Source10: macros.qt5 @@ -171,6 +166,7 @@ BuildRequires: pkgconfig(libproxy-1.0) BuildRequires: pkgconfig(ice) pkgconfig(sm) BuildRequires: pkgconfig(libpng) BuildRequires: pkgconfig(libudev) +%global openssl -openssl-linked BuildRequires: pkgconfig(openssl) BuildRequires: pkgconfig(libpulse) pkgconfig(libpulse-mainloop-glib) %if 0%{?fedora} @@ -367,9 +363,6 @@ RPM macros for building Qt5 packages. %patch52 -p1 -b .moc_WORDSIZE %patch54 -p1 -b .arm -%patch55 -p1 -b .QTBUG-51648 -## FTBFS, omit for now -%patch56 -p1 -b .QTBUG-51649 %patch60 -p1 -b .moc_system_defines %patch158 -p1 -b .0058 @@ -380,6 +373,8 @@ RPM macros for building Qt5 packages. %patch301 -p1 -b .0201 %patch321 -p1 -b .0221 %patch393 -p1 -b .0293 +%patch515 -p1 -b .0415 +%patch637 -p1 -b .0637 %define platform linux-g++ @@ -467,10 +462,10 @@ pushd %{_target_platform} -iconv \ -icu \ %{?journald} \ - -openssl-linked \ + %{?openssl} \ -optimized-qmake \ %{!?examples:-nomake examples} \ - -nomake tests \ + %{!?tests:-nomake tests} \ -no-pch \ -no-rpath \ -no-separate-debug-info \ @@ -615,11 +610,15 @@ install -p -m755 -D %{SOURCE6} %{buildroot}%{_sysconfdir}/X11/xinit/xinitrc.d/10 %check %if 0%{?tests} +## see tests/README for expected environment (running a plasma session essentially) +## we are not quite there yet export CTEST_OUTPUT_ON_FAILURE=1 export PATH=%{buildroot}%{_qt5_bindir}:$PATH export LD_LIBRARY_PATH=%{buildroot}%{_qt5_libdir} -make sub-tests %{?_smp_mflags} -C %{_target_platform} -xvfb-run -a \ +# dbus tests error out when building if session bus is not available +dbus-launch --exit-with-session \ +make sub-tests %{?_smp_mflags} -k -C %{_target_platform} ||: +xvfb-run -a --server-args="-screen 0 1280x1024x32" \ dbus-launch --exit-with-session \ time \ make check -k -C %{_target_platform}/tests ||: @@ -973,6 +972,8 @@ fi * Thu May 05 2016 Rex Dieter - 5.6.0-17 - support out-of-tree build - better %%check +- pull in final/upstream fixes for QTBUG-51648,QTBUG-51649 +- disable examples/tests in bootstrap mode * Sat Apr 30 2016 Rex Dieter - 5.6.0-16 - own %%{_qt5_plugindir}/egldeviceintegrations