aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmltypemodule_p.h
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-08-10 12:21:58 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-08-17 16:14:53 +0200
commitd0dc91158d0b44d9e1b73c3b0dacdd6699741ad7 (patch)
tree331cab9fff2169cb76e33ca80d82a175e56e91c0 /src/qml/qml/qqmltypemodule_p.h
parentb4ab58d791167329259f5403e52ce6c85b5f0074 (diff)
Avoid querying the file system for qmldir files for locked modules
If the user explicitly locks a module using qmlProtectModule, we don't load any additional qmldir files afterwards. In particular, this means you can only do that with modules that don't contain qmldir files or with modules for which the qmldir files have already been loaded in all engines that need them. This is in contrast to the "weak" locking we automatically perform when loading a plugin. When importing the module again after loading a plugin we do want to re-evaluate the qmldir directives. If the module is imported from a different engine than before, we also have to search for the qmldir file again. Amends commit 914e0300792856ddac9b99b20a8d88dd6f087fa6. [ChangeLog][QtQml] The pre-5.15 behavior of qmlProtectModule() has mostly been restored: If you explicitly protect a module, the QML engine will never look for any qmldir files or plugins for that module again. This severely limits what you can do with such a module. However, once all affected engines have loaded the module, protecting it can be a useful optimization. In contrast to pre-5.15, the qmldir cache for such modules continues to be re-used even after they are locked. Therefore, in QML engines that have loaded the module before, you can expect any "prefer" or "import" directives and any composite types to still be available after protecting the module. Fixes: QTBUG-85591 Pick-to: 6.2 Change-Id: Ia4edd860e2ddda5e0c419e1ce9764f10f32ace1f Reviewed-by: Thorbjørn Lindeijer <bjorn@lindeijer.nl> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Fawzi Mohamed <fawzi.mohamed@qt.io>
Diffstat (limited to 'src/qml/qml/qqmltypemodule_p.h')
-rw-r--r--src/qml/qml/qqmltypemodule_p.h23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/qml/qml/qqmltypemodule_p.h b/src/qml/qml/qqmltypemodule_p.h
index 0ba6245cbb..c6dae7ef55 100644
--- a/src/qml/qml/qqmltypemodule_p.h
+++ b/src/qml/qml/qqmltypemodule_p.h
@@ -72,6 +72,12 @@ struct String;
class QQmlTypeModule
{
public:
+ enum class LockLevel {
+ Open = 0,
+ Weak = 1,
+ Strong = 2
+ };
+
QQmlTypeModule() = default;
QQmlTypeModule(const QString &uri, quint8 majorVersion)
: m_module(uri), m_majorVersion(majorVersion)
@@ -80,8 +86,17 @@ public:
void add(QQmlTypePrivate *);
void remove(const QQmlTypePrivate *type);
- bool isLocked() const { return m_locked.loadRelaxed() != 0; }
- void lock() { m_locked.storeRelaxed(1); }
+ LockLevel lockLevel() const { return LockLevel(m_lockLevel.loadRelaxed()); }
+ bool setLockLevel(LockLevel mode)
+ {
+ while (true) {
+ const int currentLock = m_lockLevel.loadAcquire();
+ if (currentLock > int(mode))
+ return false;
+ if (currentLock == int(mode) || m_lockLevel.testAndSetRelease(currentLock, int(mode)))
+ return true;
+ }
+ }
QString module() const
{
@@ -114,8 +129,8 @@ private:
// Can only ever increase
QAtomicInt m_maxMinorVersion = 0;
- // Bool. Can only be set to 1 once.
- QAtomicInt m_locked = 0;
+ // LockLevel. Can only be increased.
+ QAtomicInt m_lockLevel = int(LockLevel::Open);
using TypeHash = QStringHash<QList<QQmlTypePrivate *>>;
TypeHash m_typeHash;