--- qt-opensource-4.8.0.old/src/corelib/kernel/qobject.cpp 2011-12-08 00:06:03.000000000 -0500 +++ qt-opensource-4.8.0.new/src/corelib/kernel/qobject.cpp 2011-12-30 01:28:29.339975365 -0500 @@ -69,6 +69,16 @@ QT_BEGIN_NAMESPACE +class QScopedLoopLevelIncrementer { + QThreadData *threadData; +public: + QScopedLoopLevelIncrementer(QThreadData *threadData) + : threadData(threadData) + { ++threadData->loopLevel; } + ~QScopedLoopLevelIncrementer() + { --threadData->loopLevel; } +}; + static int DIRECT_CONNECTION_ONLY = 0; static int *queuedConnectionTypes(const QList &typeNames) @@ -841,6 +851,15 @@ QObject::~QObject() if (d->isSignalConnected(0)) { QT_TRY { + // There exist cases where one connects the destroyed() signal to a slot + // in which deleteLater() calls are made or triggered. In such cases, as + // deleteLater() calls are not processed until the (event) loopLevel drops + // below the current level (which is often (always?) 1 here), the deferred + // deletions may not be done until the application exits. To have such + // deleteLater() calls processed in a reasonably timely manner from the + // the main event loop, temporarily increase the loopLevel here specifically + // for the destroyed() signal call. + QScopedLoopLevelIncrementer loopLevelIncrementer(d_func()->threadData); emit destroyed(this); } QT_CATCH(...) { // all the signal/slots connections are still in place - if we don't