summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authormread <qt-info@nokia.com>2011-04-12 15:07:11 +0100
committermread <qt-info@nokia.com>2011-04-12 15:19:33 +0100
commit6f1efe75dac53377b92d779818b43a34add92f02 (patch)
treec3db3804163d4e10b30f2fdea3694cba09eade5b /src/corelib/thread
parent46163663e956b988719563eae18773a2dedd424e (diff)
Applying the QTBUG-17986 fix to Symbian
This change takes the QTBUG-17986 fix, which deletes QThreadData for adopted threads that have created QEventLoops, and applies it to qthread_symbian.cpp, which didn't exist at the time of the original fix. One complication is that Symbian uses a separate thread to monitor adopted thread lifetime, as there is no API to intercept thread exit to have cleanup code run within the context of the thread. However the cleanup for the thread involes deleting active objects that were created in the adopted thread, not the monitor thread. If these active objects are completed but not run, their cancellation could deadlock. In particular the wake up active object in the event dispatcher is typically in this state. We deal with it by detecting the situation and re-completing/cancelling the active object in the adopted thread monitor thread, which prevents deadlock and allows correct operation of the monitor thread. It is possible for this problem to affect other active objects owned by the event dispatcher. They symptom would be that finished signals from adopted threads are not sent, or they arrive much later than they should. Task-number: QTBUG-18622 Reviewed-by: Shane Kearns
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qthread_symbian.cpp8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp
index 15e6898c00..5d8b5cbf0d 100644
--- a/src/corelib/thread/qthread_symbian.cpp
+++ b/src/corelib/thread/qthread_symbian.cpp
@@ -113,6 +113,7 @@ QThreadData *QThreadData::current()
}
data->deref();
}
+ data->isAdopted = true;
data->threadId = QThread::currentThreadId();
if (!QCoreApplicationPrivate::theMainThread)
QCoreApplicationPrivate::theMainThread = data->thread;
@@ -257,6 +258,13 @@ QCAddAdoptedThread* QCAddAdoptedThread::adoptedThreadAdder = 0;
void QCAdoptedThreadMonitor::RunL()
{
+ if (data->isAdopted) {
+ QThread *thread = data->thread;
+ Q_ASSERT(thread);
+ QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
+ Q_ASSERT(!thread_p->finished);
+ thread_p->finish(thread);
+ }
data->deref();
QCAddAdoptedThread::threadDied();
delete this;