summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authormread <qt-info@nokia.com>2011-03-18 10:42:45 +0000
committermread <qt-info@nokia.com>2011-03-18 10:49:21 +0000
commita9cb2be8c14317001c0945da84f1a19e1d6ee6c6 (patch)
treed7d9f62fe53049e6c10afa5df2a18134d4b72e59 /src/corelib/thread
parentbbbe40631bac44489d35d7ae76a3ccd41b75fe6a (diff)
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.cpp36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp
index 128124ffd7..75cb5eb699 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);