summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2021-06-25 11:06:30 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2021-08-04 19:31:52 +0200
commit460700f7736ae308bcbaa37f512355d09876dc8b (patch)
treeaa303517f2ba721a232e1547e87b764cad5d16af /src
parentfa8cffa4c97d2e46de9af6f5e91af9212e372204 (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')
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp2
-rw-r--r--src/corelib/kernel/qproperty.cpp15
-rw-r--r--src/corelib/kernel/qproperty.h1
-rw-r--r--src/corelib/kernel/qproperty_p.h1
4 files changed, 18 insertions, 1 deletions
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 <private/qproperty_p.h>
#include "qcorecmdlineargs_p.h"
#include <qdatastream.h>
#include <qdebug.h>
@@ -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<QHooks::StartupCallback>(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 <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;
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<typename Class, typename T, auto Offset, auto Setter, auto Signal=nullptr>