Fix long-standing intermittent bug whereby an application using dbus-1-tqt would randomly hang after many hours of continuous operation

pull/2/head
Timothy Pearson 12 years ago
parent 2c0058457d
commit 545c32d8e9

@ -144,6 +144,11 @@ public:
};
typedef TQMap<DBusPendingCall*, TQT_DBusPendingCall*> PendingCallMap;
PendingCallMap pendingCalls;
typedef TQValueList<TQT_DBusMessage> PendingMessagesForEmit;
PendingMessagesForEmit pendingMessages;
bool inDispatch;
};
#endif

@ -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;
}

Loading…
Cancel
Save