summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2011-02-04 09:00:35 (GMT)
committerOlivier Goffart <olivier.goffart@nokia.com>2011-02-07 15:11:06 (GMT)
commita77ab4c4dd3c0d9c5cf71afc4d3efcc76a068430 (patch)
tree47d2955a71c203240a55b892561075c33b39b5c5 /src/corelib
parentcce5cde471cb107924a31c91a05ca299f1668edb (diff)
downloadQt-a77ab4c4dd3c0d9c5cf71afc4d3efcc76a068430.zip
Qt-a77ab4c4dd3c0d9c5cf71afc4d3efcc76a068430.tar.gz
Qt-a77ab4c4dd3c0d9c5cf71afc4d3efcc76a068430.tar.bz2
Fix race condition between QEventLoop::exec and QThread::exit
As also mentioned in QTBUG-16692 Reviewed-by: brad Task-number: QTBUG-17257
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qeventloop.cpp5
-rw-r--r--src/corelib/thread/qthread_unix.cpp5
-rw-r--r--src/corelib/thread/qthread_win.cpp5
3 files changed, 13 insertions, 2 deletions
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index e78f86a..d213b0e 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -175,6 +175,8 @@ bool QEventLoop::processEvents(ProcessEventsFlags flags)
int QEventLoop::exec(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
+ //we need to protect from race condition with QThread::exit
+ QMutexLocker locker(&static_cast<QThreadPrivate *>(QObjectPrivate::get(d->threadData->thread))->mutex);
if (d->threadData->quitNow)
return -1;
@@ -186,6 +188,7 @@ int QEventLoop::exec(ProcessEventsFlags flags)
d->exit = false;
++d->threadData->loopLevel;
d->threadData->eventLoops.push(this);
+ locker.unlock();
// remove posted quit events when entering a new event loop
QCoreApplication *app = QCoreApplication::instance();
@@ -205,6 +208,7 @@ int QEventLoop::exec(ProcessEventsFlags flags)
"reimplement QApplication::notify() and catch all exceptions there.\n");
// copied from below
+ locker.relock();
QEventLoop *eventLoop = d->threadData->eventLoops.pop();
Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error");
Q_UNUSED(eventLoop); // --release warning
@@ -216,6 +220,7 @@ int QEventLoop::exec(ProcessEventsFlags flags)
#endif
// copied above
+ locker.relock();
QEventLoop *eventLoop = d->threadData->eventLoops.pop();
Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error");
Q_UNUSED(eventLoop); // --release warning
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 891ac77..5e0d2a2 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -327,7 +327,10 @@ void *QThreadPrivate::start(void *arg)
set_thread_data(data);
data->ref();
- data->quitNow = false;
+ {
+ QMutexLocker locker(&thr->d_func()->mutex);
+ data->quitNow = thr->d_func()->exited;
+ }
// ### TODO: allow the user to create a custom event dispatcher
createEventDispatcher(data);
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index cb2d1a9..f2d1310 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -298,7 +298,10 @@ unsigned int __stdcall QThreadPrivate::start(void *arg)
QThread::setTerminationEnabled(false);
- data->quitNow = false;
+ {
+ QMutexLocker locker(&thr->d_func()->mutex);
+ data->quitNow = !thr->d_func()->exited;
+ }
// ### TODO: allow the user to create a custom event dispatcher
createEventDispatcher(data);