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; typedef TQMap<DBusPendingCall*, TQT_DBusPendingCall*> PendingCallMap;
PendingCallMap pendingCalls; PendingCallMap pendingCalls;
typedef TQValueList<TQT_DBusMessage> PendingMessagesForEmit;
PendingMessagesForEmit pendingMessages;
bool inDispatch;
}; };
#endif #endif

@ -273,7 +273,7 @@ int TQT_DBusConnectionPrivate::registerMessageMetaType()
TQT_DBusConnectionPrivate::TQT_DBusConnectionPrivate(TQObject *parent) TQT_DBusConnectionPrivate::TQT_DBusConnectionPrivate(TQObject *parent)
: TQObject(parent), ref(1), mode(InvalidMode), connection(0), server(0), : TQObject(parent), ref(1), mode(InvalidMode), connection(0), server(0),
dispatcher(0) dispatcher(0), inDispatch(false)
{ {
static const int msgType = registerMessageMetaType(); static const int msgType = registerMessageMetaType();
Q_UNUSED(msgType); Q_UNUSED(msgType);
@ -452,6 +452,13 @@ void TQT_DBusConnectionPrivate::scheduleDispatch()
void TQT_DBusConnectionPrivate::dispatch() 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 (mode == ClientMode)
{ {
if (dbus_connection_dispatch(connection) != DBUS_DISPATCH_DATA_REMAINS) if (dbus_connection_dispatch(connection) != DBUS_DISPATCH_DATA_REMAINS)
@ -460,6 +467,15 @@ void TQT_DBusConnectionPrivate::dispatch()
dispatcher->stop(); 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) bool TQT_DBusConnectionPrivate::handleObjectCall(DBusMessage *message)
@ -481,7 +497,11 @@ bool TQT_DBusConnectionPrivate::handleSignal(DBusMessage *message)
// FIXME-QT4 // FIXME-QT4
//return handleSignal(TQString(), msg) | handleSignal(msg.path(), msg); //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; return true;
} }

Loading…
Cancel
Save