diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-11-24 14:32:23 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-11-24 15:02:36 (GMT) |
commit | 25c9b6ed488b1446cbdd38186992957264596314 (patch) | |
tree | 75eb8d69df9bd07f93dd1a75dd7d014486b11bd6 /tests/auto/qthread | |
parent | 68e5673bb1ca080bbaf5cf7198fcf2deafa60772 (diff) | |
download | Qt-25c9b6ed488b1446cbdd38186992957264596314.zip Qt-25c9b6ed488b1446cbdd38186992957264596314.tar.gz Qt-25c9b6ed488b1446cbdd38186992957264596314.tar.bz2 |
QThread: fix a race condition when destroying or restarting thread from finished()
Since we do not keep the mutex locked in QThreadPrivate::finish,
We could have races if the thread is destroyed or restarted from
another thread while we are still in that function
This solve tst_QCoreApplication::deliverInDefinedOrder on mac
Regression since a43583e0221311b7fe666726a
Reviewed-by: Brad
Diffstat (limited to 'tests/auto/qthread')
-rw-r--r-- | tests/auto/qthread/tst_qthread.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp index 1e14b6a..01f080f 100644 --- a/tests/auto/qthread/tst_qthread.cpp +++ b/tests/auto/qthread/tst_qthread.cpp @@ -109,6 +109,8 @@ private slots: void connectThreadFinishedSignalToObjectDeleteLaterSlot(); void wait2(); void wait3_slowDestructor(); + void destroyFinishRace(); + void startFinishRace(); void stressTest(); }; @@ -1067,5 +1069,49 @@ void tst_QThread::wait3_slowDestructor() QVERIFY(thread.wait(one_minute)); } +void tst_QThread::destroyFinishRace() +{ + class Thread : public QThread { void run() {} }; + for (int i = 0; i < 15; i++) { + Thread *thr = new Thread; + connect(thr, SIGNAL(finished()), thr, SLOT(deleteLater())); + QWeakPointer<QThread> weak(static_cast<QThread*>(thr)); + thr->start(); + while (weak) { + qApp->processEvents(); + qApp->processEvents(); + qApp->processEvents(); + qApp->processEvents(); + } + } +} + +void tst_QThread::startFinishRace() +{ + class Thread : public QThread { + public: + Thread() : i (50) {} + void run() { + i--; + if (!i) disconnect(this, SIGNAL(finished()), 0, 0); + } + int i; + }; + for (int i = 0; i < 15; i++) { + Thread thr; + connect(&thr, SIGNAL(finished()), &thr, SLOT(start())); + thr.start(); + while (!thr.isFinished() || thr.i != 0) { + qApp->processEvents(); + qApp->processEvents(); + qApp->processEvents(); + qApp->processEvents(); + } + QCOMPARE(thr.i, 0); + } +} + + + QTEST_MAIN(tst_QThread) #include "tst_qthread.moc" |