summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-11-19 08:57:18 (GMT)
committerOlivier Goffart <olivier.goffart@nokia.com>2010-11-22 09:24:34 (GMT)
commit202433ee1fd377ac36dc55fb466b9fc616b4d4fd (patch)
treeaa861dba129b686868ac58e01371a851c630a754
parent98337a5f32e58c0ea14e2b86b9fe8dcb22bfa4e3 (diff)
downloadQt-202433ee1fd377ac36dc55fb466b9fc616b4d4fd.zip
Qt-202433ee1fd377ac36dc55fb466b9fc616b4d4fd.tar.gz
Qt-202433ee1fd377ac36dc55fb466b9fc616b4d4fd.tar.bz2
QThread::exec(): Fix possibility to enter several time the event loop
If one call exit() before calling exec(), this should prevent the event loop from starting once, but later calls to exec() should work. This is a regression against Qt 4.6 introduced when fixing QTBUG-1184 Task-number: QTBUG-15378 Reviewed-by: Joao Reviewed-by: Brad
-rw-r--r--src/corelib/thread/qthread.cpp4
-rw-r--r--tests/auto/qthread/tst_qthread.cpp40
2 files changed, 43 insertions, 1 deletions
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 69b70cb..6fb182b 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -482,8 +482,10 @@ int QThread::exec()
Q_D(QThread);
QMutexLocker locker(&d->mutex);
d->data->quitNow = false;
- if (d->exited)
+ if (d->exited) {
+ d->exited = false;
return d->returnCode;
+ }
locker.unlock();
QEventLoop eventLoop;
diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp
index 843749a..85b8f04 100644
--- a/tests/auto/qthread/tst_qthread.cpp
+++ b/tests/auto/qthread/tst_qthread.cpp
@@ -106,6 +106,7 @@ private slots:
void adoptMultipleThreads();
void QTBUG13810_exitAndStart();
+ void QTBUG15378_exitAndExec();
void stressTest();
};
@@ -976,5 +977,44 @@ void tst_QThread::QTBUG13810_exitAndStart()
}
+void tst_QThread::QTBUG15378_exitAndExec()
+{
+ class Thread : public QThread {
+ public:
+ QSemaphore sem1;
+ QSemaphore sem2;
+ volatile int value;
+ void run() {
+ sem1.acquire();
+ value = exec(); //First entrence
+ sem2.release();
+ value = exec(); // Second loop
+ }
+ };
+ Thread thread;
+ thread.value = 0;
+ thread.start();
+ thread.exit(556);
+ thread.sem1.release(); //should exit the first loop
+ thread.sem2.acquire();
+ QCOMPARE(int(thread.value), 556);
+
+ //test that the thread is running by executing queued connected signal there
+ Syncronizer sync1;
+ sync1.moveToThread(&thread);
+ Syncronizer sync2;
+ sync2.moveToThread(&thread);
+ connect(&sync2, SIGNAL(propChanged(int)), &sync1, SLOT(setProp(int)), Qt::QueuedConnection);
+ connect(&sync1, SIGNAL(propChanged(int)), &thread, SLOT(quit()), Qt::QueuedConnection);
+ QMetaObject::invokeMethod(&sync2, "setProp", Qt::QueuedConnection , Q_ARG(int, 89));
+ QTest::qWait(50);
+ while(!thread.wait(10))
+ QTest::qWait(10);
+ QCOMPARE(sync2.m_prop, 89);
+ QCOMPARE(sync1.m_prop, 89);
+}
+
+
+
QTEST_MAIN(tst_QThread)
#include "tst_qthread.moc"