diff options
author | Romain Pokrzywka <romain.pokrzywka@gmail.com> | 2017-08-03 00:58:43 -0500 |
---|---|---|
committer | Jędrzej Nowacki <jedrzej.nowacki@qt.io> | 2017-08-04 18:47:55 +0000 |
commit | 02b0f44fab7808b4a687b526beada44c7015a98c (patch) | |
tree | 11e2de48fb3f75cf2cdf1f5982f385e2bc2f58b6 /src | |
parent | b22b5141404fe943e64ea7dad094097e8a0fd77d (diff) |
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 <romain.pokrzywka@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/dbus/qdbusabstractinterface.cpp | 10 |
1 files changed, 5 insertions, 5 deletions
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 |