From c5a462519a8bce0faa31ce41414022749e3ad2f5 Mon Sep 17 00:00:00 2001 From: mread Date: Thu, 17 Feb 2011 13:07:51 +0000 Subject: 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 --- src/corelib/thread/qthread_symbian.cpp | 8 +++---- 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 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) -- cgit v0.12