diff options
Diffstat (limited to 'src/qml/qml/qqmlvaluetype.cpp')
-rw-r--r-- | src/qml/qml/qqmlvaluetype.cpp | 58 |
1 files changed, 21 insertions, 37 deletions
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index b0e08d3c41..150d70ee0c 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -64,16 +64,12 @@ struct QQmlValueTypeFactoryImpl const QMetaObject *metaObjectForMetaType(QMetaType metaType); QQmlValueType *valueType(QMetaType type); - QQmlValueType *valueTypes[QMetaType::User]; - QHash<int, QQmlValueType *> userTypes; - QMutex mutex; - - QQmlValueType invalidValueType; + QHash<int, QQmlValueType *> metaTypeToValueType; + QReadWriteLock rwLock; }; QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl() { - std::fill_n(valueTypes, int(QMetaType::User), &invalidValueType); #if QT_CONFIG(qml_itemmodel) // See types wrapped in qqmlmodelindexvaluetype_p.h @@ -83,11 +79,7 @@ QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl() QQmlValueTypeFactoryImpl::~QQmlValueTypeFactoryImpl() { - for (QQmlValueType *type : valueTypes) { - if (type != &invalidValueType) - delete type; - } - qDeleteAll(userTypes); + qDeleteAll(metaTypeToValueType); } bool isInternalType(int idx) @@ -178,37 +170,29 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(QMetaType met QQmlValueType *QQmlValueTypeFactoryImpl::valueType(QMetaType type) { int idx = type.id(); - if (idx >= (int)QMetaType::User) { - // Protect the hash with a mutex - mutex.lock(); - - QHash<int, QQmlValueType *>::iterator it = userTypes.find(idx); - if (it == userTypes.end()) { - QQmlValueType *vt = nullptr; - if (const QMetaObject *mo = metaObjectForMetaType(type)) - vt = new QQmlValueType(idx, mo); - it = userTypes.insert(idx, vt); - } + // Protect the hash with a mutex + { + QReadLocker lock(&rwLock); - mutex.unlock(); - return *it; + auto it = metaTypeToValueType.constFind(idx); + if (it != metaTypeToValueType.constEnd()) { + return *it; + } } - QQmlValueType *rv = valueTypes[idx]; - if (rv == &invalidValueType) { - // No need for mutex protection - the most we can lose is a valueType instance - - // TODO: Investigate the performance/memory characteristics of - // removing the preallocated array - if (isInternalType(idx)) - rv = valueTypes[idx] = nullptr; - else if (const QMetaObject *mo = metaObjectForMetaType(type)) - rv = valueTypes[idx] = new QQmlValueType(idx, mo); - else - rv = valueTypes[idx] = nullptr; + { + QWriteLocker lock(&rwLock); + // TODO: we need try_emplace to avoid the double lookup + auto it = metaTypeToValueType.find(idx); + if (it != metaTypeToValueType.end()) // another thread inserted the element before we relocked + return *it; + QQmlValueType *vt = nullptr; + if (const QMetaObject *mo = metaObjectForMetaType(type)) + vt = new QQmlValueType(idx, mo); + it = metaTypeToValueType.insert(idx, vt); + return *it; } - return rv; } } |