summaryrefslogtreecommitdiffstats
path: root/src/dbus
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-01-26 14:35:50 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2016-01-26 16:27:28 +0100
commita15c3d086dafea83e4760f0b447be43d26b80697 (patch)
treefd224a3f83942ff4c432e1e3a3f8583d14d6a11c /src/dbus
parent87abfd351af6309691d921ca0aef077d74df4732 (diff)
parent397061a6a92db9f962360d5db96f69b315f93074 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java src/dbus/qdbusconnection_p.h src/dbus/qdbusintegrator.cpp src/dbus/qdbusintegrator_p.h tests/auto/corelib/io/qdir/qdir.pro tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp Change-Id: I3d3fd07aed015c74b1f545f1327aa73d5f365fcc
Diffstat (limited to 'src/dbus')
-rw-r--r--src/dbus/qdbusconnection_p.h1
-rw-r--r--src/dbus/qdbusintegrator.cpp46
-rw-r--r--src/dbus/qdbusintegrator_p.h19
3 files changed, 55 insertions, 11 deletions
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index d5f4f80e64..83a2e6fc32 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -286,6 +286,7 @@ private slots:
signals:
void dispatchStatusChanged();
+ void spyHooksFinished(const QDBusMessage &msg);
void messageNeedsSending(QDBusPendingCallPrivate *pcall, void *msg, int timeout = -1);
void signalNeedsConnecting(const QString &key, const QDBusConnectionPrivate::SignalHook &hook);
bool signalNeedsDisconnecting(const QString &key, const QDBusConnectionPrivate::SignalHook &hook);
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index e630744854..3cd5c4d8e4 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -126,8 +126,7 @@ void qdbusDefaultThreadDebug(int action, int condition, QDBusConnectionPrivate *
qdbusThreadDebugFunc qdbusThreadDebug = 0;
#endif
-typedef void (*QDBusSpyHook)(const QDBusMessage&);
-typedef QVarLengthArray<QDBusSpyHook, 4> QDBusSpyHookList;
+typedef QVarLengthArray<QDBusSpyCallEvent::Hook, 4> QDBusSpyHookList;
Q_GLOBAL_STATIC(QDBusSpyHookList, qDBusSpyHookList)
extern "C" {
@@ -467,12 +466,29 @@ static QStringList matchArgsForService(const QString &service, QDBusServiceWatch
}
-extern Q_DBUS_EXPORT void qDBusAddSpyHook(QDBusSpyHook);
-void qDBusAddSpyHook(QDBusSpyHook hook)
+extern Q_DBUS_EXPORT void qDBusAddSpyHook(QDBusSpyCallEvent::Hook);
+void qDBusAddSpyHook(QDBusSpyCallEvent::Hook hook)
{
qDBusSpyHookList()->append(hook);
}
+QDBusSpyCallEvent::~QDBusSpyCallEvent()
+{
+ // Reinsert the message into the processing queue for the connection.
+ // This is done in the destructor so the message is reinserted even if
+ // QCoreApplication is destroyed.
+ QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(const_cast<QObject *>(sender()));
+ qDBusDebug() << d << "message spies done for" << msg;
+ emit d->spyHooksFinished(msg);
+}
+
+void QDBusSpyCallEvent::placeMetaCall(QObject *)
+{
+ // call the spy hook list
+ for (int i = 0; i < hookCount; ++i)
+ hooks[i](msg);
+}
+
extern "C" {
static DBusHandlerResult
qDBusSignalFilter(DBusConnection *connection, DBusMessage *message, void *data)
@@ -494,16 +510,11 @@ qDBusSignalFilter(DBusConnection *connection, DBusMessage *message, void *data)
bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
{
- const QDBusSpyHookList *list = qDBusSpyHookList();
- for (int i = 0; list && i < list->size(); ++i) {
- qDBusDebug() << "calling the message spy hook";
- (*(*list)[i])(amsg);
- }
-
if (!ref.load())
return false;
if (!dispatchEnabled && !QDBusMessagePrivate::isLocal(amsg)) {
// queue messages only, we'll handle them later
+ qDBusDebug() << this << "delivery is suspended";
pendingMessages << amsg;
return amsg.type() == QDBusMessage::MethodCallMessage;
}
@@ -515,6 +526,15 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
// let them see the signal too
return false;
case QDBusMessage::MethodCallMessage:
+ // run it through the spy filters (if any) before the regular processing
+ if (Q_UNLIKELY(qDBusSpyHookList.exists()) && qApp) {
+ const QDBusSpyHookList &list = *qDBusSpyHookList;
+ qDBusDebug() << this << "invoking message spies";
+ QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this),
+ amsg, list.constData(), list.size()));
+ return true;
+ }
+
handleObjectCall(amsg);
return true;
case QDBusMessage::ReplyMessage:
@@ -986,6 +1006,8 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
QDBusMetaTypeId::init();
connect(this, &QDBusConnectionPrivate::dispatchStatusChanged,
this, &QDBusConnectionPrivate::doDispatch, Qt::QueuedConnection);
+ connect(this, &QDBusConnectionPrivate::spyHooksFinished,
+ this, &QDBusConnectionPrivate::handleObjectCall, Qt::QueuedConnection);
connect(this, &QDBusConnectionPrivate::messageNeedsSending,
this, &QDBusConnectionPrivate::sendInternal);
connect(this, &QDBusConnectionPrivate::signalNeedsConnecting,
@@ -1097,8 +1119,10 @@ void QDBusConnectionPrivate::doDispatch()
// dispatch previously queued messages
PendingMessageList::Iterator it = pendingMessages.begin();
PendingMessageList::Iterator end = pendingMessages.end();
- for ( ; it != end; ++it)
+ for ( ; it != end; ++it) {
+ qDBusDebug() << this << "dequeueing message" << *it;
handleMessage(qMove(*it));
+ }
pendingMessages.clear();
}
}
diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h
index 90ae1fc6a6..89043148e3 100644
--- a/src/dbus/qdbusintegrator_p.h
+++ b/src/dbus/qdbusintegrator_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtDBus module of the Qt Toolkit.
@@ -71,6 +72,7 @@
QT_BEGIN_NAMESPACE
class QDBusConnectionPrivate;
+class QDBusMessage;
// Really private structs used by qdbusintegrator.cpp
// Things that aren't used by any other file
@@ -139,6 +141,23 @@ private:
bool handled;
};
+class QDBusSpyCallEvent : public QMetaCallEvent
+{
+public:
+ typedef void (*Hook)(const QDBusMessage&);
+ QDBusSpyCallEvent(QDBusConnectionPrivate *cp, const QDBusConnection &c, const QDBusMessage &msg,
+ const Hook *hooks, int count)
+ : QMetaCallEvent(0, 0, Q_NULLPTR, cp, 0), conn(c), msg(msg), hooks(hooks), hookCount(count)
+ {}
+ ~QDBusSpyCallEvent();
+ void placeMetaCall(QObject *) Q_DECL_OVERRIDE;
+
+ QDBusConnection conn; // keeps the refcount in QDBusConnectionPrivate up
+ QDBusMessage msg;
+ const Hook *hooks;
+ int hookCount;
+};
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusSlotCache)