summaryrefslogtreecommitdiffstats
path: root/src/dbus
diff options
context:
space:
mode:
Diffstat (limited to 'src/dbus')
-rw-r--r--src/dbus/qdbusconnection.cpp206
-rw-r--r--src/dbus/qdbusconnection_p.h2
-rw-r--r--src/dbus/qdbusconnectionmanager_p.h11
-rw-r--r--src/dbus/qdbusintegrator.cpp1
-rw-r--r--src/dbus/qdbusserver.cpp16
-rw-r--r--src/dbus/qdbusserver.h1
6 files changed, 142 insertions, 95 deletions
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 8ebdf4c66e..a5d674bb5a 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -59,6 +59,23 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
+struct QDBusConnectionManager::ConnectionRequestData
+{
+ enum RequestType {
+ ConnectToStandardBus,
+ ConnectToBusByAddress,
+ ConnectToPeerByAddress
+ } type;
+
+ union {
+ QDBusConnection::BusType busType;
+ const QString *busAddress;
+ };
+ const QString *name;
+
+ QDBusConnectionPrivate *result;
+};
+
QDBusConnectionPrivate *QDBusConnectionManager::connection(const QString &name) const
{
return connectionHash.value(name, 0);
@@ -80,7 +97,11 @@ void QDBusConnectionManager::removeConnection(const QString &name)
QDBusConnectionManager::QDBusConnectionManager()
{
- moveToThread(Q_NULLPTR); // we don't handle events
+ connect(this, &QDBusConnectionManager::connectionRequested,
+ this, &QDBusConnectionManager::executeConnectionRequest, Qt::BlockingQueuedConnection);
+ connect(this, &QDBusConnectionManager::serverRequested,
+ this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection);
+ moveToThread(this); // ugly, don't do this in other projects
start();
}
@@ -123,6 +144,103 @@ void QDBusConnectionManager::run()
}
}
connectionHash.clear();
+
+ // allow deletion from any thread without warning
+ moveToThread(Q_NULLPTR);
+}
+
+QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(QDBusConnection::BusType type, const QString &name)
+{
+ ConnectionRequestData data;
+ data.type = ConnectionRequestData::ConnectToStandardBus;
+ data.busType = type;
+ data.name = &name;
+
+ emit connectionRequested(&data);
+ return data.result;
+}
+
+QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(const QString &address, const QString &name)
+{
+ ConnectionRequestData data;
+ data.type = ConnectionRequestData::ConnectToBusByAddress;
+ data.busAddress = &address;
+ data.name = &name;
+
+ emit connectionRequested(&data);
+ return data.result;
+}
+
+QDBusConnectionPrivate *QDBusConnectionManager::connectToPeer(const QString &address, const QString &name)
+{
+ ConnectionRequestData data;
+ data.type = ConnectionRequestData::ConnectToPeerByAddress;
+ data.busAddress = &address;
+ data.name = &name;
+
+ emit connectionRequested(&data);
+ return data.result;
+}
+
+void QDBusConnectionManager::executeConnectionRequest(QDBusConnectionManager::ConnectionRequestData *data)
+{
+ QMutexLocker locker(&mutex);
+ const QString &name = *data->name;
+ QDBusConnectionPrivate *&d = data->result;
+
+ // check if the connection exists by name
+ d = connection(name);
+ if (d || name.isEmpty())
+ return;
+
+ d = new QDBusConnectionPrivate;
+ DBusConnection *c = 0;
+ QDBusErrorInternal error;
+ switch (data->type) {
+ case ConnectionRequestData::ConnectToStandardBus:
+ switch (data->busType) {
+ case QDBusConnection::SystemBus:
+ c = q_dbus_bus_get_private(DBUS_BUS_SYSTEM, error);
+ break;
+ case QDBusConnection::SessionBus:
+ c = q_dbus_bus_get_private(DBUS_BUS_SESSION, error);
+ break;
+ case QDBusConnection::ActivationBus:
+ c = q_dbus_bus_get_private(DBUS_BUS_STARTER, error);
+ break;
+ }
+ break;
+
+ case ConnectionRequestData::ConnectToBusByAddress:
+ case ConnectionRequestData::ConnectToPeerByAddress:
+ c = q_dbus_connection_open_private(data->busAddress->toUtf8().constData(), error);
+ if (c && data->type == ConnectionRequestData::ConnectToBusByAddress) {
+ // register on the bus
+ if (!q_dbus_bus_register(c, error)) {
+ q_dbus_connection_unref(c);
+ c = 0;
+ }
+ }
+ break;
+ }
+
+ setConnection(name, d);
+ if (data->type == ConnectionRequestData::ConnectToPeerByAddress) {
+ d->setPeer(c, error);
+ } else {
+ // create the bus service
+ // will lock in QDBusConnectionPrivate::connectRelay()
+ d->setConnection(c, error);
+ d->createBusService();
+ }
+}
+
+void QDBusConnectionManager::createServer(const QString &address, void *server)
+{
+ QDBusErrorInternal error;
+ QDBusConnectionPrivate *d = new QDBusConnectionPrivate;
+ d->setServer(static_cast<QDBusServer *>(server),
+ q_dbus_server_listen(address.toUtf8().constData(), error), error);
}
/*!
@@ -318,39 +436,7 @@ QDBusConnection QDBusConnection::connectToBus(BusType type, const QString &name)
QDBusConnectionPrivate *d = 0;
return QDBusConnection(d);
}
-
- QMutexLocker locker(&_q_manager()->mutex);
-
- QDBusConnectionPrivate *d = _q_manager()->connection(name);
- if (d || name.isEmpty())
- return QDBusConnection(d);
-
- d = new QDBusConnectionPrivate;
- DBusConnection *c = 0;
- QDBusErrorInternal error;
- switch (type) {
- case SystemBus:
- c = q_dbus_bus_get_private(DBUS_BUS_SYSTEM, error);
- break;
- case SessionBus:
- c = q_dbus_bus_get_private(DBUS_BUS_SESSION, error);
- break;
- case ActivationBus:
- c = q_dbus_bus_get_private(DBUS_BUS_STARTER, error);
- break;
- }
- d->setConnection(c, error); //setConnection does the error handling for us
-
- _q_manager()->setConnection(name, d);
-
- QDBusConnection retval(d);
-
- // create the bus service
- // will lock in QDBusConnectionPrivate::connectRelay()
- d->setBusService(retval);
- d->moveToThread(_q_manager());
-
- return retval;
+ return QDBusConnection(_q_manager()->connectToBus(type, name));
}
/*!
@@ -364,34 +450,7 @@ QDBusConnection QDBusConnection::connectToBus(const QString &address,
QDBusConnectionPrivate *d = 0;
return QDBusConnection(d);
}
-
- QMutexLocker locker(&_q_manager()->mutex);
-
- QDBusConnectionPrivate *d = _q_manager()->connection(name);
- if (d || name.isEmpty())
- return QDBusConnection(d);
-
- d = new QDBusConnectionPrivate;
- // setConnection does the error handling for us
- QDBusErrorInternal error;
- DBusConnection *c = q_dbus_connection_open_private(address.toUtf8().constData(), error);
- if (c) {
- if (!q_dbus_bus_register(c, error)) {
- q_dbus_connection_unref(c);
- c = 0;
- }
- }
- d->setConnection(c, error);
- _q_manager()->setConnection(name, d);
-
- QDBusConnection retval(d);
-
- // create the bus service
- // will lock in QDBusConnectionPrivate::connectRelay()
- d->setBusService(retval);
- d->moveToThread(_q_manager());
-
- return retval;
+ return QDBusConnection(_q_manager()->connectToBus(address, name));
}
/*!
\since 4.8
@@ -406,25 +465,7 @@ QDBusConnection QDBusConnection::connectToPeer(const QString &address,
QDBusConnectionPrivate *d = 0;
return QDBusConnection(d);
}
-
- QMutexLocker locker(&_q_manager()->mutex);
-
- QDBusConnectionPrivate *d = _q_manager()->connection(name);
- if (d || name.isEmpty())
- return QDBusConnection(d);
-
- d = new QDBusConnectionPrivate;
- // setPeer does the error handling for us
- QDBusErrorInternal error;
- DBusConnection *c = q_dbus_connection_open_private(address.toUtf8().constData(), error);
-
- d->setPeer(c, error);
- _q_manager()->setConnection(name, d);
- d->moveToThread(_q_manager());
-
- QDBusConnection retval(d);
-
- return retval;
+ return QDBusConnection(_q_manager()->connectToPeer(address, name));
}
/*!
@@ -1130,9 +1171,10 @@ QDBusConnection QDBusConnection::sender()
/*!
\internal
*/
-void QDBusConnectionPrivate::setBusService(const QDBusConnection &connection)
+void QDBusConnectionPrivate::createBusService()
{
Q_ASSERT(mode == ClientMode);
+ QDBusConnection connection(this);
busService = new QDBusConnectionInterface(connection, this);
ref.deref(); // busService has increased the refcounting to us
// avoid cyclic refcounting
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index f653c427e7..765e4281fd 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -190,7 +190,7 @@ public:
explicit QDBusConnectionPrivate(QObject *parent = 0);
~QDBusConnectionPrivate();
- void setBusService(const QDBusConnection &connection);
+ void createBusService();
void setPeer(DBusConnection *connection, const QDBusErrorInternal &error);
void setConnection(DBusConnection *connection, const QDBusErrorInternal &error);
void setServer(QDBusServer *object, DBusServer *server, const QDBusErrorInternal &error);
diff --git a/src/dbus/qdbusconnectionmanager_p.h b/src/dbus/qdbusconnectionmanager_p.h
index c3c7999699..4527c562f8 100644
--- a/src/dbus/qdbusconnectionmanager_p.h
+++ b/src/dbus/qdbusconnectionmanager_p.h
@@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE
class QDBusConnectionManager : public QDaemonThread
{
Q_OBJECT
+ struct ConnectionRequestData;
public:
QDBusConnectionManager();
~QDBusConnectionManager();
@@ -65,13 +66,23 @@ public:
QDBusConnectionPrivate *connection(const QString &name) const;
void removeConnection(const QString &name);
void setConnection(const QString &name, QDBusConnectionPrivate *c);
+ QDBusConnectionPrivate *connectToBus(QDBusConnection::BusType type, const QString &name);
+ QDBusConnectionPrivate *connectToBus(const QString &address, const QString &name);
+ QDBusConnectionPrivate *connectToPeer(const QString &address, const QString &name);
mutable QMutex mutex;
+signals:
+ void connectionRequested(ConnectionRequestData *);
+ void serverRequested(const QString &address, void *server);
+
protected:
void run() Q_DECL_OVERRIDE;
private:
+ void executeConnectionRequest(ConnectionRequestData *data);
+ void createServer(const QString &address, void *server);
+
QHash<QString, QDBusConnectionPrivate *> connectionHash;
mutable QMutex senderMutex;
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index d5eaf39021..9b0a51107a 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -1644,6 +1644,7 @@ void QDBusConnectionPrivate::setServer(QDBusServer *object, DBusServer *s, const
{
mode = ServerMode;
serverObject = object;
+ object->d = this;
if (!s) {
handleError(error);
return;
diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp
index a0b2c8283c..6c1b4c10ef 100644
--- a/src/dbus/qdbusserver.cpp
+++ b/src/dbus/qdbusserver.cpp
@@ -63,14 +63,10 @@ QDBusServer::QDBusServer(const QString &address, QObject *parent)
d = 0;
return;
}
- d = new QDBusConnectionPrivate;
+ emit QDBusConnectionManager::instance()->serverRequested(address, this);
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
-
- QDBusErrorInternal error;
- d->setServer(this, q_dbus_server_listen(address.toUtf8().constData(), error), error);
- d->moveToThread(QDBusConnectionManager::instance());
}
/*!
@@ -83,23 +79,19 @@ QDBusServer::QDBusServer(QObject *parent)
{
#ifdef Q_OS_UNIX
// Use Unix sockets on Unix systems only
- static const char address[] = "unix:tmpdir=/tmp";
+ const QString address = QStringLiteral("unix:tmpdir=/tmp");
#else
- static const char address[] = "tcp:";
+ const QString address = QStringLiteral("tcp:");
#endif
if (!qdbus_loadLibDBus()) {
d = 0;
return;
}
- d = new QDBusConnectionPrivate;
+ emit QDBusConnectionManager::instance()->serverRequested(address, this);
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
-
- QDBusErrorInternal error;
- d->setServer(this, q_dbus_server_listen(address, error), error);
- d->moveToThread(QDBusConnectionManager::instance());
}
/*!
diff --git a/src/dbus/qdbusserver.h b/src/dbus/qdbusserver.h
index 2c66472a4d..3cb2ec8c50 100644
--- a/src/dbus/qdbusserver.h
+++ b/src/dbus/qdbusserver.h
@@ -69,6 +69,7 @@ private:
Q_DISABLE_COPY(QDBusServer)
Q_PRIVATE_SLOT(d, void _q_newConnection(QDBusConnectionPrivate*))
QDBusConnectionPrivate *d;
+ friend class QDBusConnectionPrivate;
};
QT_END_NAMESPACE