diff options
author | mread <qt-info@nokia.com> | 2011-02-17 13:07:51 (GMT) |
---|---|---|
committer | mread <qt-info@nokia.com> | 2011-03-09 12:47:22 (GMT) |
commit | c5a462519a8bce0faa31ce41414022749e3ad2f5 (patch) | |
tree | 381bb17971f6860277b6f98ef10a3f243caf8e63 | |
parent | 04510ff7b065b27f2a80f2cbf42cb097c98923b0 (diff) | |
download | Qt-c5a462519a8bce0faa31ce41414022749e3ad2f5.zip Qt-c5a462519a8bce0faa31ce41414022749e3ad2f5.tar.gz Qt-c5a462519a8bce0faa31ce41414022749e3ad2f5.tar.bz2 |
Symbian adopted thread monitor review fixes
The adopted thread monitor could cause a stray event panic if multiple
threads where added quickly. A new autotest was written to force the
fault (successfully). A fix was then added.
Task-number: QTBUG-13990
Reviewed-by: Shane Kearns
-rw-r--r-- | src/corelib/thread/qthread_symbian.cpp | 8 | ||||
-rw-r--r-- | tests/auto/qthread/tst_qthread.cpp | 44 |
2 files changed, 48 insertions, 4 deletions
diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp index 4bbf5e3..096cd6d 100644 --- a/src/corelib/thread/qthread_symbian.cpp +++ b/src/corelib/thread/qthread_symbian.cpp @@ -161,13 +161,13 @@ public: } void DoCancel() { - TRequestStatus *stat = &iStatus; User::RequestComplete(stat, KErrCancel); } void start() { iStatus = KRequestPending; SetActive(); + stat = &iStatus; } void RunL() { @@ -195,9 +195,8 @@ public: monitorThread.Close(); } adoptedThreadAdder->threadsToAdd.push_back(thread); - if (adoptedThreadAdder->IsActive()) { - TRequestStatus *stat = &adoptedThreadAdder->iStatus; - adoptedThreadAdder->monitorThread.RequestComplete(stat, KErrNone); + if (adoptedThreadAdder->stat) { + adoptedThreadAdder->monitorThread.RequestComplete(adoptedThreadAdder->stat, KErrNone); } } static void monitorThreadFuncL() @@ -232,6 +231,7 @@ private: RThread monitorThread; static QMutex adoptedThreadMonitorMutex; static QCAddAdoptedThread* adoptedThreadAdder; + TRequestStatus *stat; }; QMutex QCAddAdoptedThread::adoptedThreadMonitorMutex; diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp index 1629b91..ee498cc 100644 --- a/tests/auto/qthread/tst_qthread.cpp +++ b/tests/auto/qthread/tst_qthread.cpp @@ -104,6 +104,7 @@ private slots: void adoptedThreadExec(); void adoptedThreadFinished(); void adoptMultipleThreads(); + void adoptMultipleThreadsOverlap(); void QTBUG13810_exitAndStart(); void QTBUG15378_exitAndExec(); @@ -947,6 +948,49 @@ void tst_QThread::adoptMultipleThreads() QCOMPARE(int(recorder.activationCount), numThreads); } +void tst_QThread::adoptMultipleThreadsOverlap() +{ +#if defined(Q_OS_WIN) + // Windows CE is not capable of handling that many threads. On the emulator it is dead with 26 threads already. +# if defined(Q_OS_WINCE) + const int numThreads = 20; +# else + // need to test lots of threads, so that we exceed MAXIMUM_WAIT_OBJECTS in qt_adopted_thread_watcher() + const int numThreads = 200; +# endif +#elif defined(Q_OS_SYMBIAN) + // stress the monitoring thread's add function + const int numThreads = 100; +#else + const int numThreads = 5; +#endif + QVector<NativeThreadWrapper*> nativeThreads; + + SignalRecorder recorder; + + for (int i = 0; i < numThreads; ++i) { + nativeThreads.append(new NativeThreadWrapper()); + nativeThreads.at(i)->setWaitForStop(); + nativeThreads.at(i)->mutex.lock(); + nativeThreads.at(i)->start(); + } + for (int i = 0; i < numThreads; ++i) { + nativeThreads.at(i)->startCondition.wait(&nativeThreads.at(i)->mutex); + QObject::connect(nativeThreads.at(i)->qthread, SIGNAL(finished()), &recorder, SLOT(slot())); + nativeThreads.at(i)->mutex.unlock(); + } + + QObject::connect(nativeThreads.at(numThreads - 1)->qthread, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + for (int i = 0; i < numThreads; ++i) { + nativeThreads.at(i)->stop(); + nativeThreads.at(i)->join(); + } + + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(int(recorder.activationCount), numThreads); +} void tst_QThread::stressTest() { #if defined(Q_OS_WINCE) |