8#include <qcoreapplication.h>
9#include <qelapsedtimer.h>
10#include <private/qlatch_p.h>
11#include <qloggingcategory.h>
12#include <qmetaobject.h>
14#include <qsocketnotifier.h>
15#include <qstringlist.h>
17#include <private/qlocking_p.h>
18#include <QtCore/qset.h>
47using namespace Qt::StringLiterals;
49QT_IMPL_METATYPE_EXTERN(QDBusSlotCache)
56Q_CONSTINIT
static QBasicAtomicInt isDebugging = Q_BASIC_ATOMIC_INITIALIZER(-1);
57#define qDBusDebug if (::isDebugging.loadRelaxed() == 0
); else qDebug
59static inline QDebug operator<<(QDebug dbg,
const QThread *th)
61 QDebugStateSaver saver(dbg);
62 dbg.nospace() <<
"QThread(ptr=" << (
const void*)th;
63 if (th && !th->objectName().isEmpty())
64 dbg.nospace() <<
", name=" << th->objectName();
66 dbg.nospace() <<
", name=" << th->metaObject()->className();
72static inline QDebug operator<<(QDebug dbg,
const QDBusConnectionPrivate *conn)
74 QDebugStateSaver saver(dbg);
75 dbg.nospace() <<
"QDBusConnection("
76 <<
"ptr=" << (
const void*)conn
77 <<
", name=" << conn->name
78 <<
", baseService=" << conn->baseService
83void qdbusDefaultThreadDebug(
int action,
int condition, QDBusConnectionPrivate *conn)
85 qDBusDebug() << QThread::currentThread()
86 <<
"Qt D-Bus threading action" << action
87 << (condition == QDBusLockerBase::BeforeLock ?
"before lock" :
88 condition == QDBusLockerBase::AfterLock ?
"after lock" :
89 condition == QDBusLockerBase::BeforeUnlock ?
"before unlock" :
90 condition == QDBusLockerBase::AfterUnlock ?
"after unlock" :
91 condition == QDBusLockerBase::BeforePost ?
"before event posting" :
92 condition == QDBusLockerBase::AfterPost ?
"after event posting" :
93 condition == QDBusLockerBase::BeforeDeliver ?
"before event delivery" :
94 condition == QDBusLockerBase::AfterDeliver ?
"after event delivery" :
95 condition == QDBusLockerBase::BeforeAcquire ?
"before acquire" :
96 condition == QDBusLockerBase::AfterAcquire ?
"after acquire" :
97 condition == QDBusLockerBase::BeforeRelease ?
"before release" :
98 condition == QDBusLockerBase::AfterRelease ?
"after release" :
100 <<
"in connection" << conn;
102qdbusThreadDebugFunc qdbusThreadDebug =
nullptr;
110 const auto locker = qt_scoped_lock(lock);
120 const auto locker = qt_scoped_lock(lock);
124 for (
auto hook : std::as_const(hookListCopy))
146 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
147 Q_ASSERT(QThread::currentThread() == d->thread());
153 Q_ASSERT(d->timeouts.key(timeout, 0) == 0);
155 using namespace std::chrono_literals;
156 int timerId = d->startTimer(q_dbus_timeout_get_interval(timeout) * 1ms);
160 d->timeouts[timerId] = timeout;
171 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
172 Q_ASSERT(QThread::currentThread() == d->thread());
174 QDBusConnectionPrivate::TimeoutHash::iterator it = d->timeouts.begin();
175 while (it != d->timeouts.end()) {
176 if (it.value() == timeout) {
177 d->killTimer(it.key());
178 it = d->timeouts.erase(it);
202 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
203 Q_ASSERT(QThread::currentThread() == d->thread());
205 int flags = q_dbus_watch_get_flags(watch);
208 QDBusConnectionPrivate::Watcher watcher;
210 if (flags & DBUS_WATCH_READABLE) {
212 watcher.watch = watch;
213 watcher.read =
new QSocketNotifier(fd, QSocketNotifier::Read, d);
214 watcher.read->setEnabled(q_dbus_watch_get_enabled(watch));
215 d->connect(watcher.read, &QSocketNotifier::activated, d, &QDBusConnectionPrivate::socketRead);
217 if (flags & DBUS_WATCH_WRITABLE) {
219 watcher.watch = watch;
220 watcher.write =
new QSocketNotifier(fd, QSocketNotifier::Write, d);
221 watcher.write->setEnabled(q_dbus_watch_get_enabled(watch));
222 d->connect(watcher.write, &QSocketNotifier::activated, d, &QDBusConnectionPrivate::socketWrite);
224 d->watchers.insert(fd, watcher);
236 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
237 Q_ASSERT(QThread::currentThread() == d->thread());
240 QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
241 while (i != d->watchers.end() && i.key() == fd) {
242 if (i.value().watch == watch) {
243 delete i.value().read;
244 delete i.value().write;
245 i = d->watchers.erase(i);
257 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
258 Q_ASSERT(QThread::currentThread() == d->thread());
261 QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
262 while (i != d->watchers.end() && i.key() == fd) {
263 if (i.value().watch == watch) {
264 bool enabled = q_dbus_watch_get_enabled(watch);
265 int flags = q_dbus_watch_get_flags(watch);
269 if (flags & DBUS_WATCH_READABLE && i.value().read)
270 i.value().read->setEnabled(enabled);
271 if (flags & DBUS_WATCH_WRITABLE && i.value().write)
272 i.value().write->setEnabled(enabled);
281 Q_ASSERT(connection);
282 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
283 if (new_status == DBUS_DISPATCH_DATA_REMAINS)
284 emit d->dispatchStatusChanged();
291 Q_ASSERT(connection);
299 q_dbus_connection_ref(connection);
300 QDBusConnectionPrivate *serverConnection =
static_cast<QDBusConnectionPrivate *>(data);
303 if (serverConnection->anonymousAuthenticationAllowed)
304 q_dbus_connection_set_allow_anonymous(connection,
true);
306 QDBusConnectionPrivate *newConnection =
new QDBusConnectionPrivate;
308 manager->addConnection(
309 "QDBusServer-"_L1 + QString::number(
reinterpret_cast<qulonglong>(newConnection), 16),
312 QWriteLocker locker(&serverConnection->lock);
313 serverConnection->serverConnectionNames << newConnection->name;
318 newConnection->setPeer(connection, error);
319 newConnection->setDispatchEnabled(
false);
321 QReadLocker serverLock(&serverConnection->lock);
322 if (!serverConnection->serverObject)
326 QMetaObject::invokeMethod(serverConnection->serverObject, &QDBusServer::newConnection,
327 Qt::QueuedConnection, QDBusConnectionPrivate::q(newConnection));
334 newConnection->enableDispatchDelayed(serverConnection->serverObject);
340 const QString &objectPath,
const QString &interface,
341 const QString &member,
const QDBusConnectionPrivate::ArgMatchRules &argMatch,
const QString & )
344 result +=
"type='signal',"_L1;
345 const auto keyValue =
"%1='%2',"_L1;
347 if (!service.isEmpty())
348 result += keyValue.arg(
"sender"_L1, service);
349 if (!objectPath.isEmpty())
350 result += keyValue.arg(
"path"_L1, objectPath);
351 if (!interface.isEmpty())
352 result += keyValue.arg(
"interface"_L1, interface);
353 if (!member.isEmpty())
354 result += keyValue.arg(
"member"_L1, member);
357 if (!argMatch.args.isEmpty()) {
358 const QString keyValue =
"arg%1='%2',"_L1;
359 for (
int i = 0; i < argMatch.args.size(); ++i)
360 if (!argMatch.args.at(i).isNull())
361 result += keyValue.arg(i).arg(argMatch.args.at(i));
363 if (!argMatch.arg0namespace.isEmpty()) {
364 result +=
"arg0namespace='%1',"_L1.arg(argMatch.arg0namespace);
368 return result.toLatin1();
371static bool findObject(
const QDBusConnectionPrivate::ObjectTreeNode *root,
372 const QString &fullpath,
int &usedLength,
373 QDBusConnectionPrivate::ObjectTreeNode &result)
375 if (!fullpath.compare(
"/"_L1) && root->obj) {
381 int length = fullpath.size();
382 if (fullpath.at(0) == u'/')
386 const QDBusConnectionPrivate::ObjectTreeNode *node = root;
387 while (start < length && node) {
388 if (node->flags & QDBusConnection::ExportChildObjects)
390 if ((node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath))
392 int end = fullpath.indexOf(u'/', start);
393 end = (end == -1 ? length : end);
394 QStringView pathComponent = QStringView{fullpath}.mid(start, end - start);
396 QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator it =
397 std::lower_bound(node->children.constBegin(), node->children.constEnd(), pathComponent);
398 if (it != node->children.constEnd() && it->name == pathComponent)
408 usedLength = (start > length ? length : start);
410 if (node->obj || !node->children.isEmpty())
421 const QString &fullpath,
int start)
423 int length = fullpath.size();
426 const QDBusConnectionPrivate::ObjectTreeNode *node = root;
427 if (node && node->flags & QDBusConnection::ExportChildObjects) {
428 QObject *obj = node->obj;
435 int pos = fullpath.indexOf(u'/', start);
436 pos = (pos == -1 ? length : pos);
437 auto pathComponent = QStringView{fullpath}.mid(start, pos - start);
440 QObject *next =
nullptr;
441 for (QObject *child : std::as_const(obj->children())) {
442 if (child->objectName() == pathComponent) {
462 QDBusConnectionPrivate::ArgMatchRules matchArgs;
463 if (service.endsWith(u'*')) {
464 matchArgs.arg0namespace = service.chopped(1);
465 matchArgs.args << QString();
468 matchArgs.args << service;
471 case QDBusServiceWatcher::WatchForOwnerChange:
474 case QDBusServiceWatcher::WatchForRegistration:
475 matchArgs.args << QString::fromLatin1(
"", 0);
478 case QDBusServiceWatcher::WatchForUnregistration:
479 matchArgs.args << QString() << QString::fromLatin1(
"", 0);
489 auto *hooks = qDBusSpyHookList();
501 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(
const_cast<QObject *>(sender()));
502 qDBusDebug() << d <<
"message spies done for" << msg;
503 emit d->spyHooksFinished(msg);
513 if (!qDBusSpyHookList.exists())
516 qDBusSpyHookList->invoke(msg);
520static DBusHandlerResult
524 Q_UNUSED(connection);
525 QDBusConnectionPrivate *d =
static_cast<QDBusConnectionPrivate *>(data);
526 if (d->mode == QDBusConnectionPrivate::InvalidMode)
527 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
529 QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message, d->connectionCapabilities());
530 qDBusDebug() << d <<
"got message (signal):" << amsg;
532 return d->handleMessage(amsg) ?
533 DBUS_HANDLER_RESULT_HANDLED :
534 DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
538bool QDBusConnectionPrivate::handleMessage(
const QDBusMessage &amsg)
540 if (!ref.loadRelaxed())
545 bool isLocal = QDBusMessagePrivate::isLocal(amsg);
547 if (!dispatchEnabled && !isLocal) {
549 qDBusDebug() <<
this <<
"delivery is suspended";
550 pendingMessages << amsg;
551 return amsg.type() == QDBusMessage::MethodCallMessage;
554 switch (amsg.type()) {
555 case QDBusMessage::SignalMessage:
560 case QDBusMessage::MethodCallMessage:
564 if (Q_UNLIKELY(qDBusSpyHookList.exists()) && QCoreApplication::instanceExists()) {
566 Q_ASSERT(QThread::currentThread() != thread());
567 qDBusDebug() <<
this <<
"invoking message spies directly";
568 QDBusSpyCallEvent::invokeSpyHooks(amsg);
570 qDBusDebug() <<
this <<
"invoking message spies via event";
571 QCoreApplication::postEvent(
572 qApp,
new QDBusSpyCallEvent(
this, QDBusConnection(
this), amsg));
579 handleObjectCall(amsg);
581 case QDBusMessage::ReplyMessage:
582 case QDBusMessage::ErrorMessage:
583 case QDBusMessage::InvalidMessage:
590static void huntAndDestroy(QObject *needle, QDBusConnectionPrivate::ObjectTreeNode &haystack)
592 for (QDBusConnectionPrivate::ObjectTreeNode &node : haystack.children)
593 huntAndDestroy(needle, node);
595 auto isInactive = [](
const QDBusConnectionPrivate::ObjectTreeNode &node) {
return !node.isActive(); };
596 haystack.children.removeIf(isInactive);
598 if (needle == haystack.obj) {
599 haystack.obj =
nullptr;
605 QDBusConnection::UnregisterMode mode,
606 QDBusConnectionPrivate::ObjectTreeNode *node)
608 if (pathComponents.size() == i) {
613 if (mode == QDBusConnection::UnregisterTree) {
615 node->children.clear();
620 QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator end = node->children.end();
621 QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it =
622 std::lower_bound(node->children.begin(), end, pathComponents.at(i));
623 if (it == end || it->name != pathComponents.at(i))
626 huntAndUnregister(pathComponents, i + 1, mode, &(*it));
628 node->children.erase(it);
632static void huntAndEmit(DBusConnection *connection, DBusMessage *msg,
633 QObject *needle,
const QDBusConnectionPrivate::ObjectTreeNode &haystack,
634 bool isScriptable,
bool isAdaptor,
const QString &path = QString())
636 for (
const QDBusConnectionPrivate::ObjectTreeNode &node : std::as_const(haystack.children)) {
637 if (node.isActive()) {
638 huntAndEmit(connection, msg, needle, node, isScriptable, isAdaptor,
639 path + u'/' + node.name);
643 if (needle == haystack.obj) {
645 if (isAdaptor && (haystack.flags & QDBusConnection::ExportAdaptors) == 0)
647 else if (!isAdaptor) {
648 int mask = isScriptable
649 ? QDBusConnection::ExportScriptableSignals
650 : QDBusConnection::ExportNonScriptableSignals;
651 if ((haystack.flags & mask) == 0)
655 QByteArray p = path.toLatin1();
658 qDBusDebug() << QThread::currentThread() <<
"emitting signal at" << p;
660 q_dbus_message_set_path(msg2, p);
666static int findSlot(
const QMetaObject *mo,
const QByteArray &name,
int flags,
667 const QString &signature_, QList<QMetaType> &metaTypes)
669 QByteArray msgSignature = signature_.toLatin1();
670 QString parametersErrorMsg;
672 for (
int idx = mo->methodCount() - 1 ; idx >= QObject::staticMetaObject.methodCount(); --idx) {
673 QMetaMethod mm = mo->method(idx);
676 if (mm.access() != QMetaMethod::Public)
680 if (mm.methodType() != QMetaMethod::Slot && mm.methodType() != QMetaMethod::Method)
684 if (mm.name() != name)
687 QMetaType returnType = mm.returnMetaType();
688 bool isAsync = qDBusCheckAsyncTag(mm.tag());
689 bool isScriptable = mm.attributes() & QMetaMethod::Scriptable;
692 if (isAsync && returnType.id() != QMetaType::Void)
696 int inputCount = qDBusParametersForMethod(mm, metaTypes, errorMsg);
697 if (inputCount == -1) {
698 parametersErrorMsg = errorMsg;
702 metaTypes[0] = returnType;
703 bool hasMessage =
false;
704 if (inputCount > 0 &&
705 metaTypes.at(inputCount) == QDBusMetaTypeId::message()) {
713 QByteArray reconstructedSignature;
714 for (i = 1; i <= inputCount; ++i) {
715 const char *typeSignature = QDBusMetaType::typeToSignature( metaTypes.at(i) );
719 reconstructedSignature += typeSignature;
720 if (!msgSignature.startsWith(reconstructedSignature))
724 if (reconstructedSignature != msgSignature)
731 if (returnType.isValid() && returnType.id() != QMetaType::Void && QDBusMetaType::typeToSignature(returnType) ==
nullptr)
735 for (
int j = i; ok && j < metaTypes.size(); ++j)
736 if (QDBusMetaType::typeToSignature(metaTypes.at(i)) ==
nullptr)
742 if (isAsync && metaTypes.size() > i + 1)
745 if (mm.methodType() == QMetaMethod::Slot) {
746 if (isScriptable && (flags & QDBusConnection::ExportScriptableSlots) == 0)
748 if (!isScriptable && (flags & QDBusConnection::ExportNonScriptableSlots) == 0)
751 if (isScriptable && (flags & QDBusConnection::ExportScriptableInvokables) == 0)
753 if (!isScriptable && (flags & QDBusConnection::ExportNonScriptableInvokables) == 0)
762 if (!parametersErrorMsg.isEmpty()) {
763 qCWarning(dbusIntegration,
"QDBusConnection: couldn't handle call to %s: %ls",
766 qCWarning(dbusIntegration,
"QDBusConnection: couldn't handle call to %s, no slot matched",
773
774
775
776
777
778void QDBusConnectionPrivate::setDispatchEnabled(
bool enable)
781 dispatchEnabled = enable;
783 emit dispatchStatusChanged();
788QDBusCallDeliveryEvent *QDBusConnectionPrivate::prepareReply(QDBusConnectionPrivate *target,
789 QObject *object,
int idx,
790 const QList<QMetaType> &metaTypes,
791 const QDBusMessage &msg)
795 int n = metaTypes.size() - 1;
796 if (metaTypes[n] == QDBusMetaTypeId::message())
799 if (msg.arguments().size() < n)
803 for (
int i = 0; i < n; ++i)
804 if (metaTypes.at(i + 1) != msg.arguments().at(i).metaType() &&
805 msg.arguments().at(i).metaType() != QMetaType::fromType<QDBusArgument>())
810 if (target == object)
811 return DIRECT_DELIVERY;
812 return new QDBusCallDeliveryEvent(QDBusConnection(target), idx, target, msg, metaTypes);
815void QDBusConnectionPrivate::activateSignal(
const QDBusConnectionPrivate::SignalHook& hook,
816 const QDBusMessage &msg)
825 QDBusCallDeliveryEvent *call = prepareReply(
this, hook.obj, hook.midx, hook.params, msg);
826 if (call == DIRECT_DELIVERY) {
828 Q_ASSERT(
this == hook.obj);
829 deliverCall(
this, msg, hook.params, hook.midx);
833 postEventToThread(ActivateSignalAction, hook.obj, call);
836bool QDBusConnectionPrivate::activateCall(QObject *object, QDBusConnection::RegisterOptions flags,
837 const QDBusMessage &msg)
859 static const char cachePropertyName[] =
"_qdbus_slotCache";
864 Q_ASSERT_X(QThread::currentThread() == object->thread(),
865 "QDBusConnection: internal threading error",
866 "function called for an object that is in another thread!!");
868 QDBusSlotCache slotCache =
869 qvariant_cast<QDBusSlotCache>(object->property(cachePropertyName));
870 QString cacheKey = msg.member(), signature = msg.signature();
871 if (!signature.isEmpty()) {
872 cacheKey.reserve(cacheKey.size() + 1 + signature.size());
874 cacheKey += signature;
877 QDBusSlotCache::Key compoundKey{ std::move(cacheKey), flags };
878 QDBusSlotCache::Hash::ConstIterator cacheIt = slotCache.hash.constFind(compoundKey);
879 if (cacheIt == slotCache.hash.constEnd()) {
881 const QMetaObject *mo = object->metaObject();
882 QByteArray memberName = msg.member().toUtf8();
885 QDBusSlotCache::Data slotData;
886 slotData.slotIdx = ::findSlot(mo, memberName, flags, msg.signature(), slotData.metaTypes);
887 if (slotData.slotIdx == -1) {
890 slotData.slotIdx = ::findSlot(mo, memberName, flags, QString(), slotData.metaTypes);
891 if (slotData.metaTypes.size() != 2 ||
892 slotData.metaTypes.at(1) != QDBusMetaTypeId::message()) {
895 slotData.slotIdx = -1;
896 slotData.metaTypes.clear();
897 slotCache.hash.insert(compoundKey, slotData);
898 object->setProperty(cachePropertyName, QVariant::fromValue(slotCache));
900 qCWarning(dbusIntegration).nospace() <<
"Could not find slot " << mo->className()
901 <<
"::" << memberName.constData();
907 slotCache.hash.insert(compoundKey, slotData);
908 object->setProperty(cachePropertyName, QVariant::fromValue(slotCache));
911 deliverCall(object, msg, slotData.metaTypes, slotData.slotIdx);
913 }
else if (cacheIt->slotIdx == -1) {
918 deliverCall(object, msg, cacheIt->metaTypes, cacheIt->slotIdx);
924void QDBusConnectionPrivate::deliverCall(QObject *object,
const QDBusMessage &msg,
925 const QList<QMetaType> &metaTypes,
int slotIdx)
927 Q_ASSERT_X(!object || QThread::currentThread() == object->thread(),
928 "QDBusConnection: internal threading error",
929 "function called for an object that is in another thread!!");
931 QVarLengthArray<
void *, 10> params;
932 params.reserve(metaTypes.size());
934 QVarLengthArray<QVariant, 10> auxParameters;
935 auxParameters.reserve(metaTypes.size());
940 params.append(
nullptr);
944 int pCount = qMin(msg.arguments().size(), metaTypes.size() - 1);
945 for (i = 1; i <= pCount; ++i) {
946 auto id = metaTypes[i];
947 if (id == QDBusMetaTypeId::message())
950 const QList<QVariant> args = msg.arguments();
951 const QVariant &arg = args.at(i - 1);
952 if (arg.metaType() == id)
954 params.append(
const_cast<
void *>(arg.constData()));
955 else if (arg.metaType() == QMetaType::fromType<QDBusArgument>()) {
957 auxParameters.append(QVariant(QMetaType(id)));
959 const QDBusArgument &in =
960 *
reinterpret_cast<
const QDBusArgument *>(arg.constData());
961 QVariant &out = auxParameters[auxParameters.size() - 1];
963 if (Q_UNLIKELY(!QDBusMetaType::demarshall(in, out.metaType(), out.data())))
964 qFatal(
"Internal error: demarshalling function for type '%s' (%d) failed!",
965 out.typeName(), out.metaType().id());
967 params.append(
const_cast<
void *>(out.constData()));
969 qFatal(
"Internal error: got invalid meta type %d (%s) "
970 "when trying to convert to meta type %d (%s)",
971 arg.metaType().id(), arg.metaType().name(),
976 if (metaTypes.size() > i && metaTypes[i] == QDBusMetaTypeId::message()) {
977 params.append(
const_cast<
void*>(
static_cast<
const void*>(&msg)));
982 const int numMetaTypes = metaTypes.size();
983 QVariantList outputArgs;
984 if (metaTypes[0].id() != QMetaType::Void && metaTypes[0].isValid()) {
985 outputArgs.reserve(numMetaTypes - i + 1);
986 QVariant arg{QMetaType(metaTypes[0])};
987 outputArgs.append( arg );
988 params[0] =
const_cast<
void*>(outputArgs.at( outputArgs.size() - 1 ).constData());
990 outputArgs.reserve(numMetaTypes - i);
993 for ( ; i < numMetaTypes; ++i) {
994 QVariant arg{QMetaType(metaTypes[i])};
995 outputArgs.append( arg );
996 params.append(
const_cast<
void*>(outputArgs.at( outputArgs.size() - 1 ).constData()));
1005 QDBusContextPrivate context(QDBusConnection(
this), msg);
1006 QDBusContextPrivate *old = QDBusContextPrivate::set(object, &context);
1008 QPointer<QObject> ptr = object;
1009 fail = object->qt_metacall(QMetaObject::InvokeMetaMethod,
1010 slotIdx, params.data()) >= 0;
1013 QDBusContextPrivate::set(object, old);
1018 if (msg.isReplyRequired() && !msg.isDelayedReply()) {
1021 qDBusDebug() <<
this <<
"Automatically sending reply:" << outputArgs;
1022 send(msg.createReply(outputArgs));
1025 qCWarning(dbusIntegration,
"Internal error: Failed to deliver message");
1026 send(msg.createErrorReply(QDBusError::InternalError,
"Failed to deliver message"_L1));
1033QDBusConnectionPrivate::QDBusConnectionPrivate()
1036 busService(
nullptr),
1037 connection(
nullptr),
1039 anonymousAuthenticationAllowed(
false),
1040 dispatchEnabled(
true),
1041 isAuthenticated(
false)
1043 static const bool threads = q_dbus_threads_init_default();
1045 if (::isDebugging.loadRelaxed() == -1)
1046 ::isDebugging.storeRelaxed(qEnvironmentVariableIntValue(
"QDBUS_DEBUG"));
1048#ifdef QDBUS_THREAD_DEBUG
1049 if (::isDebugging.loadRelaxed() > 1)
1050 qdbusThreadDebug = qdbusDefaultThreadDebug;
1053 QDBusMetaTypeId::init();
1054 connect(
this, &QDBusConnectionPrivate::dispatchStatusChanged,
1055 this, &QDBusConnectionPrivate::doDispatch, Qt::QueuedConnection);
1056 connect(
this, &QDBusConnectionPrivate::spyHooksFinished,
1057 this, &QDBusConnectionPrivate::handleObjectCall, Qt::QueuedConnection);
1058 connect(
this, &QDBusConnectionPrivate::messageNeedsSending,
1059 this, &QDBusConnectionPrivate::sendInternal);
1061 rootNode.flags = {};
1065 watchedServices.insert(QDBusUtil::dbusService(), WatchedServiceData(QDBusUtil::dbusService(), 1));
1069 matchRefCounts.insert(
"type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='org.freedesktop.DBus'", 1);
1072QDBusConnectionPrivate::~QDBusConnectionPrivate()
1074 if (thread() && thread() != QThread::currentThread())
1076 "QDBusConnection(name=\"%s\")'s last reference in not in its creation thread! "
1077 "Timer and socket errors will follow and the program will probably crash",
1080 auto lastMode = mode;
1082 qDeleteAll(cachedMetaObjects);
1084 if (lastMode == ClientMode || lastMode == PeerMode) {
1087 Q_ASSERT(ref.loadRelaxed() == 0);
1088 QObject *obj = (QObject *)busService;
1090 disconnect(obj,
nullptr,
this,
nullptr);
1094 q_dbus_connection_unref(connection);
1095 connection =
nullptr;
1096 }
else if (lastMode == ServerMode) {
1098 q_dbus_server_unref(server);
1103void QDBusConnectionPrivate::collectAllObjects(QDBusConnectionPrivate::ObjectTreeNode &haystack,
1104 QSet<QObject *> &set)
1106 for (ObjectTreeNode &child : haystack.children)
1107 collectAllObjects(child, set);
1110 set.insert(haystack.obj);
1113void QDBusConnectionPrivate::closeConnection()
1115 QDBusWriteLocker locker(CloseConnectionAction,
this);
1117 ConnectionMode oldMode = mode;
1119 baseService.clear();
1121 if (oldMode == ServerMode && server) {
1122 q_dbus_server_disconnect(server);
1123 q_dbus_server_free_data_slot(&server_slot);
1126 if (oldMode == ClientMode || oldMode == PeerMode) {
1128 q_dbus_connection_close(connection);
1130 while (q_dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS)
1135 for (QDBusPendingCallPrivate *call : pendingCalls) {
1136 if (!call->ref.deref())
1139 pendingCalls.clear();
1146 QSet<QObject *> allObjects;
1147 collectAllObjects(rootNode, allObjects);
1148 for (
const SignalHook &signalHook : std::as_const(signalHooks))
1149 allObjects.insert(signalHook.obj);
1152 for (QObject *obj : std::as_const(allObjects))
1153 obj->disconnect(
this);
1156void QDBusConnectionPrivate::handleDBusDisconnection()
1158 while (!pendingCalls.isEmpty())
1159 processFinishedCall(pendingCalls.first());
1162void QDBusConnectionPrivate::checkThread()
1164 Q_ASSERT(thread() == QDBusConnectionManager::instance());
1165 Q_ASSERT(QThread::currentThread() == thread());
1168bool QDBusConnectionPrivate::handleError(
const QDBusErrorInternal &error)
1179void QDBusConnectionPrivate::timerEvent(QTimerEvent *e)
1182 DBusTimeout *timeout = timeouts.value(e->timerId(),
nullptr);
1184 q_dbus_timeout_handle(timeout);
1190void QDBusConnectionPrivate::doDispatch()
1192 if (mode == ClientMode || mode == PeerMode) {
1193 if (dispatchEnabled && !pendingMessages.isEmpty()) {
1195 for (QDBusMessage &message : pendingMessages) {
1196 qDBusDebug() <<
this <<
"dequeueing message" << message;
1197 handleMessage(std::move(message));
1199 pendingMessages.clear();
1201 while (q_dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS) ;
1205void QDBusConnectionPrivate::socketRead(qintptr fd)
1207 WatcherHash::ConstIterator it = watchers.constFind(fd);
1208 while (it != watchers.constEnd() && it.key() == fd) {
1209 if (it->watch && it->read && it->read->isEnabled()) {
1210 if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_READABLE))
1211 qDebug(
"OUT OF MEM");
1216 if ((mode == ClientMode || mode == PeerMode) && !isAuthenticated
1217 && q_dbus_connection_get_is_authenticated(connection))
1218 handleAuthentication();
1222void QDBusConnectionPrivate::socketWrite(qintptr fd)
1224 WatcherHash::ConstIterator it = watchers.constFind(fd);
1225 while (it != watchers.constEnd() && it.key() == fd) {
1226 if (it->watch && it->write && it->write->isEnabled()) {
1227 if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_WRITABLE))
1228 qDebug(
"OUT OF MEM");
1233 if ((mode == ClientMode || mode == PeerMode) && !isAuthenticated
1234 && q_dbus_connection_get_is_authenticated(connection))
1235 handleAuthentication();
1238void QDBusConnectionPrivate::objectDestroyed(QObject *obj)
1240 QDBusWriteLocker locker(ObjectDestroyedAction,
this);
1241 huntAndDestroy(obj, rootNode);
1243 SignalHookHash::iterator sit = signalHooks.begin();
1244 while (sit != signalHooks.end()) {
1245 if (
static_cast<QObject *>(sit.value().obj) == obj)
1246 sit = removeSignalHookNoLock(sit);
1251 obj->disconnect(
this);
1254void QDBusConnectionPrivate::relaySignal(QObject *obj,
const QMetaObject *mo,
int signalId,
1255 const QVariantList &args)
1257 QString interface = qDBusInterfaceFromMetaObject(mo);
1259 QMetaMethod mm = mo->method(signalId);
1260 QByteArray memberName = mm.name();
1263 bool isScriptable = mm.attributes() & QMetaMethod::Scriptable;
1264 bool isAdaptor =
false;
1265 for ( ; mo; mo = mo->superClass())
1266 if (mo == &QDBusAbstractAdaptor::staticMetaObject) {
1272 QDBusReadLocker locker(RelaySignalAction,
this);
1273 QDBusMessage message = QDBusMessage::createSignal(
"/"_L1, interface,
1274 QLatin1StringView(memberName));
1275 QDBusMessagePrivate::setParametersValidated(message,
true);
1276 message.setArguments(args);
1279 QDBusMessagePrivate::toDBusMessage(message, connectionCapabilities(), &error);
1281 qCWarning(dbusIntegration,
"QDBusConnection: Could not emit signal %s.%s: %s",
1289 q_dbus_message_set_no_reply(msg,
true);
1290 huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor);
1291 q_dbus_message_unref(msg);
1294void QDBusConnectionPrivate::serviceOwnerChangedNoLock(
const QString &name,
1295 const QString &oldOwner,
const QString &newOwner)
1298 WatchedServicesHash::Iterator it = watchedServices.find(name);
1299 if (it == watchedServices.end())
1301 if (oldOwner != it->owner)
1303 "QDBusConnection: name '%s' had owner '%s' but we thought it was '%s'",
1306 qDBusDebug() <<
this <<
"Updating name" << name <<
"from" << oldOwner <<
"to" << newOwner;
1307 it->owner = newOwner;
1310int QDBusConnectionPrivate::findSlot(QObject *obj,
const QByteArray &normalizedName,
1311 QList<QMetaType> ¶ms, QString &errorMsg)
1314 int midx = obj->metaObject()->indexOfMethod(normalizedName);
1318 int inputCount = qDBusParametersForMethod(obj->metaObject()->method(midx), params, errorMsg);
1319 if (inputCount == -1 || inputCount + 1 != params.size())
1325bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
1326 const QString &service,
const QString &path,
1327 const QString &interface,
const QString &name,
1328 const ArgMatchRules &argMatch, QObject *receiver,
1329 const char *signal,
int minMIdx,
bool buildSignature,
1332 QByteArray normalizedName = signal + 1;
1333 hook.midx = findSlot(receiver, signal + 1, hook.params, errorMsg);
1334 if (hook.midx == -1) {
1335 normalizedName = QMetaObject::normalizedSignature(signal + 1);
1336 hook.midx = findSlot(receiver, normalizedName, hook.params, errorMsg);
1338 if (hook.midx < minMIdx) {
1342 hook.service = service;
1344 hook.obj = receiver;
1345 hook.argumentMatch = argMatch;
1350 QString mname = name;
1351 if (buildSignature && mname.isNull()) {
1352 normalizedName.truncate(normalizedName.indexOf(
'('));
1353 mname = QString::fromUtf8(normalizedName);
1356 key.reserve(interface.size() + 1 + mname.size());
1360 if (buildSignature) {
1361 hook.signature.clear();
1362 for (
int i = 1; i < hook.params.size(); ++i)
1363 if (hook.params.at(i) != QDBusMetaTypeId::message())
1364 hook.signature += QLatin1StringView(QDBusMetaType::typeToSignature(hook.params.at(i)));
1367 hook.matchRule = buildMatchRule(service, path, interface, mname, argMatch, hook.signature);
1371void QDBusConnectionPrivate::sendError(
const QDBusMessage &msg, QDBusError::ErrorType code)
1373 if (code == QDBusError::UnknownMethod) {
1374 QString interfaceMsg;
1375 if (msg.interface().isEmpty())
1376 interfaceMsg =
"any interface"_L1;
1378 interfaceMsg =
"interface '%1'"_L1.arg(msg.interface());
1380 send(msg.createErrorReply(code,
"No such method '%1' in %2 at object path '%3' "
1381 "(signature '%4')"_L1
1382 .arg(msg.member(), interfaceMsg, msg.path(), msg.signature())));
1383 }
else if (code == QDBusError::UnknownInterface) {
1384 send(msg.createErrorReply(QDBusError::UnknownInterface,
1385 "No such interface '%1' at object path '%2'"_L1
1386 .arg(msg.interface(), msg.path())));
1387 }
else if (code == QDBusError::UnknownObject) {
1388 send(msg.createErrorReply(QDBusError::UnknownObject,
1389 "No such object path '%1'"_L1.arg(msg.path())));
1393bool QDBusConnectionPrivate::activateInternalFilters(
const ObjectTreeNode &node,
1394 const QDBusMessage &msg)
1397 const QString interface = msg.interface();
1399 if (interface.isEmpty() || interface == QDBusUtil::dbusInterfaceIntrospectable()) {
1400 if (msg.member() ==
"Introspect"_L1 && msg.signature().isEmpty()) {
1402 QDBusMessage reply = msg.createReply(qDBusIntrospectObject(node, msg.path()));
1407 if (!interface.isEmpty()) {
1408 sendError(msg, QDBusError::UnknownMethod);
1413 if (node.obj && (interface.isEmpty() ||
1414 interface == QDBusUtil::dbusInterfaceProperties())) {
1417 QDBusContextPrivate context(QDBusConnection(
this), msg);
1418 QDBusContextPrivate *old = QDBusContextPrivate::set(node.obj, &context);
1419 auto guard = qScopeGuard([&node, old]{
1420 QDBusContextPrivate::set(node.obj, old);
1423 if (msg.member() ==
"Get"_L1 && msg.signature() ==
"ss"_L1) {
1424 QDBusMessage reply = qDBusPropertyGet(node, msg);
1427 }
else if (msg.member() ==
"Set"_L1 && msg.signature() ==
"ssv"_L1) {
1428 QDBusMessage reply = qDBusPropertySet(node, msg);
1431 }
else if (msg.member() ==
"GetAll"_L1 && msg.signature() ==
"s"_L1) {
1432 QDBusMessage reply = qDBusPropertyGetAll(node, msg);
1437 if (!interface.isEmpty()) {
1438 sendError(msg, QDBusError::UnknownMethod);
1446void QDBusConnectionPrivate::activateObject(ObjectTreeNode &node,
const QDBusMessage &msg,
1456 if (node.flags & QDBusConnectionPrivate::VirtualObject) {
1457 if (node.treeNode->handleMessage(msg, q(
this))) {
1460 if (activateInternalFilters(node, msg))
1465 if (pathStartPos != msg.path().size()) {
1466 node.flags &= ~QDBusConnection::ExportAllSignals;
1467 node.obj = findChildObject(&node, msg.path(), pathStartPos);
1469 sendError(msg, QDBusError::UnknownObject);
1474 QDBusAdaptorConnector *connector;
1475 if (node.flags & QDBusConnection::ExportAdaptors &&
1476 (connector = qDBusFindAdaptorConnector(node.obj))) {
1477 auto newflags = node.flags | QDBusConnection::ExportAllSlots;
1479 if (msg.interface().isEmpty()) {
1482 for (
const QDBusAdaptorConnector::AdaptorData &adaptorData :
1483 std::as_const(connector->adaptors)) {
1484 if (activateCall(adaptorData.adaptor, newflags, msg))
1489 QDBusAdaptorConnector::AdaptorMap::ConstIterator it;
1490 it = std::lower_bound(connector->adaptors.constBegin(), connector->adaptors.constEnd(),
1492 if (it != connector->adaptors.constEnd() && msg.interface() == QLatin1StringView(it->interface)) {
1493 if (!activateCall(it->adaptor, newflags, msg))
1494 sendError(msg, QDBusError::UnknownMethod);
1502 if (activateInternalFilters(node, msg))
1506 if (node.flags & (QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportNonScriptableSlots) ||
1507 node.flags & (QDBusConnection::ExportScriptableInvokables|QDBusConnection::ExportNonScriptableInvokables)) {
1508 bool interfaceFound =
true;
1509 if (!msg.interface().isEmpty()) {
1510 if (!node.interfaceName.isEmpty())
1511 interfaceFound = msg.interface() == node.interfaceName;
1513 interfaceFound = qDBusInterfaceInObject(node.obj, msg.interface());
1516 if (interfaceFound) {
1517 if (!activateCall(node.obj, node.flags, msg))
1518 sendError(msg, QDBusError::UnknownMethod);
1524 if (msg.interface().isEmpty())
1525 sendError(msg, QDBusError::UnknownMethod);
1527 sendError(msg, QDBusError::UnknownInterface);
1530void QDBusConnectionPrivate::handleObjectCall(
const QDBusMessage &msg)
1539 ObjectTreeNode result;
1541 QThread *objThread =
nullptr;
1546 QDBusReadLocker locker(HandleObjectCallAction,
this);
1547 if (!findObject(&rootNode, msg.path(), usedLength, result)) {
1549 sendError(msg, QDBusError::UnknownObject);
1556 activateObject(result, msg, usedLength);
1560 objThread = result.obj->thread();
1562 send(msg.createErrorReply(QDBusError::InternalError,
1563 "Object '%1' (at path '%2')"
1564 " has no thread. Cannot deliver message."_L1
1565 .arg(result.obj->objectName(), msg.path())));
1569 if (!QDBusMessagePrivate::isLocal(msg)) {
1572 postEventToThread(HandleObjectCallPostEventAction, result.obj,
1573 new QDBusActivateObjectEvent(QDBusConnection(
this),
this, result,
1576 }
else if (objThread != QThread::currentThread()) {
1579 postEventToThread(HandleObjectCallPostEventAction, result.obj,
1580 new QDBusActivateObjectEvent(QDBusConnection(
this),
this, result,
1581 usedLength, msg, &latch));
1592 activateObject(result, msg, usedLength);
1600 QDBusConnectionPrivate *that = QDBusConnectionPrivate::d(connection);
1601 that->sendError(message, QDBusError::UnknownObject);
1609 QDBusConnectionPrivate *that = QDBusConnectionPrivate::d(connection);
1613 that->activateObject(node, message, pathStartPos);
1620void QDBusConnectionPrivate::handleSignal(
const QString &key,
const QDBusMessage& msg)
1622 SignalHookHash::const_iterator it = signalHooks.constFind(key);
1623 SignalHookHash::const_iterator end = signalHooks.constEnd();
1626 for ( ; it != end && it.key() == key; ++it) {
1627 const SignalHook &hook = it.value();
1628 if (!hook.service.isEmpty()) {
1629 QString owner = watchedServices.value(hook.service, WatchedServiceData(hook.service)).owner;
1630 if (owner != msg.service())
1633 if (!hook.path.isEmpty() && hook.path != msg.path())
1635 if (!hook.signature.isEmpty() && hook.signature != msg.signature())
1637 if (hook.signature.isEmpty() && !hook.signature.isNull() && !msg.signature().isEmpty())
1639 if (!hook.argumentMatch.args.isEmpty()) {
1640 const QVariantList arguments = msg.arguments();
1641 if (hook.argumentMatch.args.size() > arguments.size())
1644 bool matched =
true;
1645 for (
int i = 0; i < hook.argumentMatch.args.size(); ++i) {
1646 const QString ¶m = hook.argumentMatch.args.at(i);
1649 if (param == arguments.at(i).toString())
1657 if (!hook.argumentMatch.arg0namespace.isEmpty()) {
1658 const QVariantList arguments = msg.arguments();
1659 if (arguments.size() < 1)
1661 const QString param = arguments.at(0).toString();
1662 const QStringView ns = hook.argumentMatch.arg0namespace;
1663 if (!param.startsWith(ns) || (param.size() != ns.size() && param[ns.size()] != u'.'))
1666 activateSignal(hook, msg);
1670void QDBusConnectionPrivate::handleSignal(
const QDBusMessage& msg)
1679 QString key = msg.member();
1680 key.reserve(key.size() + 1 + msg.interface().size());
1682 key += msg.interface();
1684 QDBusWriteLocker locker(HandleSignalAction,
this);
1685 handleSignal(key, msg);
1687 key.truncate(msg.member().size() + 1);
1688 handleSignal(key, msg);
1691 key += msg.interface();
1692 handleSignal(key, msg);
1695void QDBusConnectionPrivate::watchForDBusDisconnection()
1699 hook.service.clear();
1700 hook.path = QDBusUtil::dbusPathLocal();
1702 hook.params << QMetaType(QMetaType::Void);
1703 hook.midx = staticMetaObject.indexOfSlot(
"handleDBusDisconnection()");
1704 Q_ASSERT(hook.midx != -1);
1708void QDBusConnectionPrivate::setServer(QDBusServer *object, DBusServer *s,
const QDBusErrorInternal &error)
1711 serverObject = object;
1720 dbus_bool_t data_allocated = q_dbus_server_allocate_data_slot(&server_slot);
1721 if (data_allocated && server_slot < 0)
1724 dbus_bool_t watch_functions_set = q_dbus_server_set_watch_functions(server,
1730 Q_UNUSED(watch_functions_set);
1732 dbus_bool_t time_functions_set = q_dbus_server_set_timeout_functions(server,
1738 Q_UNUSED(time_functions_set);
1740 q_dbus_server_set_new_connection_function(server, qDBusNewConnection,
this,
nullptr);
1742 dbus_bool_t data_set = q_dbus_server_set_data(server, server_slot,
this,
nullptr);
1747void QDBusConnectionPrivate::setPeer(DBusConnection *c,
const QDBusErrorInternal &error)
1757 q_dbus_connection_set_exit_on_disconnect(connection,
false);
1758 q_dbus_connection_set_watch_functions(connection,
1763 q_dbus_connection_set_timeout_functions(connection,
1768 q_dbus_connection_set_dispatch_status_function(connection, qDBusUpdateDispatchStatus,
this,
nullptr);
1769 q_dbus_connection_add_filter(connection,
1773 watchForDBusDisconnection();
1775 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::doDispatch, Qt::QueuedConnection);
1780 QDBusConnection::ConnectionCapabilities result;
1781 typedef dbus_bool_t (*can_send_type_t)(DBusConnection *,
int);
1782 static can_send_type_t can_send_type =
nullptr;
1784#if defined(QT_LINKED_LIBDBUS)
1785# if DBUS_VERSION-0
>= 0x010400
1786 can_send_type = dbus_connection_can_send_type;
1788#elif QT_CONFIG(library)
1790 can_send_type = (can_send_type_t)qdbus_resolve_conditionally(
"dbus_connection_can_send_type");
1794# define DBUS_TYPE_UNIX_FD int('h')
1797 result |= QDBusConnection::UnixFileDescriptorPassing;
1802void QDBusConnectionPrivate::handleAuthentication()
1804 capabilities.storeRelaxed(::connectionCapabilities(connection));
1805 isAuthenticated =
true;
1808void QDBusConnectionPrivate::setConnection(DBusConnection *dbc,
const QDBusErrorInternal &error)
1818 const char *service = q_dbus_bus_get_unique_name(connection);
1820 baseService = QString::fromUtf8(service);
1822 handleAuthentication();
1824 q_dbus_connection_set_exit_on_disconnect(connection,
false);
1825 q_dbus_connection_set_watch_functions(connection, qDBusAddWatch, qDBusRemoveWatch,
1826 qDBusToggleWatch,
this,
nullptr);
1827 q_dbus_connection_set_timeout_functions(connection, qDBusAddTimeout, qDBusRemoveTimeout,
1828 qDBusToggleTimeout,
this,
nullptr);
1829 q_dbus_connection_set_dispatch_status_function(connection, qDBusUpdateDispatchStatus,
this,
nullptr);
1830 q_dbus_connection_add_filter(connection, qDBusSignalFilter,
this,
nullptr);
1836 hook.service = QDBusUtil::dbusService();
1839 hook.params << QMetaType(QMetaType::Void) << QMetaType(QMetaType::QString);
1841 hook.midx = staticMetaObject.indexOfSlot(
"registerServiceNoLock(QString)");
1842 Q_ASSERT(hook.midx != -1);
1845 hook.midx = staticMetaObject.indexOfSlot(
"unregisterServiceNoLock(QString)");
1846 Q_ASSERT(hook.midx != -1);
1851 hook.params.clear();
1852 hook.params.reserve(4);
1853 hook.params << QMetaType(QMetaType::Void) << QMetaType(QMetaType::QString) << QMetaType(QMetaType::QString) << QMetaType(QMetaType::QString);
1854 hook.midx = staticMetaObject.indexOfSlot(
"serviceOwnerChangedNoLock(QString,QString,QString)");
1855 Q_ASSERT(hook.midx != -1);
1858 watchForDBusDisconnection();
1860 qDBusDebug() <<
this <<
": connected successfully";
1863 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::doDispatch, Qt::QueuedConnection);
1871 QDBusConnectionPrivate::processFinishedCall(call);
1875void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
1877 QDBusConnectionPrivate *connection =
const_cast<QDBusConnectionPrivate *>(call->connection);
1879 auto locker = qt_unique_lock(call->mutex);
1881 connection->pendingCalls.removeOne(call);
1883 QDBusMessage &msg = call->replyMessage;
1884 if (call->pending) {
1887 if (q_dbus_pending_call_get_completed(call->pending)) {
1889 DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
1890 msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->connectionCapabilities());
1891 q_dbus_message_unref(reply);
1893 msg = QDBusMessage::createError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
1896 qDBusDebug() << connection <<
"got message reply:" << msg;
1899 call->checkReceivedSignature();
1901 if (!call->receiver.isNull() && call->methodIdx != -1 && msg.type() == QDBusMessage::ReplyMessage) {
1910 QDBusCallDeliveryEvent *e = prepareReply(connection, call->receiver, call->methodIdx,
1911 call->metaTypes, msg);
1913 connection->postEventToThread(MessageResultReceivedAction, call->receiver, e);
1918 if (call->pending) {
1919 q_dbus_pending_call_unref(call->pending);
1920 call->pending =
nullptr;
1924 if (call->watcherHelper)
1925 call->watcherHelper->emitSignals(msg, call->sentMessage);
1927 call->waitForFinishedCondition.wakeAll();
1930 if (msg.type() == QDBusMessage::ErrorMessage)
1931 emit connection->callWithCallbackFailed(QDBusError(msg), call->sentMessage);
1933 if (!call->ref.deref())
1937bool QDBusConnectionPrivate::send(
const QDBusMessage& message)
1939 if (QDBusMessagePrivate::isLocal(message))
1945 QDBusMessagePrivate::toDBusMessage(message, connectionCapabilities(), &error);
1947 if (message.type() == QDBusMessage::MethodCallMessage)
1949 "QDBusConnection: error: could not send message to service \"%s\" path "
1950 "\"%s\" interface \"%s\" member \"%s\": %s",
1954 else if (message.type() == QDBusMessage::SignalMessage)
1956 "QDBusConnection: error: could not send signal to service \"%s\" path \"%s\" "
1957 "interface \"%s\" member \"%s\": %s",
1963 "QDBusConnection: error: could not send %s message to service \"%s\": %s",
1964 message.type() == QDBusMessage::ReplyMessage ?
"reply"
1965 : message.type() == QDBusMessage::ErrorMessage ?
"error"
1972 q_dbus_message_set_no_reply(msg,
true);
1973 qDBusDebug() <<
this <<
"sending message (no reply):" << message;
1974 emit messageNeedsSending(
nullptr, msg);
1990#if defined(QT_NO_DEBUG)
2008 env =
qgetenv(
"Q_DBUS_BLOCKING_CALL_MAIN_THREAD_WARNING_MS");
2016 "QDBusBlockingCallWatcher: Q_DBUS_BLOCKING_CALL_MAIN_THREAD_WARNING_MS "
2017 "must be an integer; value ignored");
2020 env =
qgetenv(
"Q_DBUS_BLOCKING_CALL_OTHER_THREAD_WARNING_MS");
2027 "QDBusBlockingCallWatcher: "
2028 "Q_DBUS_BLOCKING_CALL_OTHER_THREAD_WARNING_MS must be an integer; "
2050 if (m_maxCallTimeoutMs < 0)
2053 if (m_callTimer.elapsed() >= m_maxCallTimeoutMs) {
2056 "QDBusConnection: warning: blocking call took a long time (%d ms, max for this "
2057 "thread is %d ms) to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"",
2058 int(m_callTimer.elapsed()), m_maxCallTimeoutMs,
qPrintable(m_message.service()),
2065 QDBusMessage m_message;
2066 int m_maxCallTimeoutMs;
2067 QElapsedTimer m_callTimer;
2070QDBusMessage QDBusConnectionPrivate::sendWithReply(
const QDBusMessage &message,
2071 QDBus::CallMode mode,
int timeout)
2073 QDBusBlockingCallWatcher watcher(message);
2075 QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message,
nullptr,
nullptr,
nullptr, timeout);
2078 if (mode == QDBus::BlockWithGui)
2079 pcall->waitForFinishedWithGui();
2081 pcall->waitForFinished();
2083 QDBusMessage reply = pcall->replyMessage;
2084 lastError = QDBusError(reply);
2086 if (!pcall->ref.deref())
2091QDBusMessage QDBusConnectionPrivate::sendWithReplyLocal(
const QDBusMessage &message)
2093 qDBusDebug() <<
this <<
"sending message via local-loop:" << message;
2095 QDBusMessage localCallMsg = QDBusMessagePrivate::makeLocal(*
this, message);
2096 bool handled = handleMessage(localCallMsg);
2099 QString interface = message.interface();
2100 if (interface.isEmpty())
2101 interface =
"<no-interface>"_L1;
2102 return QDBusMessage::createError(QDBusError::InternalError,
2103 "Internal error trying to call %1.%2 at %3 (signature '%4'"_L1
2104 .arg(interface, message.member(),
2105 message.path(), message.signature()));
2109 QDBusMessage localReplyMsg = QDBusMessagePrivate::makeLocalReply(*
this, localCallMsg);
2110 if (localReplyMsg.type() == QDBusMessage::InvalidMessage) {
2113 "QDBusConnection: cannot call local method '%s' at object %s (with signature '%s') "
2117 return QDBusMessage::createError(
2118 QDBusError(QDBusError::InternalError,
2119 "local-loop message cannot have delayed replies"_L1));
2123 qDBusDebug() <<
this <<
"got message via local-loop:" << localReplyMsg;
2124 return localReplyMsg;
2127QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(
const QDBusMessage &message,
2128 QObject *receiver,
const char *returnMethod,
2129 const char *errorMethod,
int timeout)
2131 QDBusPendingCallPrivate *pcall =
new QDBusPendingCallPrivate(message,
this);
2133 if ((isLoopback = isServiceRegisteredByThread(message.service()))) {
2135 pcall->replyMessage = sendWithReplyLocal(message);
2138 if (receiver && returnMethod)
2139 pcall->setReplyCallback(receiver, returnMethod);
2142 Q_ASSERT(!pcall->watcherHelper);
2143 pcall->watcherHelper =
new QDBusPendingCallWatcherHelper;
2144 connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), receiver, errorMethod,
2145 Qt::QueuedConnection);
2146 pcall->watcherHelper->moveToThread(thread());
2149 if ((receiver && returnMethod) || errorMethod) {
2151 pcall->ref.storeRelaxed(1);
2155 pcall->ref.storeRelaxed(2);
2160 processFinishedCall(pcall);
2166 QDBusMessagePrivate::toDBusMessage(message, connectionCapabilities(), &error);
2169 "QDBusConnection: error: could not send message to service \"%s\" path \"%s\" "
2170 "interface \"%s\" member \"%s\": %s",
2174 pcall->replyMessage = QDBusMessage::createError(error);
2176 processFinishedCall(pcall);
2178 qDBusDebug() <<
this <<
"sending message:" << message;
2179 emit messageNeedsSending(pcall, msg, timeout);
2184void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall,
void *message,
int timeout)
2187 DBusPendingCall *pending =
nullptr;
2188 DBusMessage *msg =
static_cast<DBusMessage *>(message);
2189 bool isNoReply = !pcall;
2190 Q_ASSERT(isNoReply == !!q_dbus_message_get_no_reply(msg));
2194 if (isNoReply && q_dbus_connection_send(connection, msg,
nullptr)) {
2196 }
else if (!isNoReply && q_dbus_connection_send_with_reply(connection, msg, &pending, timeout)) {
2198 q_dbus_message_unref(msg);
2200 pcall->pending = pending;
2201 q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall,
nullptr);
2204 if (mode == QDBusConnectionPrivate::PeerMode || mode == QDBusConnectionPrivate::ClientMode)
2205 pendingCalls.append(pcall);
2210 lastError = error = QDBusError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
2213 lastError = error = QDBusError(QDBusError::NoMemory,
QStringLiteral(
"Out of memory"));
2216 q_dbus_message_unref(msg);
2218 pcall->replyMessage = QDBusMessage::createError(error);
2219 processFinishedCall(pcall);
2224bool QDBusConnectionPrivate::connectSignal(
const QString &service,
2225 const QString &path,
const QString &interface,
const QString &name,
2226 const QStringList &argumentMatch,
const QString &signature,
2227 QObject *receiver,
const char *slot)
2229 ArgMatchRules rules;
2230 rules.args = argumentMatch;
2231 return connectSignal(service, path, interface, name, rules, signature, receiver, slot);
2234bool QDBusConnectionPrivate::connectSignal(
const QString &service,
2235 const QString &path,
const QString &interface,
const QString &name,
2236 const ArgMatchRules &argumentMatch,
const QString &signature,
2237 QObject *receiver,
const char *slot)
2240 QDBusConnectionPrivate::SignalHook hook;
2243 hook.signature = signature;
2245 if (!prepareHook(hook, key, service, path, interface, name, argumentMatch, receiver, slot, 0,
2248 <<
"Could not connect" << interface <<
"to" << slot + 1 <<
":" <<
qPrintable(errorMsg);
2252 Q_ASSERT(thread() != QThread::currentThread());
2253 return addSignalHook(key, hook);
2256bool QDBusConnectionPrivate::addSignalHook(
const QString &key,
const SignalHook &hook)
2258 bool result =
false;
2260 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::addSignalHookImpl,
2261 Qt::BlockingQueuedConnection, qReturnArg(result), key, hook);
2266bool QDBusConnectionPrivate::addSignalHookImpl(
const QString &key,
const SignalHook &hook)
2268 QDBusWriteLocker locker(ConnectAction,
this);
2271 QDBusConnectionPrivate::SignalHookHash::ConstIterator it = signalHooks.constFind(key);
2272 QDBusConnectionPrivate::SignalHookHash::ConstIterator end = signalHooks.constEnd();
2273 for ( ; it != end && it.key() == key; ++it) {
2274 const QDBusConnectionPrivate::SignalHook &entry = it.value();
2275 if (entry.service == hook.service &&
2276 entry.path == hook.path &&
2277 entry.signature == hook.signature &&
2278 entry.obj == hook.obj &&
2279 entry.midx == hook.midx &&
2280 entry.argumentMatch == hook.argumentMatch) {
2286 signalHooks.insert(key, hook);
2287 connect(hook.obj, &QObject::destroyed,
this, &QDBusConnectionPrivate::objectDestroyed,
2288 Qt::ConnectionType(Qt::BlockingQueuedConnection | Qt::UniqueConnection));
2290 MatchRefCountHash::iterator mit = matchRefCounts.find(hook.matchRule);
2292 if (mit != matchRefCounts.end()) {
2293 mit.value() = mit.value() + 1;
2297 matchRefCounts.insert(hook.matchRule, 1);
2300 if (mode != QDBusConnectionPrivate::PeerMode) {
2301 qDBusDebug() <<
this <<
"Adding rule:" << hook.matchRule;
2302 q_dbus_bus_add_match(connection, hook.matchRule,
nullptr);
2306 if (shouldWatchService(hook.service)) {
2307 WatchedServicesHash::mapped_type &data = watchedServices[hook.service];
2308 if (++data.refcount == 1) {
2310 ArgMatchRules rules;
2311 rules.args << hook.service;
2312 q_dbus_bus_add_match(connection,
2313 buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(),
2314 QDBusUtil::nameOwnerChanged(), rules, QString()),
2316 data.owner = getNameOwnerNoCache(hook.service);
2317 qDBusDebug() <<
this <<
"Watching service" << hook.service <<
"for owner changes (current owner:"
2318 << data.owner <<
")";
2326bool QDBusConnectionPrivate::disconnectSignal(
const QString &service,
2327 const QString &path,
const QString &interface,
const QString &name,
2328 const QStringList &argumentMatch,
const QString &signature,
2329 QObject *receiver,
const char *slot)
2331 ArgMatchRules rules;
2332 rules.args = argumentMatch;
2333 return disconnectSignal(service, path, interface, name, rules, signature, receiver, slot);
2336bool QDBusConnectionPrivate::disconnectSignal(
const QString &service,
2337 const QString &path,
const QString &interface,
const QString &name,
2338 const ArgMatchRules &argumentMatch,
const QString &signature,
2339 QObject *receiver,
const char *slot)
2342 QDBusConnectionPrivate::SignalHook hook;
2344 QString name2 = name;
2348 hook.signature = signature;
2350 if (!prepareHook(hook, key, service, path, interface, name, argumentMatch, receiver, slot, 0,
2353 <<
"Could not disconnect" << interface <<
"to" << slot + 1 <<
":" <<
qPrintable(errorMsg);
2357 Q_ASSERT(thread() != QThread::currentThread());
2358 return removeSignalHook(key, hook);
2361bool QDBusConnectionPrivate::removeSignalHook(
const QString &key,
const SignalHook &hook)
2363 bool result =
false;
2365 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::removeSignalHookImpl,
2366 Qt::BlockingQueuedConnection, qReturnArg(result), key, hook);
2371bool QDBusConnectionPrivate::removeSignalHookImpl(
const QString &key,
const SignalHook &hook)
2374 QDBusWriteLocker locker(ConnectAction,
this);
2375 QDBusConnectionPrivate::SignalHookHash::Iterator it = signalHooks.find(key);
2376 QDBusConnectionPrivate::SignalHookHash::Iterator end = signalHooks.end();
2377 for ( ; it != end && it.key() == key; ++it) {
2378 const QDBusConnectionPrivate::SignalHook &entry = it.value();
2379 if (entry.service == hook.service &&
2380 entry.path == hook.path &&
2381 entry.signature == hook.signature &&
2382 entry.obj == hook.obj &&
2383 entry.midx == hook.midx &&
2384 entry.argumentMatch.args == hook.argumentMatch.args) {
2386 removeSignalHookNoLock(it);
2395QDBusConnectionPrivate::SignalHookHash::Iterator
2396QDBusConnectionPrivate::removeSignalHookNoLock(SignalHookHash::Iterator it)
2398 const SignalHook &hook = it.value();
2401 MatchRefCountHash::iterator i = matchRefCounts.find(hook.matchRule);
2402 if (i == matchRefCounts.end()) {
2404 "QDBusConnectionPrivate::disconnectSignal: MatchRule not found in "
2405 "matchRefCounts!!");
2407 if (i.value() == 1) {
2409 matchRefCounts.erase(i);
2412 i.value() = i.value() - 1;
2417 if (connection && erase) {
2418 if (mode != QDBusConnectionPrivate::PeerMode) {
2419 qDBusDebug() <<
this <<
"Removing rule:" << hook.matchRule;
2420 q_dbus_bus_remove_match(connection, hook.matchRule,
nullptr);
2424 WatchedServicesHash::Iterator sit = watchedServices.find(hook.service);
2425 if (sit != watchedServices.end()) {
2426 if (--sit.value().refcount == 0) {
2427 watchedServices.erase(sit);
2428 ArgMatchRules rules;
2429 rules.args << hook.service;
2430 q_dbus_bus_remove_match(connection,
2431 buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(),
2432 QDBusUtil::nameOwnerChanged(), rules, QString()),
2440 return signalHooks.erase(it);
2443void QDBusConnectionPrivate::registerObject(
const ObjectTreeNode *node)
2445 connect(node->obj, &QObject::destroyed,
this, &QDBusConnectionPrivate::objectDestroyed,
2446 Qt::ConnectionType(Qt::BlockingQueuedConnection | Qt::UniqueConnection));
2448 if (node->flags & (QDBusConnection::ExportAdaptors
2449 | QDBusConnection::ExportScriptableSignals
2450 | QDBusConnection::ExportNonScriptableSignals)) {
2451 QDBusAdaptorConnector *connector = qDBusCreateAdaptorConnector(node->obj);
2453 if (node->flags & (QDBusConnection::ExportScriptableSignals
2454 | QDBusConnection::ExportNonScriptableSignals)) {
2455 connector->disconnectAllSignals(node->obj);
2456 connector->connectAllSignals(node->obj);
2459 connect(connector, &QDBusAdaptorConnector::relaySignal,
this,
2460 &QDBusConnectionPrivate::relaySignal,
2461 Qt::ConnectionType(Qt::QueuedConnection | Qt::UniqueConnection));
2465void QDBusConnectionPrivate::unregisterObject(
const QString &path, QDBusConnection::UnregisterMode mode)
2467 QDBusConnectionPrivate::ObjectTreeNode *node = &rootNode;
2468 QList<QStringView> pathComponents;
2470 if (path ==
"/"_L1) {
2473 pathComponents = QStringView{path}.split(u'/');
2477 huntAndUnregister(pathComponents, i, mode, node);
2480void QDBusConnectionPrivate::connectRelay(
const QString &service,
2481 const QString &path,
const QString &interface,
2482 QDBusAbstractInterface *receiver,
2483 const QMetaMethod &signal)
2491 sig.append(QSIGNAL_CODE +
'0');
2492 sig.append(signal.methodSignature());
2494 if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig,
2495 QDBusAbstractInterface::staticMetaObject.methodCount(),
true, errorMsg)) {
2497 <<
"Could not connect" << interface <<
"to" << signal.name() <<
":" <<
qPrintable(errorMsg);
2501 Q_ASSERT(thread() != QThread::currentThread());
2502 addSignalHook(key, hook);
2505void QDBusConnectionPrivate::disconnectRelay(
const QString &service,
2506 const QString &path,
const QString &interface,
2507 QDBusAbstractInterface *receiver,
2508 const QMetaMethod &signal)
2516 sig.append(QSIGNAL_CODE +
'0');
2517 sig.append(signal.methodSignature());
2519 if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig,
2520 QDBusAbstractInterface::staticMetaObject.methodCount(),
true, errorMsg)) {
2521 qCWarning(dbusIntegration) <<
"Could not disconnect" << interface <<
"to"
2522 << signal.methodSignature() <<
":" <<
qPrintable(errorMsg);
2526 Q_ASSERT(thread() != QThread::currentThread());
2527 removeSignalHook(key, hook);
2530bool QDBusConnectionPrivate::shouldWatchService(
const QString &service)
2533 if (mode != ClientMode)
2536 if (service.isEmpty())
2539 if (service == QDBusUtil::dbusService())
2545
2546
2547
2548
2549
2550
2551
2552
2553void QDBusConnectionPrivate::watchService(
const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj,
const char *member)
2555 ArgMatchRules matchArgs = matchArgsForService(service, mode);
2556 connectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(),
2557 matchArgs, QString(), obj, member);
2561
2562
2563
2564
2565
2566
2567
2568void QDBusConnectionPrivate::unwatchService(
const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj,
const char *member)
2570 ArgMatchRules matchArgs = matchArgsForService(service, mode);
2571 disconnectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(),
2572 matchArgs, QString(), obj, member);
2575QString QDBusConnectionPrivate::getNameOwner(
const QString& serviceName)
2577 if (QDBusUtil::isValidUniqueConnectionName(serviceName))
2584 QReadLocker locker(&lock);
2585 WatchedServicesHash::ConstIterator it = watchedServices.constFind(serviceName);
2586 if (it != watchedServices.constEnd())
2591 return getNameOwnerNoCache(serviceName);
2594QString QDBusConnectionPrivate::getNameOwnerNoCache(
const QString &serviceName)
2596 QDBusMessage msg = QDBusMessage::createMethodCall(QDBusUtil::dbusService(),
2597 QDBusUtil::dbusPath(), QDBusUtil::dbusInterface(),
2599 QDBusMessagePrivate::setParametersValidated(msg,
true);
2602 QDBusPendingCallPrivate *pcall = sendWithReplyAsync(msg,
nullptr,
nullptr,
nullptr);
2603 if (thread() == QThread::currentThread()) {
2606 q_dbus_pending_call_block(pcall->pending);
2608 pcall->waitForFinished();
2609 msg = pcall->replyMessage;
2611 if (!pcall->ref.deref())
2614 if (msg.type() == QDBusMessage::ReplyMessage)
2615 return msg.arguments().at(0).toString();
2620QDBusConnectionPrivate::findMetaObject(
const QString &service,
const QString &path,
2621 const QString &interface, QDBusError &error)
2624 if (!interface.isEmpty()) {
2625 QDBusReadLocker locker(FindMetaObject1Action,
this);
2626 QDBusMetaObject *mo = cachedMetaObjects.value(interface,
nullptr);
2630 if (path.isEmpty()) {
2631 error = QDBusError(QDBusError::InvalidObjectPath,
"Object path cannot be empty"_L1);
2637 QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
2638 QDBusUtil::dbusInterfaceIntrospectable(),
2640 QDBusMessagePrivate::setParametersValidated(msg,
true);
2642 QDBusMessage reply = sendWithReply(msg, QDBus::Block);
2645 QDBusWriteLocker locker(FindMetaObject2Action,
this);
2646 QDBusMetaObject *mo =
nullptr;
2647 if (!interface.isEmpty())
2648 mo = cachedMetaObjects.value(interface,
nullptr);
2654 if (reply.type() == QDBusMessage::ReplyMessage) {
2655 if (reply.signature() ==
"s"_L1)
2657 xml = reply.arguments().at(0).toString();
2659 error = QDBusError(reply);
2661 if (reply.type() != QDBusMessage::ErrorMessage || error.type() != QDBusError::UnknownMethod)
2666 QDBusMetaObject *result = QDBusMetaObject::createMetaObject(interface, xml,
2667 cachedMetaObjects, error);
2672void QDBusConnectionPrivate::registerService(
const QString &serviceName)
2674 QDBusWriteLocker locker(RegisterServiceAction,
this);
2675 registerServiceNoLock(serviceName);
2678void QDBusConnectionPrivate::registerServiceNoLock(
const QString &serviceName)
2680 serviceNames.append(serviceName);
2683void QDBusConnectionPrivate::unregisterService(
const QString &serviceName)
2685 QDBusWriteLocker locker(UnregisterServiceAction,
this);
2686 unregisterServiceNoLock(serviceName);
2689void QDBusConnectionPrivate::unregisterServiceNoLock(
const QString &serviceName)
2691 serviceNames.removeAll(serviceName);
2694bool QDBusConnectionPrivate::isServiceRegisteredByThread(
const QString &serviceName)
2696 if (!serviceName.isEmpty() && serviceName == baseService)
2698 if (serviceName == QDBusUtil::dbusService())
2701 QDBusReadLocker locker(UnregisterServiceAction,
this);
2702 return serviceNames.contains(serviceName);
2705void QDBusConnectionPrivate::postEventToThread(
int action, QObject *object, QEvent *ev)
2707 QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforePost,
this);
2708 QCoreApplication::postEvent(object, ev);
2709 QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterPost,
this);
2713
2714
2715
2716
2717void QDBusConnectionPrivate::enableDispatchDelayed(QObject *context)
2720 QMetaObject::invokeMethod(
2726 QMetaObject::invokeMethod(
this, &QDBusConnectionPrivate::setDispatchEnabled,
2727 Qt::QueuedConnection,
true);
2731 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)
@ HandleObjectCallPostEventAction
#define qCWarning(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)
#define qPrintable(string)
#define QStringLiteral(str)
#define qUtf16Printable(string)
static void reportThreadAction(int, int, QDBusConnectionPrivate *)