diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-03-30 19:38:32 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-09-15 02:08:55 +0000 |
commit | e15e5b1d37de1903d9c19c239d15440a783dc051 (patch) | |
tree | 8499a5341f43a980a3d888f0621b92321ed4bd4a /src/dbus/qdbusintegrator.cpp | |
parent | cc5ab92cd9e06511f7a65cc3195f01a730591768 (diff) |
Bypass connectSignal() for receiving the NameOwnerChanged signal
This is an optimization but is required. Instead of going through the
entire (dis)connectSignal() stack to add/remove matching rules for the
NameOwnerChanged bus signal and call into our serviceOwnerChangedNoLock
slot, create a static hook that will match the signal and simply add/
remove the rules as needed.
The required part is that this avoids a recursion into connectSignal().
The next commit will move this code to the QtDBus manager thread and we
won't be able to call connectSignal() from there (it would create a
deadlock).
Change-Id: Iee8cbc07c4434ce9b560ffff13d074ce90ad02d4
Reviewed-by: Albert Astals Cid <aacid@kde.org>
Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src/dbus/qdbusintegrator.cpp')
-rw-r--r-- | src/dbus/qdbusintegrator.cpp | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 7370d0bbfc..c86d9f1eba 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1679,6 +1679,15 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError Q_ASSERT(hook.midx != -1); signalHooks.insert(QLatin1String("NameLost:" DBUS_INTERFACE_DBUS), hook); + // And initialize the hook for the NameOwnerChanged signal; + // we don't use connectSignal here because the rules are added by connectSignal on a per-need basis + hook.params.clear(); + hook.params.reserve(4); + hook.params << QMetaType::Void << QVariant::String << QVariant::String << QVariant::String; + hook.midx = staticMetaObject.indexOfSlot("serviceOwnerChangedNoLock(QString,QString,QString)"); + Q_ASSERT(hook.midx != -1); + signalHooks.insert(QLatin1String("NameOwnerChanged:" DBUS_INTERFACE_DBUS), hook); + qDBusDebug() << this << ": connected successfully"; // schedule a dispatch: @@ -2090,9 +2099,10 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook WatchedServicesHash::mapped_type &data = watchedServices[hook.service]; if (++data.refcount == 1) { // we need to watch for this service changing - connectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), - QStringLiteral("NameOwnerChanged"), QStringList() << hook.service, QString(), - this, SLOT(serviceOwnerChangedNoLock(QString,QString,QString))); + q_dbus_bus_add_match(connection, + buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), + QDBusUtil::nameOwnerChanged(), QStringList() << hook.service, QString()), + NULL); data.owner = getNameOwnerNoCache(hook.service); qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:" << data.owner << ")"; @@ -2170,9 +2180,10 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) if (sit != watchedServices.end()) { if (--sit.value().refcount == 0) { watchedServices.erase(sit); - disconnectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), - QStringLiteral("NameOwnerChanged"), QStringList() << hook.service, QString(), - this, SLOT(serviceOwnerChangedNoLock(QString,QString,QString))); + q_dbus_bus_remove_match(connection, + buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), + QDBusUtil::nameOwnerChanged(), QStringList() << hook.service, QString()), + NULL); } } } |