QCoreApplicationPrivate: Do checks for application instance as late as possible

`QCoreApplicationPrivate::self` is set to nullptr in `~QCoreApplication`
without any synchronization. So it is not safe to access it from
instances of `QDaemonThread` that may outlive the application instance,
but are using the Qt event system. This patch moves some usages of
`self` behind other checks, so that the QtDBus management thread can
continue workoing without race conditions detected by Thread Sanitizer
while running tst_qdbusconnection.

Change-Id: Iece65e4126a59e3a1a41dfb6a99c84527b8d389c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
bb10
Ievgenii Meshcheriakov 2023-09-22 16:19:35 +02:00
parent 5093e517b9
commit 65953e05d3
1 changed files with 6 additions and 4 deletions

View File

@ -1103,7 +1103,7 @@ void QCoreApplication::setQuitLockEnabled(bool enabled)
bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
{
bool selfRequired = QCoreApplicationPrivate::threadRequiresCoreApplication();
if (!self && selfRequired)
if (selfRequired && !self)
return false;
// Make it possible for Qt Script to hook into events even
@ -1256,7 +1256,9 @@ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiv
bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
{
if (receiver != QCoreApplication::instance() && receiver->d_func()->extraData) {
if ((receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() != mainThread()
|| receiver != QCoreApplication::instance())
&& receiver->d_func()->extraData) {
for (qsizetype i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) {
QObject *obj = receiver->d_func()->extraData->eventFilters.at(i);
if (!obj)
@ -1287,8 +1289,8 @@ bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
Q_TRACE_EXIT(QCoreApplication_notify_exit, consumed, filtered);
// send to all application event filters (only does anything in the main thread)
if (QCoreApplication::self
&& receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread()
if (receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread()
&& QCoreApplication::self
&& QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
filtered = true;
return filtered;