summaryrefslogtreecommitdiffstats
path: root/src/dbus
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2009-10-23 17:35:19 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2009-10-28 09:16:54 (GMT)
commit1176ecf0b533279e5a1c97f183e5c5f1c57fb188 (patch)
tree2af718b03d7e424d4755f68d2328875c1b4850e1 /src/dbus
parented75146e45d41ca52b64193acbf433e6d2ceaaf5 (diff)
downloadQt-1176ecf0b533279e5a1c97f183e5c5f1c57fb188.zip
Qt-1176ecf0b533279e5a1c97f183e5c5f1c57fb188.tar.gz
Qt-1176ecf0b533279e5a1c97f183e5c5f1c57fb188.tar.bz2
Stop using the NameOwnerChanged signal without arg0 in QtDBus itself
We were using this signal to update the signal hooks when the remote service changed. That meant each Qt app received every single service creation, change or destruction. Now we only watch the services we're really interested in.
Diffstat (limited to 'src/dbus')
-rw-r--r--src/dbus/qdbusconnection.cpp4
-rw-r--r--src/dbus/qdbusconnection_p.h2
-rw-r--r--src/dbus/qdbusintegrator.cpp35
3 files changed, 37 insertions, 4 deletions
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 71e433e..d7088ff 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -1005,14 +1005,10 @@ void QDBusConnectionPrivate::setBusService(const QDBusConnection &connection)
busService = new QDBusConnectionInterface(connection, this);
ref.deref(); // busService has increased the refcounting to us
// avoid cyclic refcounting
-// if (mode != PeerMode)
- QObject::connect(busService, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
- this, SIGNAL(serviceOwnerChanged(QString,QString,QString)));
QObject::connect(this, SIGNAL(callWithCallbackFailed(QDBusError,QDBusMessage)),
busService, SIGNAL(callWithCallbackFailed(QDBusError,QDBusMessage)),
Qt::QueuedConnection);
-
}
/*!
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index 2402719..ed29e4e 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -154,6 +154,7 @@ public:
typedef QMultiHash<QString, SignalHook> SignalHookHash;
typedef QHash<QString, QDBusMetaObject* > MetaObjectHash;
typedef QHash<QByteArray, int> MatchRefCountHash;
+ typedef QHash<QString, int> WatchedServicesHash;
public:
// public methods are entry points from other objects
@@ -270,6 +271,7 @@ public:
QDBusError lastError;
QStringList serviceNames;
+ WatchedServicesHash watchedServiceNames;
SignalHookHash signalHooks;
MatchRefCountHash matchRefCounts;
ObjectTreeNode rootNode;
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 89a7449..c7538c3 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -501,6 +501,11 @@ static QObject *findChildObject(const QDBusConnectionPrivate::ObjectTreeNode *ro
return 0;
}
+static bool shouldWatchService(const QString &service)
+{
+ return !service.isEmpty() && !service.startsWith(QLatin1Char(':'));
+}
+
extern QDBUS_EXPORT void qDBusAddSpyHook(QDBusSpyHook);
void qDBusAddSpyHook(QDBusSpyHook hook)
{
@@ -941,6 +946,7 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
QDBusMetaTypeId::init();
rootNode.flags = 0;
+ watchedServiceNames[QLatin1String(DBUS_SERVICE_DBUS)] = 1;
connect(this, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
@@ -2005,6 +2011,22 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook
hook.obj->metaObject()->method(hook.midx).signature(),
qPrintable(qerror.name()), qPrintable(qerror.message()));
Q_ASSERT(false);
+ } else {
+ // Successfully connected the signal
+ // Do we need to watch for this name?
+ if (shouldWatchService(hook.service)) {
+ WatchedServicesHash::Iterator it = watchedServiceNames.find(hook.service);
+ if (it != watchedServiceNames.end()) {
+ // already watching
+ ++it.value();
+ } else {
+ // we need to watch for this service changing
+ QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS);
+ connectSignal(dbusServerService, dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS),
+ QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(),
+ this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
+ }
+ }
}
}
}
@@ -2051,6 +2073,19 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it)
{
const SignalHook &hook = it.value();
+ WatchedServicesHash::Iterator sit = watchedServiceNames.find(hook.service);
+ if (sit != watchedServiceNames.end()) {
+ if (sit.value() == 1) {
+ watchedServiceNames.erase(sit);
+ QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS);
+ disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS),
+ QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(),
+ this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
+ } else {
+ --sit.value();
+ }
+ }
+
bool erase = false;
MatchRefCountHash::iterator i = matchRefCounts.find(hook.matchRule);
if (i == matchRefCounts.end()) {