summaryrefslogtreecommitdiffstats
path: root/src/dbus
diff options
context:
space:
mode:
Diffstat (limited to 'src/dbus')
-rw-r--r--src/dbus/dbus.pro4
-rw-r--r--src/dbus/qdbusconnection.cpp4
-rw-r--r--src/dbus/qdbusintegrator.cpp44
-rw-r--r--src/dbus/qdbusintegrator_p.h1
4 files changed, 38 insertions, 15 deletions
diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro
index ebeab5c1b0..4c1aec7bb3 100644
--- a/src/dbus/dbus.pro
+++ b/src/dbus/dbus.pro
@@ -25,8 +25,6 @@ win32 {
QMAKE_DOCS = $$PWD/doc/qtdbus.qdocconf
-load(qt_module)
-
PUB_HEADERS = qdbusargument.h \
qdbusconnectioninterface.h \
qdbusmacros.h \
@@ -91,3 +89,5 @@ SOURCES += qdbusconnection.cpp \
qdbusservicewatcher.cpp \
qdbusunixfiledescriptor.cpp \
qdbusvirtualobject.cpp
+
+load(qt_module)
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 3f2e80cdac..ea8c2b0311 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -214,7 +214,7 @@ QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(QDBusConnection::Bu
data.suspendedDelivery = suspendedDelivery;
emit connectionRequested(&data);
- if (suspendedDelivery) {
+ if (suspendedDelivery && data.result->connection) {
data.result->ref.ref();
QDBusConnectionDispatchEnabler *o = new QDBusConnectionDispatchEnabler(data.result);
QTimer::singleShot(0, o, SLOT(execute()));
@@ -297,7 +297,7 @@ void QDBusConnectionManager::executeConnectionRequest(QDBusConnectionManager::Co
// will lock in QDBusConnectionPrivate::connectRelay()
d->setConnection(c, error);
d->createBusService();
- if (data->suspendedDelivery)
+ if (c && data->suspendedDelivery)
d->setDispatchEnabled(false);
}
}
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 25678a56a9..105714ee64 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -487,6 +487,11 @@ QDBusSpyCallEvent::~QDBusSpyCallEvent()
void QDBusSpyCallEvent::placeMetaCall(QObject *)
{
+ invokeSpyHooks(msg, hooks, hookCount);
+}
+
+inline void QDBusSpyCallEvent::invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount)
+{
// call the spy hook list
for (int i = 0; i < hookCount; ++i)
hooks[i](msg);
@@ -515,7 +520,12 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
{
if (!ref.load())
return false;
- if (!dispatchEnabled && !QDBusMessagePrivate::isLocal(amsg)) {
+
+ // local message are always delivered, regardless of filtering
+ // or whether the dispatcher is enabled
+ bool isLocal = QDBusMessagePrivate::isLocal(amsg);
+
+ if (!dispatchEnabled && !isLocal) {
// queue messages only, we'll handle them later
qDBusDebug() << this << "delivery is suspended";
pendingMessages << amsg;
@@ -529,13 +539,23 @@ 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
+ // run it through the spy filters (if any) before the regular processing:
+ // a) if it's a local message, we're in the caller's thread, so invoke the filter directly
+ // b) if it's an external message, post to the main thread
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;
+ if (isLocal) {
+ Q_ASSERT(QThread::currentThread() != thread());
+ qDBusDebug() << this << "invoking message spies directly";
+ QDBusSpyCallEvent::invokeSpyHooks(amsg, list.constData(), list.size());
+ } else {
+ qDBusDebug() << this << "invoking message spies via event";
+ QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this),
+ amsg, list.constData(), list.size()));
+
+ // we'll be called back, so return
+ return true;
+ }
}
handleObjectCall(amsg);
@@ -1456,9 +1476,9 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
// that means the dispatchLock mutex is locked
// must not call out to user code in that case
//
- // however, if the message is internal, handleMessage was called
- // directly and no lock is in place. We can therefore call out to
- // user code, if necessary
+ // however, if the message is internal, handleMessage was called directly
+ // (user's thread) and no lock is in place. We can therefore call out to
+ // user code, if necessary.
ObjectTreeNode result;
int usedLength;
QThread *objThread = 0;
@@ -1497,12 +1517,14 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
usedLength, msg));
return;
} else if (objThread != QThread::currentThread()) {
- // synchronize with other thread
+ // looped-back message, targeting another thread:
+ // synchronize with it
postEventToThread(HandleObjectCallPostEventAction, result.obj,
new QDBusActivateObjectEvent(QDBusConnection(this), this, result,
usedLength, msg, &sem));
semWait = true;
} else {
+ // looped-back message, targeting current thread
semWait = false;
}
} // release the lock
@@ -1796,7 +1818,7 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
if (e)
connection->postEventToThread(MessageResultReceivedAction, call->receiver, e);
else
- qDBusDebug() << "Deliver failed!";
+ qDBusDebug("Deliver failed!");
}
if (call->pending) {
diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h
index 89043148e3..470baeb692 100644
--- a/src/dbus/qdbusintegrator_p.h
+++ b/src/dbus/qdbusintegrator_p.h
@@ -151,6 +151,7 @@ public:
{}
~QDBusSpyCallEvent();
void placeMetaCall(QObject *) Q_DECL_OVERRIDE;
+ static inline void invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount);
QDBusConnection conn; // keeps the refcount in QDBusConnectionPrivate up
QDBusMessage msg;