8#include <qcoreapplication.h>
10#include <qstringlist.h>
11#include <QtCore/private/qlocking_p.h>
22static void preventDllUnload();
25Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
27QDBusConnectionPrivate *QDBusConnectionManager::busConnection(QDBusConnection::BusType type)
29 static_assert(
int(QDBusConnection::SessionBus) +
int(QDBusConnection::SystemBus) == 1);
30 Q_ASSERT(type == QDBusConnection::SessionBus || type == QDBusConnection::SystemBus);
32 if (!qdbus_loadLibDBus())
37 bool suspendedDelivery = QThread::isMainThread() &&
qApp;
39 const auto locker = qt_scoped_lock(defaultBusMutex);
40 if (defaultBuses[type])
41 return defaultBuses[type];
43 QString name = QStringLiteral(
"qt_default_session_bus");
44 if (type == QDBusConnection::SystemBus)
45 name = QStringLiteral(
"qt_default_system_bus");
46 return defaultBuses[type] = connectToBus(type, name, suspendedDelivery);
51 return connectionHash.value(name,
nullptr);
56 const auto locker = qt_scoped_lock(mutex);
57 auto *conn = connection(name);
65 QDBusConnectionPrivate *d =
nullptr;
66 d = connectionHash.take(name);
67 if (d && !d->ref.deref())
79 const auto locker = qt_scoped_lock(mutex);
81 for (
const auto &name : names)
82 removeConnection(name);
86 QDBusConnectionPrivate::ConnectionMode mode)
88 const auto locker = qt_scoped_lock(mutex);
90 QDBusConnectionPrivate *d = connection(name);
91 if (d && d->mode != mode)
93 removeConnection(name);
111 defaultBuses[0] = defaultBuses[1] =
nullptr;
133 connectionHash[name] = c;
139 const auto locker = qt_scoped_lock(mutex);
140 setConnection(name, c);
148 const auto locker = qt_scoped_lock(mutex);
149 for (QDBusConnectionPrivate *d : std::as_const(connectionHash)) {
150 if (!d->ref.deref()) {
153 d->closeConnection();
154 d->moveToThread(
nullptr);
157 connectionHash.clear();
160 moveToThread(
nullptr);
164 bool suspendedDelivery)
166 QDBusConnectionPrivate *result =
nullptr;
168 QMetaObject::invokeMethod(
this, &QDBusConnectionManager::doConnectToStandardBus,
169 Qt::BlockingQueuedConnection, qReturnArg(result), type, name,
172 if (suspendedDelivery && result && result->connection)
173 result->enableDispatchDelayed(
qApp);
180 QDBusConnectionPrivate *result =
nullptr;
182 QMetaObject::invokeMethod(
this, &QDBusConnectionManager::doConnectToBus,
183 Qt::BlockingQueuedConnection, qReturnArg(result), address, name);
190 QDBusConnectionPrivate *result =
nullptr;
192 QMetaObject::invokeMethod(
this, &QDBusConnectionManager::doConnectToPeer,
193 Qt::BlockingQueuedConnection, qReturnArg(result), address, name);
198QDBusConnectionPrivate *
200 bool suspendedDelivery)
202 const auto locker = qt_scoped_lock(mutex);
205 QDBusConnectionPrivate *d = connection(name);
206 if (d || name.isEmpty())
209 d =
new QDBusConnectionPrivate;
210 DBusConnection *c =
nullptr;
211 QDBusErrorInternal error;
214 case QDBusConnection::SystemBus:
215 c = q_dbus_bus_get_private(DBUS_BUS_SYSTEM, error);
217 case QDBusConnection::SessionBus:
218 c = q_dbus_bus_get_private(DBUS_BUS_SESSION, error);
220 case QDBusConnection::ActivationBus:
221 c = q_dbus_bus_get_private(DBUS_BUS_STARTER, error);
225 setConnection(name, d);
229 d->setConnection(c, error);
230 d->createBusService();
231 if (c && suspendedDelivery)
232 d->setDispatchEnabled(
false);
240 const auto locker = qt_scoped_lock(mutex);
243 QDBusConnectionPrivate *d = connection(name);
244 if (d || name.isEmpty())
247 d =
new QDBusConnectionPrivate;
250 DBusConnection *c = q_dbus_connection_open_private(address.toUtf8().constData(), error);
253 if (!q_dbus_bus_register(c, error)) {
254 q_dbus_connection_close(c);
255 q_dbus_connection_unref(c);
260 setConnection(name, d);
264 d->setConnection(c, error);
265 d->createBusService();
273 const auto locker = qt_scoped_lock(mutex);
276 QDBusConnectionPrivate *d = connection(name);
277 if (d || name.isEmpty())
280 d =
new QDBusConnectionPrivate;
283 DBusConnection *c = q_dbus_connection_open_private(address.toUtf8().constData(), error);
285 setConnection(name, d);
286 d->setPeer(c, error);
293 QMetaObject::invokeMethod(
296 QDBusErrorInternal error;
297 QDBusConnectionPrivate *d =
new QDBusConnectionPrivate;
298 d->setServer(server, q_dbus_server_listen(address.toUtf8().constData(), error),
301 Qt::BlockingQueuedConnection);
306#include "moc_qdbusconnectionmanager_p.cpp"
309# include <qt_windows.h>
312static void preventDllUnload()
327 GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
328 GET_MODULE_HANDLE_EX_FLAG_PIN,
329 reinterpret_cast<
const wchar_t *>(&self),
QDBusConnectionPrivate * connectToBus(const QString &address, const QString &name)
static QDBusConnectionManager * instance()
void addConnection(const QString &name, QDBusConnectionPrivate *c)
void removeConnections(const QStringList &names)
QDBusConnectionPrivate * connectToPeer(const QString &address, const QString &name)
~QDBusConnectionManager()
void createServer(const QString &address, QDBusServer *server)
QDBusConnectionPrivate * existingConnection(const QString &name) const
void disconnectFrom(const QString &name, QDBusConnectionPrivate::ConnectionMode mode)
Q_DBUS_EXPORT void qDBusBindToApplication()