aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den.exter@jollamobile.com>2013-12-13 16:10:58 +1000
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-19 01:36:40 +0100
commit59396165f9efae042c6a5395cfbd3f861d12fbb5 (patch)
tree5c96c1104581c1b935bb401812fdce3d6bdd15e7 /src/qml
parent854272ecf9f26e77ddd8e3b7015cb8fe278183a5 (diff)
Fix deadlock when QQmlEngine is destroyed during compilation.
Before blocking to wait for the thread to finish ensure the thread itself is not waiting for the main thread to complete some action otherwise both threads will be waiting on the same wait condition that neither is able to wake. Likewise ensure the shutdown action is processed if the last scheduled event is currently being processed. Task-number: QTBUG-35581 Change-Id: I483fc56d0d398493f9fa907f3ab203439bfb9221 Reviewed-by: Robin Burchell <robin+qt@viroteck.net> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp
index 3accb9dce5..1ea3f25405 100644
--- a/src/qml/qml/ftw/qqmlthread.cpp
+++ b/src/qml/qml/ftw/qqmlthread.cpp
@@ -179,15 +179,17 @@ void QQmlThreadPrivate::threadEvent()
{
lock();
- if (m_shutdown) {
- quit();
- wakeOne();
- unlock();
- q->shutdownThread();
- } else {
- m_threadProcessing = true;
+ for (;;) {
+ if (m_shutdown) {
+ quit();
+ wakeOne();
+ unlock();
+ q->shutdownThread();
+
+ return;
+ } else if (!threadList.isEmpty()) {
+ m_threadProcessing = true;
- while (!threadList.isEmpty()) {
QQmlThread::Message *message = threadList.first();
unlock();
@@ -197,13 +199,15 @@ void QQmlThreadPrivate::threadEvent()
lock();
delete threadList.takeFirst();
- }
+ } else {
+ wakeOne();
- wakeOne();
+ m_threadProcessing = false;
- m_threadProcessing = false;
+ unlock();
- unlock();
+ return;
+ }
}
}
@@ -228,8 +232,11 @@ void QQmlThread::shutdown()
d->lock();
Q_ASSERT(!d->m_shutdown);
d->m_shutdown = true;
- if (d->threadList.isEmpty() && d->m_threadProcessing == false)
+ if (d->threadList.isEmpty() && d->m_threadProcessing == false) {
d->triggerThreadEvent();
+ } else if (d->mainSync) {
+ d->wakeOne();
+ }
d->wait();
d->unlock();
d->QThread::wait();
@@ -333,8 +340,14 @@ void QQmlThread::internalCallMethodInMain(Message *message)
d->triggerMainEvent();
}
- while (d->mainSync && !d->m_shutdown)
+ while (d->mainSync) {
+ if (d->m_shutdown) {
+ delete d->mainSync;
+ d->mainSync = 0;
+ break;
+ }
d->wait();
+ }
d->unlock();
}