From d27b19612cb9f21ff64b23bdc1ab2b0341240910 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Thu, 29 Nov 2012 01:04:37 -0600 Subject: Fix event queue (cherry picked from commit ede17586a14715351cce7e249a4f372e497c0fd2) --- tqdbusconnection_p.h | 23 +++++++++++++++++++++++ tqdbusintegrator.cpp | 51 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/tqdbusconnection_p.h b/tqdbusconnection_p.h index aaa8d88..829be19 100644 --- a/tqdbusconnection_p.h +++ b/tqdbusconnection_p.h @@ -47,6 +47,7 @@ #include "tqdbusatomic.h" #include "tqdbuserror.h" #include "tqdbusobject.h" +#include "tqdbusmessage.h" class TQT_DBusMessage; class TQSocketNotifier; @@ -56,6 +57,15 @@ class TQTimerEvent; struct DBusConnection; struct DBusServer; +class TQT_DBusResultInfo +{ + public: + TQT_DBusMessage message; + TQObject* receiver; + TQCString method; +}; +typedef TQValueList TQT_DBusResultInfoList; + class TQT_DBusConnectionPrivate: public TQObject { Q_OBJECT @@ -149,6 +159,19 @@ public: PendingMessagesForEmit pendingMessages; bool inDispatch; + + TQT_DBusResultInfoList m_resultEmissionQueue; + +public: + void newMethodInResultEmissionQueue(); + +private slots: + void transmitResultEmissionQueue(); + void transmitMessageEmissionQueue(); + +private: + TQTimer* m_resultEmissionQueueTimer; + TQTimer* m_messageEmissionQueueTimer; }; #endif diff --git a/tqdbusintegrator.cpp b/tqdbusintegrator.cpp index 81cb8df..ef3b76f 100644 --- a/tqdbusintegrator.cpp +++ b/tqdbusintegrator.cpp @@ -282,6 +282,11 @@ TQT_DBusConnectionPrivate::TQT_DBusConnectionPrivate(TQObject *parent) dispatcher = new TQTimer(this); TQObject::connect(dispatcher, TQT_SIGNAL(timeout()), this, TQT_SLOT(dispatch())); + + m_resultEmissionQueueTimer = new TQTimer(this); + TQObject::connect(m_resultEmissionQueueTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(transmitResultEmissionQueue())); + m_messageEmissionQueueTimer = new TQTimer(this); + TQObject::connect(m_messageEmissionQueueTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(transmitMessageEmissionQueue())); } TQT_DBusConnectionPrivate::~TQT_DBusConnectionPrivate() @@ -469,11 +474,15 @@ void TQT_DBusConnectionPrivate::dispatch() } inDispatch = false; +} - for (TQT_DBusConnectionPrivate::PendingMessagesForEmit::iterator pmfe = pendingMessages.begin(); pmfe != pendingMessages.end(); ++pmfe) { +void TQT_DBusConnectionPrivate::transmitMessageEmissionQueue() +{ + TQT_DBusConnectionPrivate::PendingMessagesForEmit::iterator pmfe; + pmfe = pendingMessages.begin(); + while (pmfe != pendingMessages.end()) { TQT_DBusMessage msg = *pmfe; - pendingMessages.remove(pmfe); - pmfe = pendingMessages.begin(); + pmfe = pendingMessages.remove(pmfe); dbusSignal(msg); } } @@ -501,6 +510,7 @@ bool TQT_DBusConnectionPrivate::handleSignal(DBusMessage *message) // which could result in arbitrary methods being called while still inside dbus_connection_dispatch. // Instead, I enqueue the messages here for TQt3 event loop transmission after dbus_connection_dispatch is finished. pendingMessages.append(msg); + if (!m_messageEmissionQueueTimer->isActive()) m_messageEmissionQueueTimer->start(0, TRUE); return true; } @@ -590,13 +600,12 @@ static void qDBusResultReceived(DBusPendingCall *pending, void *user_data) { TQT_DBusMessage reply = TQT_DBusMessage::fromDBusMessage(dbusReply); - TQObject::connect(d, TQT_SIGNAL(dbusPendingCallReply(const TQT_DBusMessage&)), - it.data()->receiver, it.data()->method.data()); - - d->emitPendingCallReply(reply); - - TQObject::disconnect(d, TQT_SIGNAL(dbusPendingCallReply(const TQT_DBusMessage&)), - it.data()->receiver, it.data()->method.data()); + TQT_DBusResultInfo dbusResult; + dbusResult.message = reply; + dbusResult.receiver = it.data()->receiver; + dbusResult.method = it.data()->method.data(); + d->m_resultEmissionQueue.append(dbusResult); + d->newMethodInResultEmissionQueue(); } dbus_message_unref(dbusReply); @@ -643,4 +652,26 @@ void TQT_DBusConnectionPrivate::flush() dbus_connection_flush(connection); } +void TQT_DBusConnectionPrivate::newMethodInResultEmissionQueue() +{ + if (!m_resultEmissionQueueTimer->isActive()) m_resultEmissionQueueTimer->start(0, TRUE); +} + +void TQT_DBusConnectionPrivate::transmitResultEmissionQueue() +{ + if (!m_resultEmissionQueue.isEmpty()) { + TQT_DBusResultInfoList::Iterator it; + it = m_resultEmissionQueue.begin(); + while (it != m_resultEmissionQueue.end()) { + TQT_DBusResultInfo dbusResult = (*it); + m_resultEmissionQueue.remove(it); + it = m_resultEmissionQueue.begin(); + + TQObject::connect(this, TQT_SIGNAL(dbusPendingCallReply(const TQT_DBusMessage&)), dbusResult.receiver, dbusResult.method.data()); + emitPendingCallReply(dbusResult.message); + TQObject::disconnect(this, TQT_SIGNAL(dbusPendingCallReply(const TQT_DBusMessage&)), dbusResult.receiver, dbusResult.method.data()); + } + } +} + #include "tqdbusconnection_p.moc" -- cgit v1.2.3