7#include <qcoreapplication.h>
8#include <qelapsedtimer.h>
9#include <qloggingcategory.h>
10#include <qmetaobject.h>
12#include <qsocketnotifier.h>
13#include <qstringlist.h>
15#include <private/qlocking_p.h>
16#include <QtCore/qset.h>
45using namespace Qt::StringLiterals;
47QT_IMPL_METATYPE_EXTERN(QDBusSlotCache)
54Q_CONSTINIT
static QBasicAtomicInt isDebugging = Q_BASIC_ATOMIC_INITIALIZER(-1);
55#define qDBusDebug if (::isDebugging.loadRelaxed() == 0
); else qDebug
57static inline QDebug operator<<(QDebug dbg,
const QThread *th)
59 QDebugStateSaver saver(dbg);
60 dbg.nospace() <<
"QThread(ptr=" << (
const void*)th;
61 if (th && !th->objectName().isEmpty())
62 dbg.nospace() <<
", name=" << th->objectName();
64 dbg.nospace() <<
", name=" << th->metaObject()->className();
70static inline QDebug operator<<(QDebug dbg,
const QDBusConnectionPrivate *conn)
72 QDebugStateSaver saver(dbg);
73 dbg.nospace() <<
"QDBusConnection("
74 <<
"ptr=" << (
const void*)conn
75 <<
", name=" << conn->name
76 <<
", baseService=" << conn->baseService
81void qdbusDefaultThreadDebug(
int action,
int condition, QDBusConnectionPrivate *conn)
83 qDBusDebug() << QThread::currentThread()
84 <<
"Qt D-Bus threading action" << action
85 << (condition == QDBusLockerBase::BeforeLock ?
"before lock" :
86 condition == QDBusLockerBase::AfterLock ?
"after lock" :
87 condition == QDBusLockerBase::BeforeUnlock ?
"before unlock" :
88 condition == QDBusLockerBase::AfterUnlock ?
"after unlock" :
89 condition == QDBusLockerBase::BeforePost ?
"before event posting" :
90 condition == QDBusLockerBase::AfterPost ?
"after event posting" :
91 condition == QDBusLockerBase::BeforeDeliver ?
"before event delivery" :
92 condition == QDBusLockerBase::AfterDeliver ?
"after event delivery" :
93 condition == QDBusLockerBase::BeforeAcquire ?
"before acquire" :
94 condition == QDBusLockerBase::AfterAcquire ?
"after acquire" :
95 condition == QDBusLockerBase::BeforeRelease ?
"before release" :
96 condition == QDBusLockerBase::AfterRelease ?
"after release" :
98 <<
"in connection" << conn;
100qdbusThreadDebugFunc qdbusThreadDebug =
nullptr;
108 const auto locker = qt_scoped_lock(lock);
118 const auto locker = qt_scoped_lock(lock);
122 for (
auto hook : std::as_const(hookListCopy))
144 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
145 Q_ASSERT(QThread::currentThread() == d->thread());
151 Q_ASSERT(d->timeouts.key(timeout, 0) == 0);
153 using namespace std::chrono_literals;
154 int timerId = d->startTimer(q_dbus_timeout_get_interval(timeout) * 1ms);
158 d->timeouts[timerId] = timeout;
169 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
170 Q_ASSERT(QThread::currentThread() == d->thread());
172 QDBusConnectionPrivate::TimeoutHash::iterator it = d->timeouts.begin();
173 while (it != d->timeouts.end()) {
174 if (it.value() == timeout) {
175 d->killTimer(it.key());
176 it = d->timeouts.erase(it);
200 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
201 Q_ASSERT(QThread::currentThread() == d->thread());
203 int flags = q_dbus_watch_get_flags(watch);
206 QDBusConnectionPrivate::Watcher watcher;
208 if (flags & DBUS_WATCH_READABLE) {
210 watcher.watch = watch;
211 watcher.read =
new QSocketNotifier(fd, QSocketNotifier::Read, d);
212 watcher.read->setEnabled(q_dbus_watch_get_enabled(watch));
213 d->connect(watcher.read, &QSocketNotifier::activated, d, &QDBusConnectionPrivate::socketRead);
215 if (flags & DBUS_WATCH_WRITABLE) {
217 watcher.watch = watch;
218 watcher.write =
new QSocketNotifier(fd, QSocketNotifier::Write, d);
219 watcher.write->setEnabled(q_dbus_watch_get_enabled(watch));
220 d->connect(watcher.write, &QSocketNotifier::activated, d, &QDBusConnectionPrivate::socketWrite);
222 d->watchers.insert(fd, watcher);
234 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
235 Q_ASSERT(QThread::currentThread() == d->thread());
238 QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
239 while (i != d->watchers.end() && i.key() == fd) {
240 if (i.value().watch == watch) {
241 delete i.value().read;
242 delete i.value().write;
243 i = d->watchers.erase(i);
255 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
256 Q_ASSERT(QThread::currentThread() == d->thread());
259 QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
260 while (i != d->watchers.end() && i.key() == fd) {
261 if (i.value().watch == watch) {
262 bool enabled = q_dbus_watch_get_enabled(watch);
263 int flags = q_dbus_watch_get_flags(watch);
267 if (flags & DBUS_WATCH_READABLE && i.value().read)
268 i.value().read->setEnabled(enabled);
269 if (flags & DBUS_WATCH_WRITABLE && i.value().write)
270 i.value().write->setEnabled(enabled);
279 Q_ASSERT(connection);
280 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
281 if (new_status == DBUS_DISPATCH_DATA_REMAINS)
282 emit d->dispatchStatusChanged();
289 Q_ASSERT(connection);
297 q_dbus_connection_ref(connection);
298 QDBusConnectionPrivate *serverConnection =
static_cast<QDBusConnectionPrivate *>(data);
301 if (serverConnection->anonymousAuthenticationAllowed)
302 q_dbus_connection_set_allow_anonymous(connection,
true);
304 QDBusConnectionPrivate *newConnection =
new QDBusConnectionPrivate;
306 manager->addConnection(
307 "QDBusServer-"_L1 + QString::number(
reinterpret_cast<qulonglong>(newConnection), 16),
310 QWriteLocker locker(&serverConnection->lock);
311 serverConnection->serverConnectionNames << newConnection->name;
316 newConnection->setPeer(connection, error);
317 newConnection->setDispatchEnabled(
false);
319 QReadLocker serverLock(&serverConnection->lock);
320 if (!serverConnection->serverObject)
324 QMetaObject::invokeMethod(serverConnection->serverObject, &QDBusServer::newConnection,
325 Qt::QueuedConnection, QDBusConnectionPrivate::q(newConnection));
332 newConnection->enableDispatchDelayed(serverConnection->serverObject);
338 const QString &objectPath,
const QString &interface,
339 const QString &member,
const QDBusConnectionPrivate::ArgMatchRules &argMatch,
const QString & )
342 result +=
"type='signal',"_L1;
343 const auto keyValue =
"%1='%2',"_L1;
345 if (!service.isEmpty())
346 result += keyValue.arg(
"sender"_L1, service);
347 if (!objectPath.isEmpty())
348 result += keyValue.arg(
"path"_L1, objectPath);
349 if (!interface.isEmpty())
350 result += keyValue.arg(
"interface"_L1, interface);
351 if (!member.isEmpty())
352 result += keyValue.arg(
"member"_L1, member);
355 if (!argMatch.args.isEmpty()) {
356 const QString keyValue =
"arg%1='%2',"_L1;
357 for (
int i = 0; i < argMatch.args.size(); ++i)
358 if (!argMatch.args.at(i).isNull())
359 result += keyValue.arg(i).arg(argMatch.args.at(i));
361 if (!argMatch.arg0namespace.isEmpty()) {
362 result +=
"arg0namespace='%1',"_L1.arg(argMatch.arg0namespace);
366 return result.toLatin1();
369static bool findObject(
const QDBusConnectionPrivate::ObjectTreeNode *root,
370 const QString &fullpath,
int &usedLength,
371 QDBusConnectionPrivate::ObjectTreeNode &result)
373 if (!fullpath.compare(
"/"_L1) && root->obj) {
379 int length = fullpath.size();
380 if (fullpath.at(0) == u'/')
384 const QDBusConnectionPrivate::ObjectTreeNode *node = root;
385 while (start < length && node) {
386 if (node->flags & QDBusConnection::ExportChildObjects)
388 if ((node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath))
390 int end = fullpath.indexOf(u'/', start);
391 end = (end == -1 ? length : end);
392 QStringView pathComponent = QStringView{fullpath}.mid(start, end - start);
394 QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator it =
395 std::lower_bound(node->children.constBegin(), node->children.constEnd(), pathComponent);
396 if (it != node->children.constEnd() && it->name == pathComponent)
406 usedLength = (start > length ? length : start);
408 if (node->obj || !node->children.isEmpty())
419 const QString &fullpath,
int start)
421 int length = fullpath.size();
424 const QDBusConnectionPrivate::ObjectTreeNode *node = root;
425 if (node && node->flags & QDBusConnection::ExportChildObjects) {
426 QObject *obj = node->obj;
433 int pos = fullpath.indexOf(u'/', start);
434 pos = (pos == -1 ? length : pos);
435 auto pathComponent = QStringView{fullpath}.mid(start, pos - start);
438 QObject *next =
nullptr;
439 for (QObject *child : std::as_const(obj->children())) {
440 if (child->objectName() == pathComponent) {
460 QDBusConnectionPrivate::ArgMatchRules matchArgs;
461 if (service.endsWith(u'*')) {
462 matchArgs.arg0namespace = service.chopped(1);
463 matchArgs.args << QString();
466 matchArgs.args << service;
469 case QDBusServiceWatcher::WatchForOwnerChange:
472 case QDBusServiceWatcher::WatchForRegistration:
473 matchArgs.args << QString::fromLatin1(
"", 0);
476 case QDBusServiceWatcher::WatchForUnregistration:
477 matchArgs.args << QString() << QString::fromLatin1(
"", 0);
487 auto *hooks = qDBusSpyHookList();
499 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(
const_cast<QObject *>(sender()));
500 qDBusDebug() << d <<
"message spies done for" << msg;
501 emit d->spyHooksFinished(msg);
511 if (!qDBusSpyHookList.exists())
514 qDBusSpyHookList->invoke(msg);
518static DBusHandlerResult
522 Q_UNUSED(connection);
523 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
524 if (d->mode == QDBusConnectionPrivate::InvalidMode)
525 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
527 QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message, d->connectionCapabilities());
528 qDBusDebug() << d <<
"got message (signal):" << amsg;
530 return d->handleMessage(amsg) ?
531 DBUS_HANDLER_RESULT_HANDLED :
532 DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
536bool QDBusConnectionPrivate::handleMessage(
const QDBusMessage &amsg)
538 if (!ref.loadRelaxed())
543 bool isLocal = QDBusMessagePrivate::isLocal(amsg);
545 if (!dispatchEnabled && !isLocal) {
547 qDBusDebug() <<
this <<
"delivery is suspended";
548 pendingMessages << amsg;
549 return amsg.type() == QDBusMessage::MethodCallMessage;
552 switch (amsg.type()) {
553 case QDBusMessage::SignalMessage:
558 case QDBusMessage::MethodCallMessage:
562 if (Q_UNLIKELY(qDBusSpyHookList.exists()) && QCoreApplication::instanceExists()) {
564 Q_ASSERT(QThread::currentThread() != thread());
565 qDBusDebug() <<
this <<
"invoking message spies directly";
566 QDBusSpyCallEvent::invokeSpyHooks(amsg);
568 qDBusDebug() <<
this <<
"invoking message spies via event";
569 QCoreApplication::postEvent(
570 qApp,
new QDBusSpyCallEvent(
this, QDBusConnection(
this), amsg));
577 handleObjectCall(amsg);
579 case QDBusMessage::ReplyMessage:
580 case QDBusMessage::ErrorMessage:
581 case QDBusMessage::InvalidMessage:
588static void huntAndDestroy(QObject *needle, QDBusConnectionPrivate::ObjectTreeNode &haystack)
590 for (QDBusConnectionPrivate::ObjectTreeNode &node : haystack.children)
591 huntAndDestroy(needle, node);
593 auto isInactive = [](
const QDBusConnectionPrivate::ObjectTreeNode &node) {
return !node.isActive(); };
594 haystack.children.removeIf(isInactive);
596 if (needle == haystack.obj) {
597 haystack.obj =
nullptr;
603 QDBusConnection::UnregisterMode mode,
604 QDBusConnectionPrivate::ObjectTreeNode *node)
606 if (pathComponents.size() == i) {
611 if (mode == QDBusConnection::UnregisterTree) {
613 node->children.clear();
618 QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator end = node->children.end();
619 QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it =
620 std::lower_bound(node->children.begin(), end, pathComponents.at(i));
621 if (it == end || it->name != pathComponents.at(i))
624 huntAndUnregister(pathComponents, i + 1, mode, &(*it));
626 node->children.erase(it);
630static void huntAndEmit(DBusConnection *connection, DBusMessage *msg,
631 QObject *needle,
const QDBusConnectionPrivate::ObjectTreeNode &haystack,
632 bool isScriptable,
bool isAdaptor,
const QString &path = QString())
634 for (
const QDBusConnectionPrivate::ObjectTreeNode &node : std::as_const(haystack.children)) {
635 if (node.isActive()) {
636 huntAndEmit(connection, msg, needle, node, isScriptable, isAdaptor,
637 path + u'/' + node.name);
641 if (needle == haystack.obj) {
643 if (isAdaptor && (haystack.flags & QDBusConnection::ExportAdaptors) == 0)
645 else if (!isAdaptor) {
646 int mask = isScriptable
647 ? QDBusConnection::ExportScriptableSignals
648 : QDBusConnection::ExportNonScriptableSignals;
649 if ((haystack.flags & mask) == 0)
653 QByteArray p = path.toLatin1();
656 qDBusDebug() << QThread::currentThread() <<
"emitting signal at" << p;
658 q_dbus_message_set_path(msg2, p);
664static int findSlot(
const QMetaObject *mo,
const QByteArray &name,
int flags,
665 const QString &signature_, QList<QMetaType> &metaTypes)
667 QByteArray msgSignature = signature_.toLatin1();
668 QString parametersErrorMsg;
670 for (
int idx = mo->methodCount() - 1 ; idx >= QObject::staticMetaObject.methodCount(); --idx) {
671 QMetaMethod mm = mo->method(idx);
674 if (mm.access() != QMetaMethod::Public)
678 if (mm.methodType() != QMetaMethod::Slot && mm.methodType() != QMetaMethod::Method)
682 if (mm.name() != name)
685 QMetaType returnType = mm.returnMetaType();
686 bool isAsync = qDBusCheckAsyncTag(mm.tag());
687 bool isScriptable = mm.attributes() & QMetaMethod::Scriptable;
690 if (isAsync && returnType.id() != QMetaType::Void)
694 int inputCount = qDBusParametersForMethod(mm, metaTypes, errorMsg);
695 if (inputCount == -1) {
696 parametersErrorMsg = errorMsg;
700 metaTypes[0] = returnType;
701 bool hasMessage =
false;
702 if (inputCount > 0 &&
703 metaTypes.at(inputCount) == QDBusMetaTypeId::message()) {
711 QByteArray reconstructedSignature;
712 for (i = 1; i <= inputCount; ++i) {
713 const char *typeSignature = QDBusMetaType::typeToSignature( metaTypes.at(i) );
717 reconstructedSignature += typeSignature;
718 if (!msgSignature.startsWith(reconstructedSignature))
722 if (reconstructedSignature != msgSignature)
729 if (returnType.isValid() && returnType.id() != QMetaType::Void && QDBusMetaType::typeToSignature(returnType) ==
nullptr)
733 for (
int j = i; ok && j < metaTypes.size(); ++j)
734 if (QDBusMetaType::typeToSignature(metaTypes.at(i)) ==
nullptr)
740 if (isAsync && metaTypes.size() > i + 1)
743 if (mm.methodType() == QMetaMethod::Slot) {
744 if (isScriptable && (flags & QDBusConnection::ExportScriptableSlots) == 0)
746 if (!isScriptable && (flags & QDBusConnection::ExportNonScriptableSlots) == 0)
749 if (isScriptable && (flags & QDBusConnection::ExportScriptableInvokables) == 0)
751 if (!isScriptable && (flags & QDBusConnection::ExportNonScriptableInvokables) == 0)
760 if (!parametersErrorMsg.isEmpty()) {
761 qCWarning(dbusIntegration,
"QDBusConnection: couldn't handle call to %s: %ls",
764 qCWarning(dbusIntegration,
"QDBusConnection: couldn't handle call to %s, no slot matched",
771
772
773
774
775
776void QDBusConnectionPrivate::setDispatchEnabled(
bool enable)
779 dispatchEnabled = enable;
781 emit dispatchStatusChanged();
786QDBusCallDeliveryEvent *QDBusConnectionPrivate::prepareReply(QDBusConnectionPrivate *target,
787 QObject *object,
int idx,
788 const QList<QMetaType> &metaTypes,
789 const QDBusMessage &msg)
793 int n = metaTypes.size() - 1;
794 if (metaTypes[n] == QDBusMetaTypeId::message())
797 if (msg.arguments().size() < n)
801 for (
int i = 0; i < n; ++i)
802 if (metaTypes.at(i + 1) != msg.arguments().at(i).metaType() &&
803 msg.arguments().at(i).metaType() != QMetaType::fromType<QDBusArgument>())
808 if (target == object)
809 return DIRECT_DELIVERY;
810 return new QDBusCallDeliveryEvent(QDBusConnection(target), idx, target, msg, metaTypes);
813void QDBusConnectionPrivate::activateSignal(
const QDBusConnectionPrivate::SignalHook& hook,
814 const QDBusMessage &msg)
823 QDBusCallDeliveryEvent *call = prepareReply(
this, hook.obj, hook.midx, hook.params, msg);
824 if (call == DIRECT_DELIVERY) {
826 Q_ASSERT(
this == hook.obj);
827 deliverCall(
this, msg, hook.params, hook.midx);
831 postEventToThread(ActivateSignalAction, hook.obj, call);
834bool QDBusConnectionPrivate::activateCall(QObject *object, QDBusConnection::RegisterOptions flags,
835 const QDBusMessage &msg)
857 static const char cachePropertyName[] =
"_qdbus_slotCache";
862 Q_ASSERT_X(QThread::currentThread() == object->thread(),
863 "QDBusConnection: internal threading error",
864 "function called for an object that is in another thread!!");
866 QDBusSlotCache slotCache =
867 qvariant_cast<QDBusSlotCache>(object->property(cachePropertyName));
868 QString cacheKey = msg.member(), signature = msg.signature();
869 if (!signature.isEmpty()) {
870 cacheKey.reserve(cacheKey.size() + 1 + signature.size());
872 cacheKey += signature;
875 QDBusSlotCache::Key compoundKey{ std::move(cacheKey), flags };
876 QDBusSlotCache::Hash::ConstIterator cacheIt = slotCache.hash.constFind(compoundKey);
877 if (cacheIt == slotCache.hash.constEnd()) {
879 const QMetaObject *mo = object->metaObject();
880 QByteArray memberName = msg.member().toUtf8();
883 QDBusSlotCache::Data slotData;
884 slotData.slotIdx = ::findSlot(mo, memberName, flags, msg.signature(), slotData.metaTypes);
885 if (slotData.slotIdx == -1) {
888 slotData.slotIdx = ::findSlot(mo, memberName, flags, QString(), slotData.metaTypes);
889 if (slotData.metaTypes.size() != 2 ||
890 slotData.metaTypes.at(1) != QDBusMetaTypeId::message()) {
893 slotData.slotIdx = -1;
894 slotData.metaTypes.clear();
895 slotCache.hash.insert(compoundKey, slotData);
896 object->setProperty(cachePropertyName, QVariant::fromValue(slotCache));
898 qCWarning(dbusIntegration).nospace() <<
"Could not find slot " << mo->className()
899 <<
"::" << memberName.constData();
905 slotCache.hash.insert(compoundKey, slotData);
906 object->setProperty(cachePropertyName, QVariant::fromValue(slotCache));
909 deliverCall(object, msg, slotData.metaTypes, slotData.slotIdx);
911 }
else if (cacheIt->slotIdx == -1) {
916 deliverCall(object, msg, cacheIt->metaTypes, cacheIt->slotIdx);
922void QDBusConnectionPrivate::deliverCall(QObject *object,
const QDBusMessage &msg,
923 const QList<QMetaType> &metaTypes,
int slotIdx)
925 Q_ASSERT_X(!object || QThread::currentThread() == object->thread(),
926 "QDBusConnection: internal threading error",
927 "function called for an object that is in another thread!!");
929 QVarLengthArray<
void *, 10> params;
930 params.reserve(metaTypes.size());
932 QVarLengthArray<QVariant, 10> auxParameters;
933 auxParameters.reserve(metaTypes.size());
938 params.append(
nullptr);
942 int pCount = qMin(msg.arguments().size(), metaTypes.size() - 1);
943 for (i = 1; i <= pCount; ++i) {
944 auto id = metaTypes[i];
945 if (id == QDBusMetaTypeId::message())
948 const QList<QVariant> args = msg.arguments();
949 const QVariant &arg = args.at(i - 1);
950 if (arg.metaType() == id)
952 params.append(
const_cast<
void *>(arg.constData()));
953 else if (arg.metaType() == QMetaType::fromType<QDBusArgument>()) {
955 auxParameters.append(QVariant(QMetaType(id)));
957 const QDBusArgument &in =
958 *
reinterpret_cast<
const QDBusArgument *>(arg.constData());
959 QVariant &out = auxParameters[auxParameters.size() - 1];
961 if (Q_UNLIKELY(!QDBusMetaType::demarshall(in, out.metaType(), out.data())))
962 qFatal(
"Internal error: demarshalling function for type '%s' (%d) failed!",
963 out.typeName(), out.metaType().id());
965 params.append(
const_cast<
void *>(out.constData()));
967 qFatal(
"Internal error: got invalid meta type %d (%s) "
968 "when trying to convert to meta type %d (%s)",
969 arg.metaType().id(), arg.metaType().name(),
974 if (metaTypes.size() > i && metaTypes[i] == QDBusMetaTypeId::message()) {
975 params.append(
const_cast<
void*>(
static_cast<
const void*>(&msg)));
980 const int numMetaTypes = metaTypes.size();
981 QVariantList outputArgs;
982 if (metaTypes[0].id() != QMetaType::Void && metaTypes[0].isValid()) {
983 outputArgs.reserve(numMetaTypes - i + 1);
984 QVariant arg{QMetaType(metaTypes[0])};
985 outputArgs.append( arg );
986 params[0] =
const_cast<
void*>(outputArgs.at( outputArgs.size() - 1 ).constData());
988 outputArgs.reserve(numMetaTypes - i);
991 for ( ; i < numMetaTypes; ++i) {
992 QVariant arg{QMetaType(metaTypes[i])};
993 outputArgs.append( arg );
994 params.append(
const_cast<
void*>(outputArgs.at( outputArgs.size() - 1 ).constData()));
1003 QDBusContextPrivate context(QDBusConnection(
this), msg);
1004 QDBusContextPrivate *old = QDBusContextPrivate::set(object, &context);
1006 QPointer<QObject> ptr = object;
1007 fail = object->qt_metacall(QMetaObject::InvokeMetaMethod,
1008 slotIdx, params.data()) >= 0;
1011 QDBusContextPrivate::set(object, old);
1016 if (msg.isReplyRequired() && !msg.isDelayedReply()) {
1019 qDBusDebug() <<
this <<
"Automatically sending reply:" << outputArgs;
1020 send(msg.createReply(outputArgs));
1023 qCWarning(dbusIntegration,
"Internal error: Failed to deliver message");
1024 send(msg.createErrorReply(QDBusError::InternalError,
"Failed to deliver message"_L1));
1031QDBusConnectionPrivate::QDBusConnectionPrivate()
1034 busService(
nullptr),
1035 connection(
nullptr),
1036 rootNode(QStringLiteral(
"/")),
1037 anonymousAuthenticationAllowed(
false),
1038 dispatchEnabled(
true),
1039 isAuthenticated(
false)
1041 static const bool threads = q_dbus_threads_init_default();
1043 if (::isDebugging.loadRelaxed() == -1)
1044 ::isDebugging.storeRelaxed(qEnvironmentVariableIntValue(
"QDBUS_DEBUG"));
1046#ifdef QDBUS_THREAD_DEBUG
1047 if (::isDebugging.loadRelaxed() > 1)
1048 qdbusThreadDebug = qdbusDefaultThreadDebug;
1051 QDBusMetaTypeId::init();
1052 connect(
this, &QDBusConnectionPrivate::dispatchStatusChanged,
1053 this, &QDBusConnectionPrivate::doDispatch, Qt::QueuedConnection);
1054 connect(
this, &QDBusConnectionPrivate::spyHooksFinished,
1055 this, &QDBusConnectionPrivate::handleObjectCall, Qt::QueuedConnection);
1056 connect(
this, &QDBusConnectionPrivate::messageNeedsSending,
1057 this, &QDBusConnectionPrivate::sendInternal);
1059 rootNode.flags = {};
1063 watchedServices.insert(QDBusUtil::dbusService(), WatchedServiceData(QDBusUtil::dbusService(), 1));
1067 matchRefCounts.insert(
"type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='org.freedesktop.DBus'", 1);
1070QDBusConnectionPrivate::~QDBusConnectionPrivate()
1072 if (thread() && thread() != QThread::currentThread())
1074 "QDBusConnection(name=\"%s\")'s last reference in not in its creation thread! "
1075 "Timer and socket errors will follow and the program will probably crash",
1078 auto lastMode = mode;
1080 qDeleteAll(cachedMetaObjects);
1082 if (lastMode == ClientMode || lastMode == PeerMode) {
1085 Q_ASSERT(ref.loadRelaxed() == 0);
1086 QObject *obj = (QObject *)busService;
1088 disconnect(obj,
nullptr,
this,
nullptr);
1092 q_dbus_connection_unref(connection);
1093 connection =
nullptr;
1094 }
else if (lastMode == ServerMode) {
1096 q_dbus_server_unref(server);
1101void QDBusConnectionPrivate::collectAllObjects(QDBusConnectionPrivate::ObjectTreeNode &haystack,
1102 QSet<QObject *> &set)
1104 for (ObjectTreeNode &child : haystack.children)
1105 collectAllObjects(child, set);
1108 set.insert(haystack.obj);
1111void QDBusConnectionPrivate::closeConnection()
1113 QDBusWriteLocker locker(CloseConnectionAction,
this);
1115 ConnectionMode oldMode = mode;
1117 baseService.clear();
1119 if (oldMode == ServerMode && server) {
1120 q_dbus_server_disconnect(server);
1121 q_dbus_server_free_data_slot(&server_slot);
1124 if (oldMode == ClientMode || oldMode == PeerMode) {
1126 q_dbus_connection_close(connection);
1128 while (q_dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS)
1133 for (QDBusPendingCallPrivate *call : pendingCalls) {
1134 if (!call->ref.deref())
1137 pendingCalls.clear();
1144 QSet<QObject *> allObjects;
1145 collectAllObjects(rootNode, allObjects);
1146 for (
const SignalHook &signalHook : std::as_const(signalHooks))
1147 allObjects.insert(signalHook.obj);
1150 for (QObject *obj : std::as_const(allObjects))
1151 obj->disconnect(
this);
1154void QDBusConnectionPrivate::handleDBusDisconnection()
1156 while (!pendingCalls.isEmpty())
1157 processFinishedCall(pendingCalls.first());
1160void QDBusConnectionPrivate::checkThread()
1162 Q_ASSERT(thread() == QDBusConnectionManager::instance());
1163 Q_ASSERT(QThread::currentThread() == thread());
1166bool QDBusConnectionPrivate::handleError(
const QDBusErrorInternal &error)
1177void QDBusConnectionPrivate::timerEvent(QTimerEvent *e)
1180 DBusTimeout *timeout = timeouts.value(e->timerId(),
nullptr);
1182 q_dbus_timeout_handle(timeout);
1188void QDBusConnectionPrivate::doDispatch()
1190 if (mode == ClientMode || mode == PeerMode) {
1191 if (dispatchEnabled && !pendingMessages.isEmpty()) {
1193 for (QDBusMessage &message : pendingMessages) {
1194 qDBusDebug() <<
this <<
"dequeueing message" << message;
1195 handleMessage(std::move(message));
1197 pendingMessages.clear();
1199 while (q_dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS) ;
1203void QDBusConnectionPrivate::socketRead(qintptr fd)
1205 WatcherHash::ConstIterator it = watchers.constFind(fd);
1206 while (it != watchers.constEnd() && it.key() == fd) {
1207 if (it->watch && it->read && it->read->isEnabled()) {
1208 if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_READABLE))
1209 qDebug(
"OUT OF MEM");
1214 if ((mode == ClientMode || mode == PeerMode) && !isAuthenticated
1215 && q_dbus_connection_get_is_authenticated(connection))
1216 handleAuthentication();
1220void QDBusConnectionPrivate::socketWrite(qintptr fd)
1222 WatcherHash::ConstIterator it = watchers.constFind(fd);
1223 while (it != watchers.constEnd() && it.key() == fd) {
1224 if (it->watch && it->write && it->write->isEnabled()) {
1225 if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_WRITABLE))
1226 qDebug(
"OUT OF MEM");
1231 if ((mode == ClientMode || mode == PeerMode) && !isAuthenticated
1232 && q_dbus_connection_get_is_authenticated(connection))
1233 handleAuthentication();
1236void QDBusConnectionPrivate::objectDestroyed(QObject *obj)
1238 QDBusWriteLocker locker(ObjectDestroyedAction,
this);
1239 huntAndDestroy(obj, rootNode);
1241 SignalHookHash::iterator sit = signalHooks.begin();
1242 while (sit != signalHooks.end()) {
1243 if (
static_cast<QObject *>(sit.value().obj) == obj)
1244 sit = removeSignalHookNoLock(sit);
1249 obj->disconnect(
this);
1252void QDBusConnectionPrivate::relaySignal(QObject *obj,
const QMetaObject *mo,
int signalId,
1253 const QVariantList &args)
1255 QString interface = qDBusInterfaceFromMetaObject(mo);
1257 QMetaMethod mm = mo->method(signalId);
1258 QByteArray memberName = mm.name();
1261 bool isScriptable = mm.attributes() & QMetaMethod::Scriptable;
1262 bool isAdaptor =
false;
1263 for ( ; mo; mo = mo->superClass())
1264 if (mo == &QDBusAbstractAdaptor::staticMetaObject) {
1270 QDBusReadLocker locker(RelaySignalAction,
this);
1271 QDBusMessage message = QDBusMessage::createSignal(
"/"_L1, interface,
1272 QLatin1StringView(memberName));
1273 QDBusMessagePrivate::setParametersValidated(message,
true);
1274 message.setArguments(args);
1277 QDBusMessagePrivate::toDBusMessage(message, connectionCapabilities(), &error);
1279 qCWarning(dbusIntegration,
"QDBusConnection: Could not emit signal %s.%s: %s",
1287 q_dbus_message_set_no_reply(msg,
true);
1288 huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor);
1289 q_dbus_message_unref(msg);
1292void QDBusConnectionPrivate::serviceOwnerChangedNoLock(
const QString &name,
1293 const QString &oldOwner,
const QString &newOwner)
1296 WatchedServicesHash::Iterator it = watchedServices.find(name);
1297 if (it == watchedServices.end())
1299 if (oldOwner != it->owner)
1301 "QDBusConnection: name '%s' had owner '%s' but we thought it was '%s'",
1304 qDBusDebug() <<
this <<
"Updating name" << name <<
"from" << oldOwner <<
"to" << newOwner;
1305 it->owner = newOwner;
1308int QDBusConnectionPrivate::findSlot(QObject *obj,
const QByteArray &normalizedName,
1309 QList<QMetaType> ¶ms, QString &errorMsg)
1312 int midx = obj->metaObject()->indexOfMethod(normalizedName);
1316 int inputCount = qDBusParametersForMethod(obj->metaObject()->method(midx), params, errorMsg);
1317 if (inputCount == -1 || inputCount + 1 != params.size())
1323bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
1324 const QString &service,
const QString &path,
1325 const QString &interface,
const QString &name,
1326 const ArgMatchRules &argMatch, QObject *receiver,
1327 const char *signal,
int minMIdx,
bool buildSignature,
1330 QByteArray normalizedName = signal + 1;
1331 hook.midx = findSlot(receiver, signal + 1, hook.params, errorMsg);
1332 if (hook.midx == -1) {
1333 normalizedName = QMetaObject::normalizedSignature(signal + 1);
1334 hook.midx = findSlot(receiver, normalizedName, hook.params, errorMsg);
1336 if (hook.midx < minMIdx) {
1340 hook.service = service;
1342 hook.obj = receiver;
1343 hook.argumentMatch = argMatch;
1348 QString mname = name;
1349 if (buildSignature && mname.isNull()) {
1350 normalizedName.truncate(normalizedName.indexOf(
'('));
1351 mname = QString::fromUtf8(normalizedName);
1354 key.reserve(interface.size() + 1 + mname.size());
1358 if (buildSignature) {
1359 hook.signature.clear();
1360 for (
int i = 1; i < hook.params.size(); ++i)
1361 if (hook.params.at(i) != QDBusMetaTypeId::message())
1362 hook.signature += QLatin1StringView(QDBusMetaType::typeToSignature(hook.params.at(i)));
1365 hook.matchRule = buildMatchRule(service, path, interface, mname, argMatch, hook.signature);
1369void QDBusConnectionPrivate::sendError(
const QDBusMessage &msg, QDBusError::ErrorType code)
1371 if (code == QDBusError::UnknownMethod) {
1372 QString interfaceMsg;
1373 if (msg.interface().isEmpty())
1374 interfaceMsg =
"any interface"_L1;
1376 interfaceMsg =
"interface '%1'"_L1.arg(msg.interface());
1378 send(msg.createErrorReply(code,
"No such method '%1' in %2 at object path '%3' "
1379 "(signature '%4')"_L1
1380 .arg(msg.member(), interfaceMsg, msg.path(), msg.signature())));
1381 }
else if (code == QDBusError::UnknownInterface) {
1382 send(msg.createErrorReply(QDBusError::UnknownInterface,
1383 "No such interface '%1' at object path '%2'"_L1
1384 .arg(msg.interface(), msg.path())));
1385 }
else if (code == QDBusError::UnknownObject) {
1386 send(msg.createErrorReply(QDBusError::UnknownObject,
1387 "No such object path '%1'"_L1.arg(msg.path())));
1391bool QDBusConnectionPrivate::activateInternalFilters(
const ObjectTreeNode &node,
1392 const QDBusMessage &msg)
1395 const QString interface = msg.interface();
1397 if (interface.isEmpty() || interface == QDBusUtil::dbusInterfaceIntrospectable()) {
1398 if (msg.member() ==
"Introspect"_L1 && msg.signature().isEmpty()) {
1400 QDBusMessage reply = msg.createReply(qDBusIntrospectObject(node, msg.path()));
1405 if (!interface.isEmpty()) {
1406 sendError(msg, QDBusError::UnknownMethod);
1411 if (node.obj && (interface.isEmpty() ||
1412 interface == QDBusUtil::dbusInterfaceProperties())) {
1414 if (msg.member() ==
"Get"_L1 && msg.signature() ==
"ss"_L1) {
1415 QDBusMessage reply = qDBusPropertyGet(node, msg);
1418 }
else if (msg.member() ==
"Set"_L1 && msg.signature() ==
"ssv"_L1) {
1419 QDBusMessage reply = qDBusPropertySet(node, msg);
1422 }
else if (msg.member() ==
"GetAll"_L1 && msg.signature() ==
"s"_L1) {
1423 QDBusMessage reply = qDBusPropertyGetAll(node, msg);
1428 if (!interface.isEmpty()) {
1429 sendError(msg, QDBusError::UnknownMethod);
1437void QDBusConnectionPrivate::activateObject(ObjectTreeNode &node,
const QDBusMessage &msg,
1447 if (node.flags & QDBusConnectionPrivate::VirtualObject) {
1448 if (node.treeNode->handleMessage(msg, q(
this))) {
1451 if (activateInternalFilters(node, msg))
1456 if (pathStartPos != msg.path().size()) {
1457 node.flags &= ~QDBusConnection::ExportAllSignals;
1458 node.obj = findChildObject(&node, msg.path(), pathStartPos);
1460 sendError(msg, QDBusError::UnknownObject);
1465 QDBusAdaptorConnector *connector;
1466 if (node.flags & QDBusConnection::ExportAdaptors &&
1467 (connector = qDBusFindAdaptorConnector(node.obj))) {
1468 auto newflags = node.flags | QDBusConnection::ExportAllSlots;
1470 if (msg.interface().isEmpty()) {
1473 for (
const QDBusAdaptorConnector::AdaptorData &adaptorData :
1474 std::as_const(connector->adaptors)) {
1475 if (activateCall(adaptorData.adaptor, newflags, msg))
1480 QDBusAdaptorConnector::AdaptorMap::ConstIterator it;
1481 it = std::lower_bound(connector->adaptors.constBegin(), connector->adaptors.constEnd(),
1483 if (it != connector->adaptors.constEnd() && msg.interface() == QLatin1StringView(it->interface)) {
1484 if (!activateCall(it->adaptor, newflags, msg))
1485 sendError(msg, QDBusError::UnknownMethod);
1493 if (activateInternalFilters(node, msg))
1497 if (node.flags & (QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportNonScriptableSlots) ||
1498 node.flags & (QDBusConnection::ExportScriptableInvokables|QDBusConnection::ExportNonScriptableInvokables)) {
1499 bool interfaceFound =
true;
1500 if (!msg.interface().isEmpty()) {
1501 if (!node.interfaceName.isEmpty())
1502 interfaceFound = msg.interface() == node.interfaceName;
1504 interfaceFound = qDBusInterfaceInObject(node.obj, msg.interface());
1507 if (interfaceFound) {
1508 if (!activateCall(node.obj, node.flags, msg))
1509 sendError(msg, QDBusError::UnknownMethod);
1515 if (msg.interface().isEmpty())
1516 sendError(msg, QDBusError::UnknownMethod);
1518 sendError(msg, QDBusError::UnknownInterface);
1521void QDBusConnectionPrivate::handleObjectCall(
const QDBusMessage &msg)
1530 ObjectTreeNode result;
1532 QThread *objThread =
nullptr;
1537 QDBusReadLocker locker(HandleObjectCallAction,
this);
1538 if (!findObject(&rootNode, msg.path(), usedLength, result)) {
1540 sendError(msg, QDBusError::UnknownObject);
1547 activateObject(result, msg, usedLength);
1551 objThread = result.obj->thread();
1553 send(msg.createErrorReply(QDBusError::InternalError,
1554 "Object '%1' (at path '%2')"
1555 " has no thread. Cannot deliver message."_L1
1556 .arg(result.obj->objectName(), msg.path())));
1560 if (!QDBusMessagePrivate::isLocal(msg)) {
1563 postEventToThread(HandleObjectCallPostEventAction, result.obj,
1564 new QDBusActivateObjectEvent(QDBusConnection(
this),
this, result,
1567 }
else if (objThread != QThread::currentThread()) {
1570 postEventToThread(HandleObjectCallPostEventAction, result.obj,
1571 new QDBusActivateObjectEvent(QDBusConnection(
this),
this, result,
1572 usedLength, msg, &sem));
1581 SEM_ACQUIRE(HandleObjectCallSemaphoreAction, sem);
1583 activateObject(result, msg, usedLength);
1591 QDBusConnectionPrivate *that = QDBusConnectionPrivate::d(connection);
1592 that->sendError(message, QDBusError::UnknownObject);
1600 QDBusConnectionPrivate *that = QDBusConnectionPrivate::d(connection);
1604 that->activateObject(node, message, pathStartPos);
1611void QDBusConnectionPrivate::handleSignal(
const QString &key,
const QDBusMessage& msg)
1613 SignalHookHash::const_iterator it = signalHooks.constFind(key);
1614 SignalHookHash::const_iterator end = signalHooks.constEnd();
1617 for ( ; it != end && it.key() == key; ++it) {
1618 const SignalHook &hook = it.value();
1619 if (!hook.service.isEmpty()) {
1620 QString owner = watchedServices.value(hook.service, WatchedServiceData(hook.service)).owner;
1621 if (owner != msg.service())
1624 if (!hook.path.isEmpty() && hook.path != msg.path())
1626 if (!hook.signature.isEmpty() && hook.signature != msg.signature())
1628 if (hook.signature.isEmpty() && !hook.signature.isNull() && !msg.signature().isEmpty())
1630 if (!hook.argumentMatch.args.isEmpty()) {
1631 const QVariantList arguments = msg.arguments();
1632 if (hook.argumentMatch.args.size() > arguments.size())
1635 bool matched =
true;
1636 for (
int i = 0; i < hook.argumentMatch.args.size(); ++i) {
1637 const QString ¶m = hook.argumentMatch.args.at(i);
1640 if (param == arguments.at(i).toString())
1648 if (!hook.argumentMatch.arg0namespace.isEmpty()) {
1649 const QVariantList arguments = msg.arguments();
1650 if (arguments.size() < 1)
1652 const QString param = arguments.at(0).toString();
1653 const QStringView ns = hook.argumentMatch.arg0namespace;
1654 if (!param.startsWith(ns) || (param.size() != ns.size() && param[ns.size()] != u'.'))
1657 activateSignal(hook, msg);
1661void QDBusConnectionPrivate::handleSignal(
const QDBusMessage& msg)
1670 QString key = msg.member();
1671 key.reserve(key.size() + 1 + msg.interface().size());
1673 key += msg.interface();
1675 QDBusWriteLocker locker(HandleSignalAction,
this);
1676 handleSignal(key, msg);
1678 key.truncate(msg.member().size() + 1);
1679 handleSignal(key, msg);
1682 key += msg.interface();
1683 handleSignal(key, msg);
1686void QDBusConnectionPrivate::watchForDBusDisconnection()
1690 hook.service.clear();
1691 hook.path = QDBusUtil::dbusPathLocal();
1693 hook.params << QMetaType(QMetaType::Void);
1694 hook.midx = staticMetaObject.indexOfSlot(
"handleDBusDisconnection()");
1695 Q_ASSERT(hook.midx != -1);
1699void QDBusConnectionPrivate::setServer(QDBusServer *object, DBusServer *s,
const QDBusErrorInternal &error)
1702 serverObject = object;
1711 dbus_bool_t data_allocated = q_dbus_server_allocate_data_slot(&server_slot);
1712 if (data_allocated && server_slot < 0)
1715 dbus_bool_t watch_functions_set = q_dbus_server_set_watch_functions(server,
1721 Q_UNUSED(watch_functions_set);
1723 dbus_bool_t time_functions_set = q_dbus_server_set_timeout_functions(server,
1729 Q_UNUSED(time_functions_set);
1731 q_dbus_server_set_new_connection_function(server, qDBusNewConnection,
this,
nullptr);
1733 dbus_bool_t data_set = q_dbus_server_set_data(server, server_slot,
this,
nullptr);
1738void QDBusConnectionPrivate::setPeer(DBusConnection *c,
const QDBusErrorInternal &error)
1748 q_dbus_connection_set_exit_on_disconnect(connection,
false);
1749 q_dbus_connection_set_watch_functions(connection,
1754 q_dbus_connection_set_timeout_functions(connection,
1759 q_dbus_connection_set_dispatch_status_function(connection, qDBusUpdateDispatchStatus,
this,
nullptr);
1760 q_dbus_connection_add_filter(connection,
1764 watchForDBusDisconnection();
1766 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::doDispatch, Qt::QueuedConnection);
1771 QDBusConnection::ConnectionCapabilities result;
1772 typedef dbus_bool_t (*can_send_type_t)(DBusConnection *,
int);
1773 static can_send_type_t can_send_type =
nullptr;
1775#if defined(QT_LINKED_LIBDBUS)
1776# if DBUS_VERSION-0
>= 0x010400
1777 can_send_type = dbus_connection_can_send_type;
1779#elif QT_CONFIG(library)
1781 can_send_type = (can_send_type_t)qdbus_resolve_conditionally(
"dbus_connection_can_send_type");
1785# define DBUS_TYPE_UNIX_FD int('h')
1788 result |= QDBusConnection::UnixFileDescriptorPassing;
1793void QDBusConnectionPrivate::handleAuthentication()
1795 capabilities.storeRelaxed(::connectionCapabilities(connection));
1796 isAuthenticated =
true;
1799void QDBusConnectionPrivate::setConnection(DBusConnection *dbc,
const QDBusErrorInternal &error)
1809 const char *service = q_dbus_bus_get_unique_name(connection);
1811 baseService = QString::fromUtf8(service);
1813 handleAuthentication();
1815 q_dbus_connection_set_exit_on_disconnect(connection,
false);
1816 q_dbus_connection_set_watch_functions(connection, qDBusAddWatch, qDBusRemoveWatch,
1817 qDBusToggleWatch,
this,
nullptr);
1818 q_dbus_connection_set_timeout_functions(connection, qDBusAddTimeout, qDBusRemoveTimeout,
1819 qDBusToggleTimeout,
this,
nullptr);
1820 q_dbus_connection_set_dispatch_status_function(connection, qDBusUpdateDispatchStatus,
this,
nullptr);
1821 q_dbus_connection_add_filter(connection, qDBusSignalFilter,
this,
nullptr);
1827 hook.service = QDBusUtil::dbusService();
1830 hook.params << QMetaType(QMetaType::Void) << QMetaType(QMetaType::QString);
1832 hook.midx = staticMetaObject.indexOfSlot(
"registerServiceNoLock(QString)");
1833 Q_ASSERT(hook.midx != -1);
1836 hook.midx = staticMetaObject.indexOfSlot(
"unregisterServiceNoLock(QString)");
1837 Q_ASSERT(hook.midx != -1);
1842 hook.params.clear();
1843 hook.params.reserve(4);
1844 hook.params << QMetaType(QMetaType::Void) << QMetaType(QMetaType::QString) << QMetaType(QMetaType::QString) << QMetaType(QMetaType::QString);
1845 hook.midx = staticMetaObject.indexOfSlot(
"serviceOwnerChangedNoLock(QString,QString,QString)");
1846 Q_ASSERT(hook.midx != -1);
1849 watchForDBusDisconnection();
1851 qDBusDebug() <<
this <<
": connected successfully";
1854 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::doDispatch, Qt::QueuedConnection);
1862 QDBusConnectionPrivate::processFinishedCall(call);
1866void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
1868 QDBusConnectionPrivate *connection =
const_cast<QDBusConnectionPrivate *>(call->connection);
1870 auto locker = qt_unique_lock(call->mutex);
1872 connection->pendingCalls.removeOne(call);
1874 QDBusMessage &msg = call->replyMessage;
1875 if (call->pending) {
1878 if (q_dbus_pending_call_get_completed(call->pending)) {
1880 DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
1881 msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->connectionCapabilities());
1882 q_dbus_message_unref(reply);
1884 msg = QDBusMessage::createError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
1887 qDBusDebug() << connection <<
"got message reply:" << msg;
1890 call->checkReceivedSignature();
1892 if (!call->receiver.isNull() && call->methodIdx != -1 && msg.type() == QDBusMessage::ReplyMessage) {
1901 QDBusCallDeliveryEvent *e = prepareReply(connection, call->receiver, call->methodIdx,
1902 call->metaTypes, msg);
1904 connection->postEventToThread(MessageResultReceivedAction, call->receiver, e);
1909 if (call->pending) {
1910 q_dbus_pending_call_unref(call->pending);
1911 call->pending =
nullptr;
1915 if (call->watcherHelper)
1916 call->watcherHelper->emitSignals(msg, call->sentMessage);
1918 call->waitForFinishedCondition.wakeAll();
1921 if (msg.type() == QDBusMessage::ErrorMessage)
1922 emit connection->callWithCallbackFailed(QDBusError(msg), call->sentMessage);
1924 if (!call->ref.deref())
1928bool QDBusConnectionPrivate::send(
const QDBusMessage& message)
1930 if (QDBusMessagePrivate::isLocal(message))
1936 QDBusMessagePrivate::toDBusMessage(message, connectionCapabilities(), &error);
1938 if (message.type() == QDBusMessage::MethodCallMessage)
1940 "QDBusConnection: error: could not send message to service \"%s\" path "
1941 "\"%s\" interface \"%s\" member \"%s\": %s",
1945 else if (message.type() == QDBusMessage::SignalMessage)
1947 "QDBusConnection: error: could not send signal to service \"%s\" path \"%s\" "
1948 "interface \"%s\" member \"%s\": %s",
1954 "QDBusConnection: error: could not send %s message to service \"%s\": %s",
1955 message.type() == QDBusMessage::ReplyMessage ?
"reply"
1956 : message.type() == QDBusMessage::ErrorMessage ?
"error"
1963 q_dbus_message_set_no_reply(msg,
true);
1964 qDBusDebug() <<
this <<
"sending message (no reply):" << message;
1965 emit messageNeedsSending(
nullptr, msg);
1981#if defined(QT_NO_DEBUG)
1999 env =
qgetenv(
"Q_DBUS_BLOCKING_CALL_MAIN_THREAD_WARNING_MS");
2007 "QDBusBlockingCallWatcher: Q_DBUS_BLOCKING_CALL_MAIN_THREAD_WARNING_MS "
2008 "must be an integer; value ignored");
2011 env =
qgetenv(
"Q_DBUS_BLOCKING_CALL_OTHER_THREAD_WARNING_MS");
2018 "QDBusBlockingCallWatcher: "
2019 "Q_DBUS_BLOCKING_CALL_OTHER_THREAD_WARNING_MS must be an integer; "
2041 if (m_maxCallTimeoutMs < 0)
2044 if (m_callTimer.elapsed() >= m_maxCallTimeoutMs) {
2047 "QDBusConnection: warning: blocking call took a long time (%d ms, max for this "
2048 "thread is %d ms) to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"",
2049 int(m_callTimer.elapsed()), m_maxCallTimeoutMs,
qPrintable(m_message.service()),
2056 QDBusMessage m_message;
2057 int m_maxCallTimeoutMs;
2058 QElapsedTimer m_callTimer;
2061QDBusMessage QDBusConnectionPrivate::sendWithReply(
const QDBusMessage &message,
2062 QDBus::CallMode mode,
int timeout)
2064 QDBusBlockingCallWatcher watcher(message);
2066 QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message,
nullptr,
nullptr,
nullptr, timeout);
2069 if (mode == QDBus::BlockWithGui)
2070 pcall->waitForFinishedWithGui();
2072 pcall->waitForFinished();
2074 QDBusMessage reply = pcall->replyMessage;
2075 lastError = QDBusError(reply);
2077 if (!pcall->ref.deref())
2082QDBusMessage QDBusConnectionPrivate::sendWithReplyLocal(
const QDBusMessage &message)
2084 qDBusDebug() <<
this <<
"sending message via local-loop:" << message;
2086 QDBusMessage localCallMsg = QDBusMessagePrivate::makeLocal(*
this, message);
2087 bool handled = handleMessage(localCallMsg);
2090 QString interface = message.interface();
2091 if (interface.isEmpty())
2092 interface =
"<no-interface>"_L1;
2093 return QDBusMessage::createError(QDBusError::InternalError,
2094 "Internal error trying to call %1.%2 at %3 (signature '%4'"_L1
2095 .arg(interface, message.member(),
2096 message.path(), message.signature()));
2100 QDBusMessage localReplyMsg = QDBusMessagePrivate::makeLocalReply(*
this, localCallMsg);
2101 if (localReplyMsg.type() == QDBusMessage::InvalidMessage) {
2104 "QDBusConnection: cannot call local method '%s' at object %s (with signature '%s') "
2108 return QDBusMessage::createError(
2109 QDBusError(QDBusError::InternalError,
2110 "local-loop message cannot have delayed replies"_L1));
2114 qDBusDebug() <<
this <<
"got message via local-loop:" << localReplyMsg;
2115 return localReplyMsg;
2118QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(
const QDBusMessage &message,
2119 QObject *receiver,
const char *returnMethod,
2120 const char *errorMethod,
int timeout)
2122 QDBusPendingCallPrivate *pcall =
new QDBusPendingCallPrivate(message,
this);
2124 if ((isLoopback = isServiceRegisteredByThread(message.service()))) {
2126 pcall->replyMessage = sendWithReplyLocal(message);
2129 if (receiver && returnMethod)
2130 pcall->setReplyCallback(receiver, returnMethod);
2133 Q_ASSERT(!pcall->watcherHelper);
2134 pcall->watcherHelper =
new QDBusPendingCallWatcherHelper;
2135 connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), receiver, errorMethod,
2136 Qt::QueuedConnection);
2137 pcall->watcherHelper->moveToThread(thread());
2140 if ((receiver && returnMethod) || errorMethod) {
2142 pcall->ref.storeRelaxed(1);
2146 pcall->ref.storeRelaxed(2);
2151 processFinishedCall(pcall);
2157 QDBusMessagePrivate::toDBusMessage(message, connectionCapabilities(), &error);
2160 "QDBusConnection: error: could not send message to service \"%s\" path \"%s\" "
2161 "interface \"%s\" member \"%s\": %s",
2165 pcall->replyMessage = QDBusMessage::createError(error);
2167 processFinishedCall(pcall);
2169 qDBusDebug() <<
this <<
"sending message:" << message;
2170 emit messageNeedsSending(pcall, msg, timeout);
2175void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall,
void *message,
int timeout)
2178 DBusPendingCall *pending =
nullptr;
2179 DBusMessage *msg =
static_cast<DBusMessage *>(message);
2180 bool isNoReply = !pcall;
2181 Q_ASSERT(isNoReply == !!q_dbus_message_get_no_reply(msg));
2185 if (isNoReply && q_dbus_connection_send(connection, msg,
nullptr)) {
2187 }
else if (!isNoReply && q_dbus_connection_send_with_reply(connection, msg, &pending, timeout)) {
2189 q_dbus_message_unref(msg);
2191 pcall->pending = pending;
2192 q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall,
nullptr);
2195 if (mode == QDBusConnectionPrivate::PeerMode || mode == QDBusConnectionPrivate::ClientMode)
2196 pendingCalls.append(pcall);
2201 lastError = error = QDBusError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
2204 lastError = error = QDBusError(QDBusError::NoMemory, QStringLiteral(
"Out of memory"));
2207 q_dbus_message_unref(msg);
2209 pcall->replyMessage = QDBusMessage::createError(error);
2210 processFinishedCall(pcall);
2215bool QDBusConnectionPrivate::connectSignal(
const QString &service,
2216 const QString &path,
const QString &interface,
const QString &name,
2217 const QStringList &argumentMatch,
const QString &signature,
2218 QObject *receiver,
const char *slot)
2220 ArgMatchRules rules;
2221 rules.args = argumentMatch;
2222 return connectSignal(service, path, interface, name, rules, signature, receiver, slot);
2225bool QDBusConnectionPrivate::connectSignal(
const QString &service,
2226 const QString &path,
const QString &interface,
const QString &name,
2227 const ArgMatchRules &argumentMatch,
const QString &signature,
2228 QObject *receiver,
const char *slot)
2231 QDBusConnectionPrivate::SignalHook hook;
2234 hook.signature = signature;
2236 if (!prepareHook(hook, key, service, path, interface, name, argumentMatch, receiver, slot, 0,
2239 <<
"Could not connect" << interface <<
"to" << slot + 1 <<
":" <<
qPrintable(errorMsg);
2243 Q_ASSERT(thread() != QThread::currentThread());
2244 return addSignalHook(key, hook);
2247bool QDBusConnectionPrivate::addSignalHook(
const QString &key,
const SignalHook &hook)
2249 bool result =
false;
2251 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::addSignalHookImpl,
2252 Qt::BlockingQueuedConnection, qReturnArg(result), key, hook);
2257bool QDBusConnectionPrivate::addSignalHookImpl(
const QString &key,
const SignalHook &hook)
2259 QDBusWriteLocker locker(ConnectAction,
this);
2262 QDBusConnectionPrivate::SignalHookHash::ConstIterator it = signalHooks.constFind(key);
2263 QDBusConnectionPrivate::SignalHookHash::ConstIterator end = signalHooks.constEnd();
2264 for ( ; it != end && it.key() == key; ++it) {
2265 const QDBusConnectionPrivate::SignalHook &entry = it.value();
2266 if (entry.service == hook.service &&
2267 entry.path == hook.path &&
2268 entry.signature == hook.signature &&
2269 entry.obj == hook.obj &&
2270 entry.midx == hook.midx &&
2271 entry.argumentMatch == hook.argumentMatch) {
2277 signalHooks.insert(key, hook);
2278 connect(hook.obj, &QObject::destroyed,
this, &QDBusConnectionPrivate::objectDestroyed,
2279 Qt::ConnectionType(Qt::BlockingQueuedConnection | Qt::UniqueConnection));
2281 MatchRefCountHash::iterator mit = matchRefCounts.find(hook.matchRule);
2283 if (mit != matchRefCounts.end()) {
2284 mit.value() = mit.value() + 1;
2288 matchRefCounts.insert(hook.matchRule, 1);
2291 if (mode != QDBusConnectionPrivate::PeerMode) {
2292 qDBusDebug() <<
this <<
"Adding rule:" << hook.matchRule;
2293 q_dbus_bus_add_match(connection, hook.matchRule,
nullptr);
2297 if (shouldWatchService(hook.service)) {
2298 WatchedServicesHash::mapped_type &data = watchedServices[hook.service];
2299 if (++data.refcount == 1) {
2301 ArgMatchRules rules;
2302 rules.args << hook.service;
2303 q_dbus_bus_add_match(connection,
2304 buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(),
2305 QDBusUtil::nameOwnerChanged(), rules, QString()),
2307 data.owner = getNameOwnerNoCache(hook.service);
2308 qDBusDebug() <<
this <<
"Watching service" << hook.service <<
"for owner changes (current owner:"
2309 << data.owner <<
")";
2317bool QDBusConnectionPrivate::disconnectSignal(
const QString &service,
2318 const QString &path,
const QString &interface,
const QString &name,
2319 const QStringList &argumentMatch,
const QString &signature,
2320 QObject *receiver,
const char *slot)
2322 ArgMatchRules rules;
2323 rules.args = argumentMatch;
2324 return disconnectSignal(service, path, interface, name, rules, signature, receiver, slot);
2327bool QDBusConnectionPrivate::disconnectSignal(
const QString &service,
2328 const QString &path,
const QString &interface,
const QString &name,
2329 const ArgMatchRules &argumentMatch,
const QString &signature,
2330 QObject *receiver,
const char *slot)
2333 QDBusConnectionPrivate::SignalHook hook;
2335 QString name2 = name;
2339 hook.signature = signature;
2341 if (!prepareHook(hook, key, service, path, interface, name, argumentMatch, receiver, slot, 0,
2344 <<
"Could not disconnect" << interface <<
"to" << slot + 1 <<
":" <<
qPrintable(errorMsg);
2348 Q_ASSERT(thread() != QThread::currentThread());
2349 return removeSignalHook(key, hook);
2352bool QDBusConnectionPrivate::removeSignalHook(
const QString &key,
const SignalHook &hook)
2354 bool result =
false;
2356 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::removeSignalHookImpl,
2357 Qt::BlockingQueuedConnection, qReturnArg(result), key, hook);
2362bool QDBusConnectionPrivate::removeSignalHookImpl(
const QString &key,
const SignalHook &hook)
2365 QDBusWriteLocker locker(ConnectAction,
this);
2366 QDBusConnectionPrivate::SignalHookHash::Iterator it = signalHooks.find(key);
2367 QDBusConnectionPrivate::SignalHookHash::Iterator end = signalHooks.end();
2368 for ( ; it != end && it.key() == key; ++it) {
2369 const QDBusConnectionPrivate::SignalHook &entry = it.value();
2370 if (entry.service == hook.service &&
2371 entry.path == hook.path &&
2372 entry.signature == hook.signature &&
2373 entry.obj == hook.obj &&
2374 entry.midx == hook.midx &&
2375 entry.argumentMatch.args == hook.argumentMatch.args) {
2377 removeSignalHookNoLock(it);
2386QDBusConnectionPrivate::SignalHookHash::Iterator
2387QDBusConnectionPrivate::removeSignalHookNoLock(SignalHookHash::Iterator it)
2389 const SignalHook &hook = it.value();
2392 MatchRefCountHash::iterator i = matchRefCounts.find(hook.matchRule);
2393 if (i == matchRefCounts.end()) {
2395 "QDBusConnectionPrivate::disconnectSignal: MatchRule not found in "
2396 "matchRefCounts!!");
2398 if (i.value() == 1) {
2400 matchRefCounts.erase(i);
2403 i.value() = i.value() - 1;
2408 if (connection && erase) {
2409 if (mode != QDBusConnectionPrivate::PeerMode) {
2410 qDBusDebug() <<
this <<
"Removing rule:" << hook.matchRule;
2411 q_dbus_bus_remove_match(connection, hook.matchRule,
nullptr);
2415 WatchedServicesHash::Iterator sit = watchedServices.find(hook.service);
2416 if (sit != watchedServices.end()) {
2417 if (--sit.value().refcount == 0) {
2418 watchedServices.erase(sit);
2419 ArgMatchRules rules;
2420 rules.args << hook.service;
2421 q_dbus_bus_remove_match(connection,
2422 buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(),
2423 QDBusUtil::nameOwnerChanged(), rules, QString()),
2431 return signalHooks.erase(it);
2434void QDBusConnectionPrivate::registerObject(
const ObjectTreeNode *node)
2436 connect(node->obj, &QObject::destroyed,
this, &QDBusConnectionPrivate::objectDestroyed,
2437 Qt::ConnectionType(Qt::BlockingQueuedConnection | Qt::UniqueConnection));
2439 if (node->flags & (QDBusConnection::ExportAdaptors
2440 | QDBusConnection::ExportScriptableSignals
2441 | QDBusConnection::ExportNonScriptableSignals)) {
2442 QDBusAdaptorConnector *connector = qDBusCreateAdaptorConnector(node->obj);
2444 if (node->flags & (QDBusConnection::ExportScriptableSignals
2445 | QDBusConnection::ExportNonScriptableSignals)) {
2446 connector->disconnectAllSignals(node->obj);
2447 connector->connectAllSignals(node->obj);
2450 connect(connector, &QDBusAdaptorConnector::relaySignal,
this,
2451 &QDBusConnectionPrivate::relaySignal,
2452 Qt::ConnectionType(Qt::QueuedConnection | Qt::UniqueConnection));
2456void QDBusConnectionPrivate::unregisterObject(
const QString &path, QDBusConnection::UnregisterMode mode)
2458 QDBusConnectionPrivate::ObjectTreeNode *node = &rootNode;
2459 QList<QStringView> pathComponents;
2461 if (path ==
"/"_L1) {
2464 pathComponents = QStringView{path}.split(u'/');
2468 huntAndUnregister(pathComponents, i, mode, node);
2471void QDBusConnectionPrivate::connectRelay(
const QString &service,
2472 const QString &path,
const QString &interface,
2473 QDBusAbstractInterface *receiver,
2474 const QMetaMethod &signal)
2482 sig.append(QSIGNAL_CODE +
'0');
2483 sig.append(signal.methodSignature());
2485 if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig,
2486 QDBusAbstractInterface::staticMetaObject.methodCount(),
true, errorMsg)) {
2488 <<
"Could not connect" << interface <<
"to" << signal.name() <<
":" <<
qPrintable(errorMsg);
2492 Q_ASSERT(thread() != QThread::currentThread());
2493 addSignalHook(key, hook);
2496void QDBusConnectionPrivate::disconnectRelay(
const QString &service,
2497 const QString &path,
const QString &interface,
2498 QDBusAbstractInterface *receiver,
2499 const QMetaMethod &signal)
2507 sig.append(QSIGNAL_CODE +
'0');
2508 sig.append(signal.methodSignature());
2510 if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig,
2511 QDBusAbstractInterface::staticMetaObject.methodCount(),
true, errorMsg)) {
2512 qCWarning(dbusIntegration) <<
"Could not disconnect" << interface <<
"to"
2513 << signal.methodSignature() <<
":" <<
qPrintable(errorMsg);
2517 Q_ASSERT(thread() != QThread::currentThread());
2518 removeSignalHook(key, hook);
2521bool QDBusConnectionPrivate::shouldWatchService(
const QString &service)
2524 if (mode != ClientMode)
2527 if (service.isEmpty())
2530 if (service == QDBusUtil::dbusService())
2536
2537
2538
2539
2540
2541
2542
2543
2544void QDBusConnectionPrivate::watchService(
const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj,
const char *member)
2546 ArgMatchRules matchArgs = matchArgsForService(service, mode);
2547 connectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(),
2548 matchArgs, QString(), obj, member);
2552
2553
2554
2555
2556
2557
2558
2559void QDBusConnectionPrivate::unwatchService(
const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj,
const char *member)
2561 ArgMatchRules matchArgs = matchArgsForService(service, mode);
2562 disconnectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(),
2563 matchArgs, QString(), obj, member);
2566QString QDBusConnectionPrivate::getNameOwner(
const QString& serviceName)
2568 if (QDBusUtil::isValidUniqueConnectionName(serviceName))
2575 QReadLocker locker(&lock);
2576 WatchedServicesHash::ConstIterator it = watchedServices.constFind(serviceName);
2577 if (it != watchedServices.constEnd())
2582 return getNameOwnerNoCache(serviceName);
2585QString QDBusConnectionPrivate::getNameOwnerNoCache(
const QString &serviceName)
2587 QDBusMessage msg = QDBusMessage::createMethodCall(QDBusUtil::dbusService(),
2588 QDBusUtil::dbusPath(), QDBusUtil::dbusInterface(),
2589 QStringLiteral(
"GetNameOwner"));
2590 QDBusMessagePrivate::setParametersValidated(msg,
true);
2593 QDBusPendingCallPrivate *pcall = sendWithReplyAsync(msg,
nullptr,
nullptr,
nullptr);
2594 if (thread() == QThread::currentThread()) {
2597 q_dbus_pending_call_block(pcall->pending);
2599 pcall->waitForFinished();
2600 msg = pcall->replyMessage;
2602 if (!pcall->ref.deref())
2605 if (msg.type() == QDBusMessage::ReplyMessage)
2606 return msg.arguments().at(0).toString();
2611QDBusConnectionPrivate::findMetaObject(
const QString &service,
const QString &path,
2612 const QString &interface, QDBusError &error)
2615 if (!interface.isEmpty()) {
2616 QDBusReadLocker locker(FindMetaObject1Action,
this);
2617 QDBusMetaObject *mo = cachedMetaObjects.value(interface,
nullptr);
2621 if (path.isEmpty()) {
2622 error = QDBusError(QDBusError::InvalidObjectPath,
"Object path cannot be empty"_L1);
2628 QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
2629 QDBusUtil::dbusInterfaceIntrospectable(),
2630 QStringLiteral(
"Introspect"));
2631 QDBusMessagePrivate::setParametersValidated(msg,
true);
2633 QDBusMessage reply = sendWithReply(msg, QDBus::Block);
2636 QDBusWriteLocker locker(FindMetaObject2Action,
this);
2637 QDBusMetaObject *mo =
nullptr;
2638 if (!interface.isEmpty())
2639 mo = cachedMetaObjects.value(interface,
nullptr);
2645 if (reply.type() == QDBusMessage::ReplyMessage) {
2646 if (reply.signature() ==
"s"_L1)
2648 xml = reply.arguments().at(0).toString();
2650 error = QDBusError(reply);
2652 if (reply.type() != QDBusMessage::ErrorMessage || error.type() != QDBusError::UnknownMethod)
2657 QDBusMetaObject *result = QDBusMetaObject::createMetaObject(interface, xml,
2658 cachedMetaObjects, error);
2663void QDBusConnectionPrivate::registerService(
const QString &serviceName)
2665 QDBusWriteLocker locker(RegisterServiceAction,
this);
2666 registerServiceNoLock(serviceName);
2669void QDBusConnectionPrivate::registerServiceNoLock(
const QString &serviceName)
2671 serviceNames.append(serviceName);
2674void QDBusConnectionPrivate::unregisterService(
const QString &serviceName)
2676 QDBusWriteLocker locker(UnregisterServiceAction,
this);
2677 unregisterServiceNoLock(serviceName);
2680void QDBusConnectionPrivate::unregisterServiceNoLock(
const QString &serviceName)
2682 serviceNames.removeAll(serviceName);
2685bool QDBusConnectionPrivate::isServiceRegisteredByThread(
const QString &serviceName)
2687 if (!serviceName.isEmpty() && serviceName == baseService)
2689 if (serviceName == QDBusUtil::dbusService())
2692 QDBusReadLocker locker(UnregisterServiceAction,
this);
2693 return serviceNames.contains(serviceName);
2696void QDBusConnectionPrivate::postEventToThread(
int action, QObject *object, QEvent *ev)
2698 QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforePost,
this);
2699 QCoreApplication::postEvent(object, ev);
2700 QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterPost,
this);
2704
2705
2706
2707
2708void QDBusConnectionPrivate::enableDispatchDelayed(QObject *context)
2711 QMetaObject::invokeMethod(
2717 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::setDispatchEnabled,
2718 Qt::QueuedConnection,
true);
2722 Qt::QueuedConnection);
~QDBusActivateObjectEvent() override
void placeMetaCall(QObject *) override
~QDBusBlockingCallWatcher()
static QDBusConnectionManager * instance()
DBusPendingCall * pending
~QDBusSpyCallEvent() override
void placeMetaCall(QObject *) override
static void invokeSpyHooks(const QDBusMessage &msg)
void(* Hook)(const QDBusMessage &)
void add(QDBusSpyCallEvent::Hook hook)
void invoke(const QDBusMessage &msg)
#define DBUS_TYPE_UNIX_FD
#define DBUS_INTERFACE_LOCAL
#define DBUS_INTERFACE_DBUS
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return dbus_watch_get_unix_fd
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return dbus_connection_send
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction dbus_timeout_get_enabled
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return dbus_message_unref
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return dbus_message_copy
static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, void *data)
static QDBusConnectionPrivate::ArgMatchRules matchArgsForService(const QString &service, QDBusServiceWatcher::WatchMode mode)
static bool findObject(const QDBusConnectionPrivate::ObjectTreeNode *root, const QString &fullpath, int &usedLength, QDBusConnectionPrivate::ObjectTreeNode &result)
static void qDBusUpdateDispatchStatus(DBusConnection *connection, DBusDispatchStatus new_status, void *data)
static void qDBusRemoveWatch(DBusWatch *watch, void *data)
static dbus_int32_t server_slot
static void qDBusResultReceived(DBusPendingCall *pending, void *user_data)
static void qDBusToggleTimeout(DBusTimeout *timeout, void *data)
static void huntAndUnregister(const QList< QStringView > &pathComponents, int i, QDBusConnection::UnregisterMode mode, QDBusConnectionPrivate::ObjectTreeNode *node)
static dbus_bool_t qDBusAddWatch(DBusWatch *watch, void *data)
static QDBusConnection::ConnectionCapabilities connectionCapabilities(DBusConnection *connection)
static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
static QObject * findChildObject(const QDBusConnectionPrivate::ObjectTreeNode *root, const QString &fullpath, int start)
Q_DBUS_EXPORT void qDBusAddSpyHook(QDBusSpyCallEvent::Hook)
static QDBusCallDeliveryEvent *const DIRECT_DELIVERY
static void huntAndEmit(DBusConnection *connection, DBusMessage *msg, QObject *needle, const QDBusConnectionPrivate::ObjectTreeNode &haystack, bool isScriptable, bool isAdaptor, const QString &path=QString())
static void qDBusRemoveTimeout(DBusTimeout *timeout, void *data)
static QByteArray buildMatchRule(const QString &service, const QString &objectPath, const QString &interface, const QString &member, const QDBusConnectionPrivate::ArgMatchRules &argMatch, const QString &)
static DBusHandlerResult qDBusSignalFilter(DBusConnection *connection, DBusMessage *message, void *data)
static void qDBusToggleWatch(DBusWatch *watch, void *data)
static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags, const QString &signature_, QList< QMetaType > &metaTypes)
static void huntAndDestroy(QObject *needle, QDBusConnectionPrivate::ObjectTreeNode &haystack)
#define SEM_ACQUIRE(action, sem)
#define qCWarning(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)
#define qPrintable(string)
#define qUtf16Printable(string)
static void reportThreadAction(int, int, QDBusConnectionPrivate *)