Avoid TLS access for groupUpdateData
By putting the groupUpdateData pointer into the same thread local as the binding status, we avoid having to fetch two thread_local variables. Moreover, we can reuse the caching mechanism which we have in place for QBindingStatus to avoid costly TLS lookups. Pick-to: 6.2 Change-Id: Iaea515763510daab83f89b8e74f35a80965d6965 Reviewed-by: Lars Knoll <lars.knoll@qt.io>bb10
parent
460700f773
commit
71fea09e1a
|
|
@ -198,7 +198,7 @@ struct QPropertyDelayedNotifications
|
|||
}
|
||||
};
|
||||
|
||||
static thread_local QPropertyDelayedNotifications *groupUpdateData = nullptr;
|
||||
static thread_local QBindingStatus bindingStatus;
|
||||
|
||||
/*!
|
||||
\since 6.2
|
||||
|
|
@ -222,6 +222,7 @@ static thread_local QPropertyDelayedNotifications *groupUpdateData = nullptr;
|
|||
*/
|
||||
void Qt::beginPropertyUpdateGroup()
|
||||
{
|
||||
QPropertyDelayedNotifications *& groupUpdateData = bindingStatus.groupUpdateData;
|
||||
if (!groupUpdateData)
|
||||
groupUpdateData = new QPropertyDelayedNotifications;
|
||||
++groupUpdateData->ref;
|
||||
|
|
@ -241,6 +242,7 @@ void Qt::beginPropertyUpdateGroup()
|
|||
*/
|
||||
void Qt::endPropertyUpdateGroup()
|
||||
{
|
||||
QPropertyDelayedNotifications *& groupUpdateData = bindingStatus.groupUpdateData;
|
||||
auto *data = groupUpdateData;
|
||||
Q_ASSERT(data->ref);
|
||||
if (--data->ref)
|
||||
|
|
@ -467,8 +469,6 @@ QPropertyBindingData::QPropertyBindingData(QPropertyBindingData &&other) : d_ptr
|
|||
QPropertyBindingDataPointer::fixupAfterMove(this);
|
||||
}
|
||||
|
||||
static thread_local QBindingStatus bindingStatus;
|
||||
|
||||
BindingEvaluationState::BindingEvaluationState(QPropertyBindingPrivate *binding, QBindingStatus *status)
|
||||
: binding(binding)
|
||||
{
|
||||
|
|
@ -544,13 +544,23 @@ void QPropertyBindingData::registerWithCurrentlyEvaluatingBinding_helper(Binding
|
|||
}
|
||||
|
||||
void QPropertyBindingData::notifyObservers(QUntypedPropertyData *propertyDataPtr) const
|
||||
{
|
||||
notifyObservers(propertyDataPtr, nullptr);
|
||||
}
|
||||
|
||||
void QPropertyBindingData::notifyObservers(QUntypedPropertyData *propertyDataPtr, QBindingStorage *storage) const
|
||||
{
|
||||
if (isNotificationDelayed())
|
||||
return;
|
||||
QPropertyBindingDataPointer d{this};
|
||||
|
||||
if (QPropertyObserverPointer observer = d.firstObserver()) {
|
||||
auto *delay = groupUpdateData;
|
||||
auto status = storage ? storage->bindingStatus : nullptr;
|
||||
QPropertyDelayedNotifications *delay;
|
||||
if (status && status->threadId == QThread::currentThreadId())
|
||||
delay = status->groupUpdateData;
|
||||
else
|
||||
delay = bindingStatus.groupUpdateData;
|
||||
if (delay) {
|
||||
delay->addProperty(this, propertyDataPtr);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -944,8 +944,10 @@ struct QBindingStatus
|
|||
QtPrivate::BindingEvaluationState *currentlyEvaluatingBinding = nullptr;
|
||||
QtPrivate::CompatPropertySafePoint *currentCompatProperty = nullptr;
|
||||
Qt::HANDLE threadId = nullptr;
|
||||
QPropertyDelayedNotifications *groupUpdateData = nullptr;
|
||||
};
|
||||
|
||||
|
||||
struct QBindingStorageData;
|
||||
class Q_CORE_EXPORT QBindingStorage
|
||||
{
|
||||
|
|
@ -955,6 +957,7 @@ class Q_CORE_EXPORT QBindingStorage
|
|||
template<typename Class, typename T, auto Offset, auto Setter, auto Signal>
|
||||
friend class QObjectCompatProperty;
|
||||
friend class QObjectPrivate;
|
||||
friend class QtPrivate::QPropertyBindingData;
|
||||
public:
|
||||
QBindingStorage();
|
||||
~QBindingStorage();
|
||||
|
|
@ -1184,7 +1187,7 @@ private:
|
|||
void notify(const QtPrivate::QPropertyBindingData *binding)
|
||||
{
|
||||
if (binding)
|
||||
binding->notifyObservers(this);
|
||||
binding->notifyObservers(this, qGetBindingStorage(owner()));
|
||||
if constexpr (HasSignal) {
|
||||
if constexpr (SignalTakesValue::value)
|
||||
(owner()->*Signal)(this->valueBypassingBindings());
|
||||
|
|
@ -1322,7 +1325,7 @@ public:
|
|||
auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
|
||||
auto bd = storage->bindingData(const_cast<QObjectComputedProperty *>(this), false);
|
||||
if (bd)
|
||||
bd->notifyObservers(this);
|
||||
bd->notifyObservers(this, qGetBindingStorage(owner()));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -592,7 +592,7 @@ private:
|
|||
void notify(const QtPrivate::QPropertyBindingData *binding)
|
||||
{
|
||||
if (binding)
|
||||
binding->notifyObservers(this);
|
||||
binding->notifyObservers(this, qGetBindingStorage(owner()));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBindingStorage;
|
||||
|
||||
namespace QtPrivate {
|
||||
// QPropertyBindingPrivatePtr operates on a RefCountingMixin solely so that we can inline
|
||||
// the constructor and copy constructor
|
||||
|
|
@ -302,6 +304,7 @@ public:
|
|||
}
|
||||
void registerWithCurrentlyEvaluatingBinding() const;
|
||||
void notifyObservers(QUntypedPropertyData *propertyDataPtr) const;
|
||||
void notifyObservers(QUntypedPropertyData *propertyDataPtr, QBindingStorage *storage) const;
|
||||
private:
|
||||
/*!
|
||||
\internal
|
||||
|
|
|
|||
Loading…
Reference in New Issue