diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-06-25 11:06:30 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-08-04 19:31:52 +0200 |
commit | 460700f7736ae308bcbaa37f512355d09876dc8b (patch) | |
tree | aa303517f2ba721a232e1547e87b764cad5d16af /src/corelib/kernel/qproperty.cpp | |
parent | fa8cffa4c97d2e46de9af6f5e91af9212e372204 (diff) |
QProperty: Avoid TLS lookup if we are in the same thread
If the QBindingStatus we receive from the QObject is from the thread
which is currently running, we do not need to refetch the thread local;
the reason we refetched the thread_local was after all only to guard
against the case where a QObject's property gets read in a different
thread.
To determine whether we are in the same thread, we can store the thread
id in the thread_local structure. Currently, it only gets initialized
for the main thread in QCoreApplication (as bindings are mostly used
there).
At a later point, we could either expose initBindingStatusThreadId, or
call the function when a QThread gets started.
Pick-to: 6.2
Change-Id: Id8eb803973bb083abfab83a62bfccc9e88a4e542
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/kernel/qproperty.cpp')
-rw-r--r-- | src/corelib/kernel/qproperty.cpp | 15 |
1 files changed, 14 insertions, 1 deletions
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 <qscopedvaluerollback.h> #include <QScopeGuard> #include <QtCore/qloggingcategory.h> +#include <QThread> 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<QUntypedPropertyData *>(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; |