From 9b4bd98744623f81b7b0950e207209f0c19adb46 Mon Sep 17 00:00:00 2001 From: Jan Arne Petersen Date: Mon, 15 Oct 2012 13:30:55 +0300 Subject: Fix QDBusServer with more than one connection Create a new QDBusConnectionPrivate for every new connection in qDBusNewConnection instead of creating a single QDBusConnectionPrivate in the QDBusServer constructor which gets assigned the latest connected DBusConnection in qDBusNewConnection (and loses track on all previous DBusConnections). Also extend tst_QDBusConnection::registerObjectPeer() test with multiple connections to the server. Task-Number: QTBUG-24921 Change-Id: I4341e8d48d464f3fe0a314a6ab14f848545d65a0 (cherry picked from qtbase/a386194f9952683c0be5028f2b7f0ce9617fe404) Reviewed-by: Thiago Macieira --- src/dbus/qdbusconnection_p.h | 1 + src/dbus/qdbusintegrator.cpp | 14 +++++--- src/dbus/qdbusserver.cpp | 8 ++--- tests/auto/qdbusconnection/tst_qdbusconnection.cpp | 38 +++++++++++++++++----- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 2443fca..476456a 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -274,6 +274,7 @@ public: QDBusConnection::ConnectionCapabilities capabilities; QString name; // this connection's name QString baseService; // this connection's base service + QStringList serverConnectionNames; ConnectionMode mode; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 71647e7..0f0b647 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -50,6 +50,7 @@ #include "qdbusargument.h" #include "qdbusconnection_p.h" +#include "qdbusconnectionmanager_p.h" #include "qdbusinterface_p.h" #include "qdbusmessage.h" #include "qdbusmetatype.h" @@ -385,16 +386,21 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v // keep the connection alive q_dbus_connection_ref(connection); - QDBusConnectionPrivate *d = static_cast(data); + QDBusConnectionPrivate *serverConnection = static_cast(data); + + QDBusConnectionPrivate *newConnection = new QDBusConnectionPrivate(serverConnection->parent()); + QMutexLocker locker(&QDBusConnectionManager::instance()->mutex); + QDBusConnectionManager::instance()->setConnection(QLatin1String("QDBusServer-") + QString::number(reinterpret_cast(newConnection)), newConnection); + serverConnection->serverConnectionNames << newConnection->name; // setPeer does the error handling for us QDBusErrorInternal error; - d->setPeer(connection, error); + newConnection->setPeer(connection, error); - QDBusConnection retval = QDBusConnectionPrivate::q(d); + QDBusConnection retval = QDBusConnectionPrivate::q(newConnection); // make QDBusServer emit the newConnection signal - d->serverConnection(retval); + serverConnection->serverConnection(retval); } } // extern "C" diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp index 6acc770..90bfa6e 100644 --- a/src/dbus/qdbusserver.cpp +++ b/src/dbus/qdbusserver.cpp @@ -72,9 +72,6 @@ QDBusServer::QDBusServer(const QString &address, QObject *parent) } d = new QDBusConnectionPrivate(this); - QMutexLocker locker(&QDBusConnectionManager::instance()->mutex); - QDBusConnectionManager::instance()->setConnection(QLatin1String("QDBusServer-") + QString::number(reinterpret_cast(d)), d); - QObject::connect(d, SIGNAL(newServerConnection(QDBusConnection)), this, SIGNAL(newConnection(QDBusConnection))); @@ -89,7 +86,10 @@ QDBusServer::~QDBusServer() { if (QDBusConnectionManager::instance()) { QMutexLocker locker(&QDBusConnectionManager::instance()->mutex); - QDBusConnectionManager::instance()->removeConnection(d->name); + Q_FOREACH (const QString &name, d->serverConnectionNames) { + QDBusConnectionManager::instance()->removeConnection(name); + } + d->serverConnectionNames.clear(); } } diff --git a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp index ae7affa..9436e16 100644 --- a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp @@ -391,38 +391,51 @@ class MyServer : public QDBusServer public: MyServer(QString path, QString addr, QObject* parent) : QDBusServer(addr, parent), m_path(path), - m_conn("none") + m_connections() { connect(this, SIGNAL(newConnection(const QDBusConnection&)), SLOT(handleConnection(const QDBusConnection&))); } - bool registerObject() + bool registerObject(const QDBusConnection& c) { - if( !m_conn.registerObject(m_path, &m_obj, QDBusConnection::ExportAllSlots) ) + QDBusConnection conn(c); + if (!conn.registerObject(m_path, &m_obj, QDBusConnection::ExportAllSlots)) return false; - if(! (m_conn.objectRegisteredAt(m_path) == &m_obj)) + if (!(conn.objectRegisteredAt(m_path) == &m_obj)) return false; return true; } + bool registerObject() + { + Q_FOREACH (const QString &name, m_connections) { + if (!registerObject(QDBusConnection(name))) + return false; + } + return true; + } + void unregisterObject() { - m_conn.unregisterObject(m_path); + Q_FOREACH (const QString &name, m_connections) { + QDBusConnection c(name); + c.unregisterObject(m_path); + } } public slots: void handleConnection(const QDBusConnection& c) { - m_conn = c; + m_connections << c.name(); QVERIFY(isConnected()); - QVERIFY(m_conn.isConnected()); - QVERIFY(registerObject()); + QVERIFY(c.isConnected()); + QVERIFY(registerObject(c)); } private: MyObject m_obj; QString m_path; - QDBusConnection m_conn; + QStringList m_connections; }; @@ -443,6 +456,8 @@ void tst_QDBusConnection::registerObjectPeer() MyServer server(path, "unix:tmpdir=/tmp", 0); + QDBusConnection::connectToPeer(server.address(), "beforeFoo"); + { QDBusConnection con = QDBusConnection::connectToPeer(server.address(), "foo"); @@ -454,6 +469,8 @@ void tst_QDBusConnection::registerObjectPeer() QCOMPARE(obj.path, path); } + QDBusConnection::connectToPeer(server.address(), "afterFoo"); + { QDBusConnection con("foo"); QVERIFY(con.isConnected()); @@ -483,6 +500,9 @@ void tst_QDBusConnection::registerObjectPeer() QVERIFY(!con.isConnected()); QVERIFY(!callMethodPeer(con, path)); } + + QDBusConnection::disconnectFromPeer("beforeFoo"); + QDBusConnection::disconnectFromPeer("afterFoo"); } void tst_QDBusConnection::registerObject2() -- cgit v0.12