summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-11-04 14:52:12 (GMT)
committerOlivier Goffart <olivier.goffart@nokia.com>2010-11-22 14:09:07 (GMT)
commita43583e0221311b7fe666726ab668e41c5e4bba2 (patch)
tree1a3a2db7a834c35b0b0c6e511e06193b95c95dbc /tests/auto
parent5e13c65b7083ba6a28820a82f2fa19ca8c1569b0 (diff)
downloadQt-a43583e0221311b7fe666726ab668e41c5e4bba2.zip
Qt-a43583e0221311b7fe666726ab668e41c5e4bba2.tar.gz
Qt-a43583e0221311b7fe666726ab668e41c5e4bba2.tar.bz2
QThreadPrivate::finish should not keep mutex locked when calling signals
This fix the deadlock shown in the new test wait3_slowDestructor Add a test for QThread::wait(timeout) Task-number: QTBUG-15030 Reviewed-by: Joao Reviewed-by: Brad
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/qthread/tst_qthread.cpp77
1 files changed, 77 insertions, 0 deletions
diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp
index f290a2b..49c3576 100644
--- a/tests/auto/qthread/tst_qthread.cpp
+++ b/tests/auto/qthread/tst_qthread.cpp
@@ -107,6 +107,8 @@ private slots:
void QTBUG13810_exitAndStart();
void connectThreadFinishedSignalToObjectDeleteLaterSlot();
+ void wait2();
+ void wait3_slowDestructor();
void stressTest();
};
@@ -976,6 +978,7 @@ void tst_QThread::QTBUG13810_exitAndStart()
QCOMPARE(sync1.m_prop, 89);
}
+
void tst_QThread::connectThreadFinishedSignalToObjectDeleteLaterSlot()
{
QThread thread;
@@ -990,5 +993,79 @@ void tst_QThread::connectThreadFinishedSignalToObjectDeleteLaterSlot()
QVERIFY(p.isNull());
}
+class Waiting_Thread : public QThread
+{
+public:
+ enum { WaitTime = 800 };
+ QMutex mutex;
+ QWaitCondition cond1;
+ QWaitCondition cond2;
+
+ void run()
+ {
+ QMutexLocker locker(&mutex);
+ cond1.wait(&mutex);
+ cond2.wait(&mutex, WaitTime);
+ }
+};
+
+void tst_QThread::wait2()
+{
+ QElapsedTimer timer;
+ Waiting_Thread thread;
+ thread.start();
+ timer.start();
+ QVERIFY(!thread.wait(Waiting_Thread::WaitTime));
+ qint64 elapsed = timer.elapsed();
+
+ QVERIFY(elapsed >= Waiting_Thread::WaitTime);
+ //QVERIFY(elapsed < Waiting_Thread::WaitTime * 1.4);
+
+ timer.start();
+ thread.cond1.wakeOne();
+ QVERIFY(thread.wait(/*Waiting_Thread::WaitTime * 1.4*/));
+ elapsed = timer.elapsed();
+ QVERIFY(elapsed >= Waiting_Thread::WaitTime);
+ //QVERIFY(elapsed < Waiting_Thread::WaitTime * 1.4);
+}
+
+
+class SlowSlotObject : public QObject {
+ Q_OBJECT
+public:
+ QMutex mutex;
+ QWaitCondition cond;
+public slots:
+ void slowSlot() {
+ QMutexLocker locker(&mutex);
+ cond.wait(&mutex);
+ }
+};
+
+void tst_QThread::wait3_slowDestructor()
+{
+ SlowSlotObject slow;
+ QThread thread;
+ QObject::connect(&thread, SIGNAL(finished()), &slow, SLOT(slowSlot()), Qt::DirectConnection);
+
+ enum { WaitTime = 1800 };
+ QElapsedTimer timer;
+
+ thread.start();
+ thread.quit();
+ //the quit function will cause the thread to finish and enter the slowSlot that is blocking
+
+ timer.start();
+ QVERIFY(!thread.wait(Waiting_Thread::WaitTime));
+ qint64 elapsed = timer.elapsed();
+
+ QVERIFY(elapsed >= Waiting_Thread::WaitTime);
+ //QVERIFY(elapsed < Waiting_Thread::WaitTime * 1.4);
+
+ slow.cond.wakeOne();
+ //now the thread shoud finish quickly
+ QVERIFY(thread.wait(one_minute));
+}
+
QTEST_MAIN(tst_QThread)
#include "tst_qthread.moc"