diff options
Diffstat (limited to 'src/dbus')
-rw-r--r-- | src/dbus/dbus.pro | 4 | ||||
-rw-r--r-- | src/dbus/qdbusconnection.cpp | 4 | ||||
-rw-r--r-- | src/dbus/qdbusintegrator.cpp | 44 | ||||
-rw-r--r-- | src/dbus/qdbusintegrator_p.h | 1 |
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; |