diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-11-26 12:19:30 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-11-26 12:19:30 -0600 |
commit | 545c32d8e94199bf5d1c44035016dab7320e9cf6 (patch) | |
tree | b0d54cd986f55c430108a170ec81f9a4091bc5a6 | |
parent | 2c0058457d080cca6fccd1a9f7daaafb3a0e2e51 (diff) | |
download | dbus-1-tqt-545c32d8e94199bf5d1c44035016dab7320e9cf6.tar.gz dbus-1-tqt-545c32d8e94199bf5d1c44035016dab7320e9cf6.zip |
Fix long-standing intermittent bug whereby an application using dbus-1-tqt would randomly hang after many hours of continuous operation
-rw-r--r-- | tqdbusconnection_p.h | 5 | ||||
-rw-r--r-- | tqdbusintegrator.cpp | 24 |
2 files changed, 27 insertions, 2 deletions
diff --git a/tqdbusconnection_p.h b/tqdbusconnection_p.h index cf64c2c..97537f0 100644 --- a/tqdbusconnection_p.h +++ b/tqdbusconnection_p.h @@ -144,6 +144,11 @@ public: }; typedef TQMap<DBusPendingCall*, TQT_DBusPendingCall*> PendingCallMap; PendingCallMap pendingCalls; + + typedef TQValueList<TQT_DBusMessage> PendingMessagesForEmit; + PendingMessagesForEmit pendingMessages; + + bool inDispatch; }; #endif diff --git a/tqdbusintegrator.cpp b/tqdbusintegrator.cpp index 373e4a0..55af1e0 100644 --- a/tqdbusintegrator.cpp +++ b/tqdbusintegrator.cpp @@ -273,7 +273,7 @@ int TQT_DBusConnectionPrivate::registerMessageMetaType() TQT_DBusConnectionPrivate::TQT_DBusConnectionPrivate(TQObject *parent) : TQObject(parent), ref(1), mode(InvalidMode), connection(0), server(0), - dispatcher(0) + dispatcher(0), inDispatch(false) { static const int msgType = registerMessageMetaType(); Q_UNUSED(msgType); @@ -452,6 +452,13 @@ void TQT_DBusConnectionPrivate::scheduleDispatch() void TQT_DBusConnectionPrivate::dispatch() { + // dbus_connection_dispatch will hang if called recursively + if (inDispatch) { + printf("[dbus-1-tqt] WARNING: Attempt to call dispatch() recursively was silently ignored to prevent lockup!\n\r"); fflush(stdout); + return; + } + inDispatch = true; + if (mode == ClientMode) { if (dbus_connection_dispatch(connection) != DBUS_DISPATCH_DATA_REMAINS) @@ -460,6 +467,15 @@ void TQT_DBusConnectionPrivate::dispatch() dispatcher->stop(); } } + + inDispatch = false; + + for (TQT_DBusConnectionPrivate::PendingMessagesForEmit::iterator pmfe = pendingMessages.begin(); pmfe != pendingMessages.end(); ++pmfe) { + TQT_DBusMessage msg = *pmfe; + pendingMessages.remove(pmfe); + pmfe = pendingMessages.begin(); + dbusSignal(msg); + } } bool TQT_DBusConnectionPrivate::handleObjectCall(DBusMessage *message) @@ -481,7 +497,11 @@ bool TQT_DBusConnectionPrivate::handleSignal(DBusMessage *message) // FIXME-QT4 //return handleSignal(TQString(), msg) | handleSignal(msg.path(), msg); - dbusSignal(msg); + // If dbusSignal(msg) were called here, it could easily cause a lockup as it would enter the TQt3 event loop, + // 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); + return true; } |