diff options
author | mread <qt-info@nokia.com> | 2011-03-18 10:42:45 (GMT) |
---|---|---|
committer | mread <qt-info@nokia.com> | 2011-03-18 10:49:21 (GMT) |
commit | a9cb2be8c14317001c0945da84f1a19e1d6ee6c6 (patch) | |
tree | d7d9f62fe53049e6c10afa5df2a18134d4b72e59 /src/corelib/thread | |
parent | bbbe40631bac44489d35d7ae76a3ccd41b75fe6a (diff) | |
download | Qt-a9cb2be8c14317001c0945da84f1a19e1d6ee6c6.zip Qt-a9cb2be8c14317001c0945da84f1a19e1d6ee6c6.tar.gz Qt-a9cb2be8c14317001c0945da84f1a19e1d6ee6c6.tar.bz2 |
Making Symbian helper threads exit cleanly at app exit
The idle detector thread and the adopted thread monitor thread could
keep an app alive unnecessarily after main had exited, if the app's
main thread was no longer set "process permanent".
The idle detector thread now exits when the QCoreApplication is
destroyed.
The adopted thread monitor thread now exits when there are no more
adopted threads to monitor.
Task-number: QTBUG-18073
Reviewed-by: Shane Kearns
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qthread_symbian.cpp | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp index 128124f..75cb5eb 100644 --- a/src/corelib/thread/qthread_symbian.cpp +++ b/src/corelib/thread/qthread_symbian.cpp @@ -131,11 +131,7 @@ public: { data->symbian_thread_handle.LogonCancel(iStatus); } - void RunL() - { - data->deref(); - delete this; - } + void RunL(); private: QThreadData* data; }; @@ -177,6 +173,7 @@ public: for (int i=threadsToAdd.size()-1; i>=0; i--) { // Create an active object to monitor the thread new (ELeave) QCAdoptedThreadMonitor(threadsToAdd[i]); + count++; threadsToAdd.pop_back(); } start(); @@ -193,6 +190,8 @@ public: User::WaitForRequest(started); monitorThread.Close(); } + if (RThread().Id() == adoptedThreadAdder->monitorThread.Id()) + return; adoptedThreadAdder->threadsToAdd.push_back(thread); if (adoptedThreadAdder->stat) { adoptedThreadAdder->monitorThread.RequestComplete(adoptedThreadAdder->stat, KErrNone); @@ -204,15 +203,15 @@ public: CleanupStack::PushL(scheduler); CActiveScheduler::Install(scheduler); - adoptedThreadAdder = new(ELeave) QCAddAdoptedThread(); + adoptedThreadAdder = new(ELeave) QCAddAdoptedThread(); CleanupStack::PushL(adoptedThreadAdder); adoptedThreadAdder->ConstructL(); + QCAddAdoptedThread *adder = adoptedThreadAdder; RThread::Rendezvous(KErrNone); CActiveScheduler::Start(); - CleanupStack::PopAndDestroy(adoptedThreadAdder); - adoptedThreadAdder = 0; + CleanupStack::PopAndDestroy(adder); CleanupStack::PopAndDestroy(scheduler); } static int monitorThreadFunc(void *) @@ -224,18 +223,37 @@ public: delete cleanup; return ret; } + static void threadDied() + { + QMutexLocker adoptedThreadMonitorMutexlock(&adoptedThreadMonitorMutex); + if (adoptedThreadAdder) { + adoptedThreadAdder->count--; + if (adoptedThreadAdder->count <= 0 && adoptedThreadAdder->threadsToAdd.size() == 0) { + CActiveScheduler::Stop(); + adoptedThreadAdder = 0; + } + } + } private: QVector<QThread*> threadsToAdd; RThread monitorThread; static QMutex adoptedThreadMonitorMutex; - static QCAddAdoptedThread* adoptedThreadAdder; + static QCAddAdoptedThread *adoptedThreadAdder; + int count; TRequestStatus *stat; }; QMutex QCAddAdoptedThread::adoptedThreadMonitorMutex; QCAddAdoptedThread* QCAddAdoptedThread::adoptedThreadAdder = 0; +void QCAdoptedThreadMonitor::RunL() +{ + data->deref(); + QCAddAdoptedThread::threadDied(); + delete this; +} + void QAdoptedThread::init() { Q_D(QThread); |