QThread::isFinished should return true from finished()

and isRunning() should return false.

This restore the Qt 4.7 behaviour

In Qt 4.7, the finished() was called with the thread's intenal mutex
locked. Which mean that:
 - Call to isRunning or isFinished called from a slot connected to
   finish within the thread would deadlock. (Hence no compatibility
   to keep here)
 - Call to isRunning or isFinished from a slot connected with
   QueuedConnection in another thread would lock the mutex until
   the destructors are finished. and then return as if the thread have
   finished.

Change-Id: I963eccae8f7634aff90cc4bbab6ca886a78e35eb
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Olivier Goffart 2011-11-03 14:11:34 +01:00 committed by Qt by Nokia
parent 1fe8fb81b1
commit ec5e59b73c
2 changed files with 36 additions and 2 deletions

View File

@ -422,7 +422,7 @@ bool QThread::isFinished() const
{
Q_D(const QThread);
QMutexLocker locker(&d->mutex);
return d->finished;
return d->finished || d->isInFinish;
}
/*!
@ -434,7 +434,7 @@ bool QThread::isRunning() const
{
Q_D(const QThread);
QMutexLocker locker(&d->mutex);
return d->running;
return d->running && !d->isInFinish;
}
/*!

View File

@ -111,6 +111,7 @@ private slots:
void destroyFinishRace();
void startFinishRace();
void startAndQuitCustomEventLoop();
void isRunningInFinished();
#ifndef Q_OS_WINCE
void stressTest();
@ -1199,6 +1200,39 @@ void tst_QThread::startAndQuitCustomEventLoop()
}
}
class FinishedTestObject : public QObject {
Q_OBJECT
public:
FinishedTestObject() : ok(false) {}
bool ok;
public slots:
void slotFinished() {
QThread *t = qobject_cast<QThread *>(sender());
ok = t && t->isFinished() && !t->isRunning();
}
};
void tst_QThread::isRunningInFinished()
{
for (int i = 0; i < 15; i++) {
QThread thread;
thread.start();
FinishedTestObject localObject;
FinishedTestObject inThreadObject;
localObject.setObjectName("...");
inThreadObject.moveToThread(&thread);
connect(&thread, SIGNAL(finished()), &localObject, SLOT(slotFinished()));
connect(&thread, SIGNAL(finished()), &inThreadObject, SLOT(slotFinished()));
QEventLoop loop;
connect(&thread, SIGNAL(finished()), &loop, SLOT(quit()));
QMetaObject::invokeMethod(&thread, "quit", Qt::QueuedConnection);
loop.exec();
QVERIFY(!thread.isRunning());
QVERIFY(thread.isFinished());
QVERIFY(localObject.ok);
QVERIFY(inThreadObject.ok);
}
}
QTEST_MAIN(tst_QThread)
#include "tst_qthread.moc"