diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2019-02-04 09:25:31 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-02-07 13:49:26 +0000 |
commit | 8d0b649c6b6ebf64dd4f644a5a2b3b1fa34e57c9 (patch) | |
tree | 41fd801a6949cd59374e81b8a3c0939c25118bc2 /src/qml/qml/qqmlmetatype.cpp | |
parent | 77ca9599418806733322b6be55283098cea383a4 (diff) |
Tighten the interface of QQmlTypeModule
No other classes really need direct access to QQmlTypeModulePrivate.
Adding or removing types, as well as lookup of types needs to be
protected by a mutex, as that can happen from multiple threads. However,
we don't need to acquire the global type registration mutex in order to
change the internals of some QQmlTypeModule. Rather, each type module
gets its own mutex.
The minimum and maximum versions as well as the "locked" property can be
handled with atomic integers as they only ever move in one direction.
The module and majorVersion properties are constant over the life time
of the object. Therefore they don't need any locking.
Task-number: QTBUG-73271
Change-Id: I23fe7dcaf521ccecaaaf19c1fb0436e109c42f03
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlmetatype.cpp')
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 124 |
1 files changed, 55 insertions, 69 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 34412a5fcb..8c3717844c 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -253,7 +253,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da versionedUri.uri = nameSpace; versionedUri.majorVersion = majorVersion; if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)){ - if (QQmlTypeModulePrivate::get(qqtm)->locked){ + if (qqtm->isLocked()){ QString failure(QCoreApplication::translate("qmlRegisterType", "Cannot install %1 '%2' into protected module '%3' version '%4'")); data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace).arg(majorVersion)); @@ -272,8 +272,7 @@ QQmlTypeModule *getTypeModule(const QHashedString &uri, int majorVersion, QQmlMe QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion); QQmlTypeModule *module = data->uriToModule.value(versionedUri); if (!module) { - module = new QQmlTypeModule; - module->d->uri = versionedUri; + module = new QQmlTypeModule(versionedUri.uri, versionedUri.majorVersion); data->uriToModule.insert(versionedUri, module); } return module; @@ -309,7 +308,7 @@ void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data) QQmlTypeModule *module = getTypeModule(mod, type->version_maj, data); Q_ASSERT(module); - module->d->add(type); + module->add(type); } } @@ -447,7 +446,7 @@ bool QQmlMetaType::protectModule(const char *uri, int majVersion) versionedUri.majorVersion = majVersion; if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)) { - QQmlTypeModulePrivate::get(qqtm)->locked = true; + qqtm->lock(); return true; } return false; @@ -460,9 +459,7 @@ void QQmlMetaType::registerModule(const char *uri, int versionMajor, int version QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), versionMajor, data); Q_ASSERT(module); - QQmlTypeModulePrivate *p = QQmlTypeModulePrivate::get(module); - p->minMinorVersion = qMin(p->minMinorVersion, versionMinor); - p->maxMinorVersion = qMax(p->maxMinorVersion, versionMinor); + module->addMinorVersion(versionMinor); } int QQmlMetaType::typeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName) @@ -543,7 +540,7 @@ bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion) versionedUri.uri = uri; versionedUri.majorVersion = majVersion; if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)) - return QQmlTypeModulePrivate::get(qqtm)->locked; + return qqtm->isLocked(); return false; } @@ -900,20 +897,15 @@ QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, int minorVe void QQmlMetaType::unregisterType(int typeIndex) { QQmlMetaTypeDataPtr data; - { - const QQmlTypePrivate *d = data->types.value(typeIndex).priv(); - if (d) { - removeQQmlTypePrivate(data->idToType, d); - removeQQmlTypePrivate(data->nameToType, d); - removeQQmlTypePrivate(data->urlToType, d); - removeQQmlTypePrivate(data->urlToNonFileImportType, d); - removeQQmlTypePrivate(data->metaObjectToType, d); - for (QQmlMetaTypeData::TypeModules::Iterator module = data->uriToModule.begin(); module != data->uriToModule.end(); ++module) { - QQmlTypeModulePrivate *modulePrivate = (*module)->priv(); - modulePrivate->remove(d); - } - data->types[typeIndex] = QQmlType(); - } + if (const QQmlTypePrivate *d = data->types.value(typeIndex).priv()) { + removeQQmlTypePrivate(data->idToType, d); + removeQQmlTypePrivate(data->nameToType, d); + removeQQmlTypePrivate(data->urlToType, d); + removeQQmlTypePrivate(data->urlToNonFileImportType, d); + removeQQmlTypePrivate(data->metaObjectToType, d); + for (auto & module : data->uriToModule) + module->remove(d); + data->types[typeIndex] = QQmlType(); } } @@ -921,54 +913,48 @@ void QQmlMetaType::freeUnusedTypesAndCaches() { QQmlMetaTypeDataPtr data; - { - bool deletedAtLeastOneType; - do { - deletedAtLeastOneType = false; - QList<QQmlType>::Iterator it = data->types.begin(); - while (it != data->types.end()) { - const QQmlTypePrivate *d = (*it).priv(); - if (d && d->refCount == 1) { - deletedAtLeastOneType = true; - - removeQQmlTypePrivate(data->idToType, d); - removeQQmlTypePrivate(data->nameToType, d); - removeQQmlTypePrivate(data->urlToType, d); - removeQQmlTypePrivate(data->urlToNonFileImportType, d); - removeQQmlTypePrivate(data->metaObjectToType, d); - - for (QQmlMetaTypeData::TypeModules::Iterator module = data->uriToModule.begin(); module != data->uriToModule.end(); ++module) { - QQmlTypeModulePrivate *modulePrivate = (*module)->priv(); - modulePrivate->remove(d); - } - - *it = QQmlType(); - } else { - ++it; - } + bool deletedAtLeastOneType; + do { + deletedAtLeastOneType = false; + QList<QQmlType>::Iterator it = data->types.begin(); + while (it != data->types.end()) { + const QQmlTypePrivate *d = (*it).priv(); + if (d && d->refCount == 1) { + deletedAtLeastOneType = true; + + removeQQmlTypePrivate(data->idToType, d); + removeQQmlTypePrivate(data->nameToType, d); + removeQQmlTypePrivate(data->urlToType, d); + removeQQmlTypePrivate(data->urlToNonFileImportType, d); + removeQQmlTypePrivate(data->metaObjectToType, d); + + for (auto &module : data->uriToModule) + module->remove(d); + + *it = QQmlType(); + } else { + ++it; } - } while (deletedAtLeastOneType); - } - - { - bool deletedAtLeastOneCache; - do { - deletedAtLeastOneCache = false; - QHash<const QMetaObject *, QQmlPropertyCache *>::Iterator it = data->propertyCaches.begin(); - while (it != data->propertyCaches.end()) { - - if ((*it)->count() == 1) { - QQmlPropertyCache *pc = nullptr; - qSwap(pc, *it); - it = data->propertyCaches.erase(it); - pc->release(); - deletedAtLeastOneCache = true; - } else { - ++it; - } + } + } while (deletedAtLeastOneType); + + bool deletedAtLeastOneCache; + do { + deletedAtLeastOneCache = false; + QHash<const QMetaObject *, QQmlPropertyCache *>::Iterator it = data->propertyCaches.begin(); + while (it != data->propertyCaches.end()) { + + if ((*it)->count() == 1) { + QQmlPropertyCache *pc = nullptr; + qSwap(pc, *it); + it = data->propertyCaches.erase(it); + pc->release(); + deletedAtLeastOneCache = true; + } else { + ++it; } - } while (deletedAtLeastOneCache); - } + } + } while (deletedAtLeastOneCache); } /*! |