path: root/src/gui
diff options
authorGiuseppe D'Angelo <>2019-10-11 00:42:08 +0200
committerGiuseppe D'Angelo <>2019-11-13 16:22:40 +0100
commit782df5b41dd3ab098fd1d3233339079487e1812f (patch)
treea2727ed7dda4ecff4331e99d05f085bb7fc01184 /src/gui
parent4e0d5498eb7ba401e6697182ce74b34d439ecf76 (diff)
Make QObjectPrivate::threadData a proper atomic
QObjectPrivate::threadData used to be a QThreadData *, and was read and written from multiple threads without proper synchronization. As an example, it was read from QCoreApplication::postEvent and written from QObject::moveToThread, therefore causing UB. Port threadData to a proper atomic, removing the races. Fix all usage points. In general, QObject is documented to be simply reentrant, not thread-safe, and certain bits (e.g. timers, moveToThread) are not even reentrant. The reasoning therefore is that a given QObject's threadData is not supposed to be touched by multiple threads without some synchronization happening elsewhere, and therefore relaxed loads should be sufficient. As drive-by change: refactor QCoreApplication::postEvent. It was particularly subtle, because it had a loop using a volatile to cope with the possibility of the receiver object switching thread while we tried to lock its thread's event queue. However, volatile does not achieve any synchronization, so drop it, and refactor the algorithm using better locking primitives. Put this algorithm in a common place, and also reuse it from removePostedEvents, which was lacking any synchronization. Change-Id: Icc755f7eb418ff54b33db4bdd87fd8eaf4e82c7a Reviewed-by: Thiago Macieira <>
Diffstat (limited to 'src/gui')
1 files changed, 1 insertions, 1 deletions
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 26f65b2f16..ee493faa5d 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -116,7 +116,7 @@ public:
static QAbstractEventDispatcher *qt_qpa_core_dispatcher()
if (QCoreApplication::instance())
- return QCoreApplication::instance()->d_func()->threadData->eventDispatcher.loadRelaxed();
+ return QCoreApplication::instance()->d_func()->threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
return nullptr;