aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlproperty.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-01-13 18:36:13 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-01-29 15:39:42 +0100
commit228f854ff99719d4c8151a3b52612e74f649f2b8 (patch)
tree2c41080c864f7907d64c7dd4b0bf645248e49889 /src/qml/qml/qqmlproperty.cpp
parenta82b1b278ace7a500f95473f2a873923d2d4e60a (diff)
Get rid of global gadgetPtr in QQmlValueType
We should not keep user-created objects in global data structures. This is inherently thread-unsafe and crashes when the user passes static data and later unloads the same. Instead we keep the cached gadgetPtr wrapper objects in the engine now. Fixes: QTBUG-79553 Change-Id: I24ac3e84b572831d1d70b61b8a6001338579e284 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlproperty.cpp')
-rw-r--r--src/qml/qml/qqmlproperty.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index f5aae8f462..d191d07258 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1044,13 +1044,19 @@ QVariant QQmlProperty::read(const QObject *object, const QString &name, QQmlEngi
QVariant QQmlPropertyPrivate::readValueProperty()
{
- if (isValueType()) {
-
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType());
- Q_ASSERT(valueType);
- valueType->read(object, core.coreIndex());
- return valueType->metaObject()->property(valueTypeData.coreIndex()).read(valueType);
+ auto doRead = [&](QQmlGadgetPtrWrapper *wrapper) {
+ wrapper->read(object, core.coreIndex());
+ return wrapper->property(valueTypeData.coreIndex()).read(wrapper);
+ };
+ if (isValueType()) {
+ if (QQmlGadgetPtrWrapper *wrapper = QQmlGadgetPtrWrapper::instance(engine, core.propType()))
+ return doRead(wrapper);
+ if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) {
+ QQmlGadgetPtrWrapper wrapper(valueType, nullptr);
+ return doRead(&wrapper);
+ }
+ return QVariant();
} else if (core.isQList()) {
QQmlListProperty<QObject> prop;
@@ -1183,10 +1189,22 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object,
bool rv = false;
if (valueTypeData.isValid()) {
- QQmlValueType *writeBack = QQmlValueTypeFactory::valueType(core.propType());
- writeBack->read(object, core.coreIndex());
- rv = write(writeBack, valueTypeData, value, context, flags);
- writeBack->write(object, core.coreIndex(), flags);
+ auto doWrite = [&](QQmlGadgetPtrWrapper *wrapper) {
+ wrapper->read(object, core.coreIndex());
+ rv = write(wrapper, valueTypeData, value, context, flags);
+ wrapper->write(object, core.coreIndex(), flags);
+ };
+
+ QQmlGadgetPtrWrapper *wrapper = context
+ ? QQmlGadgetPtrWrapper::instance(context->engine, core.propType())
+ : nullptr;
+ if (wrapper) {
+ doWrite(wrapper);
+ } else if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) {
+ QQmlGadgetPtrWrapper wrapper(valueType, nullptr);
+ doWrite(&wrapper);
+ }
+
} else {
rv = write(object, core, value, context, flags);
}