diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 812b4afcc4..87ab87181f 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -47,6 +47,7 @@ #include "qeventloop.h" #endif #include "qmetaobject.h" +#include #include "qcorecmdlineargs_p.h" #include #include @@ -861,6 +862,7 @@ void QCoreApplicationPrivate::init() qt_call_pre_routines(); qt_startup_hook(); #ifndef QT_BOOTSTRAPPED + QtPrivate::initBindingStatusThreadId(); if (Q_UNLIKELY(qtHookData[QHooks::Startup])) reinterpret_cast(qtHookData[QHooks::Startup])(); #endif diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index f1c8adb8a0..50ec3807d3 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -43,6 +43,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -2184,7 +2185,12 @@ void QBindingStorage::registerDependency_helper(const QUntypedPropertyData *data Q_ASSERT(bindingStatus); // Use ::bindingStatus to get the binding from TLS. This is required, so that reads from // another thread do not register as dependencies - auto *currentBinding = QT_PREPEND_NAMESPACE(bindingStatus).currentlyEvaluatingBinding; + const bool threadMatches = (QThread::currentThreadId() == bindingStatus->threadId); + QtPrivate::BindingEvaluationState *currentBinding; + if (Q_LIKELY(threadMatches)) + currentBinding = bindingStatus->currentlyEvaluatingBinding; + else + currentBinding = QT_PREPEND_NAMESPACE(bindingStatus).currentlyEvaluatingBinding; QUntypedPropertyData *dd = const_cast(data); auto storage = QBindingStoragePrivate(d).get(dd, /*create=*/ currentBinding != nullptr); if (!storage) @@ -2205,6 +2211,13 @@ QPropertyBindingData *QBindingStorage::bindingData_helper(QUntypedPropertyData * namespace QtPrivate { + + +void initBindingStatusThreadId() +{ + bindingStatus.threadId = QThread::currentThreadId(); +} + BindingEvaluationState *suspendCurrentBindingStatus() { auto ret = bindingStatus.currentlyEvaluatingBinding; diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index b25e932595..008748840d 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -943,6 +943,7 @@ struct QBindingStatus { QtPrivate::BindingEvaluationState *currentlyEvaluatingBinding = nullptr; QtPrivate::CompatPropertySafePoint *currentCompatProperty = nullptr; + Qt::HANDLE threadId = nullptr; }; struct QBindingStorageData; diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h index 2883308299..ba1eb7adf2 100644 --- a/src/corelib/kernel/qproperty_p.h +++ b/src/corelib/kernel/qproperty_p.h @@ -391,6 +391,7 @@ inline QPropertyObserverPointer QPropertyBindingDataPointer::firstObserver() con namespace QtPrivate { Q_CORE_EXPORT bool isPropertyInBindingWrapper(const QUntypedPropertyData *property); + void Q_CORE_EXPORT initBindingStatusThreadId(); } template