From 02b0f44fab7808b4a687b526beada44c7015a98c Mon Sep 17 00:00:00 2001 From: Romain Pokrzywka Date: Thu, 3 Aug 2017 00:58:43 -0500 Subject: Fix race condition in QDBusAbstractInterfacePrivate::initOwnerTracking() The current code fetches currentOwner in the constructor, then sets up a connection between a service watcher and _q_serviceOwnerChanged() in initOwnerTracking(). But an owner change notification could arrive after we fetch the current owner and before the connection is made. In this case the owner change notification will be lost, and the interface will keep reporting being invalid permanently. The fix is to delay initializing currentOwner until after the connection is made. Task-number: QTBUG-62284 Change-Id: I92b9d61004e14fd2ee2543488740a542dc7a9b7a Reviewed-by: Romain Pokrzywka Reviewed-by: Thiago Macieira --- src/dbus/qdbusabstractinterface.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/dbus') diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index c90173db76..9f2e688ebb 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -121,11 +121,6 @@ QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv if (!connection.isConnected()) { lastError = QDBusError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage()); - } else if (!service.isEmpty()) { - currentOwner = connectionPrivate()->getNameOwner(service); // verify the name owner - if (currentOwner.isEmpty()) { - lastError = connectionPrivate()->lastError; - } } } @@ -133,9 +128,14 @@ void QDBusAbstractInterfacePrivate::initOwnerTracking() { if (!isValid || !connection.isConnected() || !connectionPrivate()->shouldWatchService(service)) return; + QObject::connect(new QDBusServiceWatcher(service, connection, QDBusServiceWatcher::WatchForOwnerChange, q_func()), SIGNAL(serviceOwnerChanged(QString,QString,QString)), q_func(), SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + + currentOwner = connectionPrivate()->getNameOwner(service); + if (currentOwner.isEmpty()) + lastError = connectionPrivate()->lastError; } bool QDBusAbstractInterfacePrivate::canMakeCalls() const -- cgit v1.2.3