Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmltypeloaderdata_p.h
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQMLTYPELOADERDATA_P_H
5#define QQMLTYPELOADERDATA_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <private/qqmlrefcount_p.h>
19#include <private/qqmltypeloaderqmldircontent_p.h>
20#include <private/qqmltypeloaderthread_p.h>
21#include <private/qv4engine_p.h>
22
23#include <QtQml/qtqmlglobal.h>
24#include <QtQml/qqmlengine.h>
25
26#include <QtCore/qcache.h>
27#include <QtCore/qthread.h>
28
29QT_BEGIN_NAMESPACE
30
31class QQmlProfiler;
32class QQmlQmldirData;
33class QQmlScriptBlob;
34class QQmlTypeData;
35
56
58{
60public:
63
70
72
75
76 // Maps from an import to a linked list of qmldir info.
77 // Used in locateLocalQmldir()
79
80 // Modules for which plugins have been loaded and processed in the context of this type
81 // loader's engine. Plugins can have engine-specific initialization callbacks. This is why
82 // we have to keep track of this.
84
85 // Plugins that have been initialized in the context of this engine. In theory, the same
86 // plugin can be used for multiple modules. Therefore, we need to keep track of this
87 // separately from modulesForWhichPluginsHaveBeenProcessed.
89
90#if QT_CONFIG(qml_network)
93#endif
94};
95
97{
99public:
101
104
105 // URL interceptors must be set before loading any types. Otherwise we get data races.
107
108#if QT_CONFIG(qml_debug)
110#endif
111
114 bool isDebugging = false;
115 bool initialized = false;
116};
117
118#if QT_CONFIG(qml_network)
119class QQmlTypeLoaderNetworkAccessManagerData
120{
121 Q_DISABLE_COPY_MOVE(QQmlTypeLoaderNetworkAccessManagerData)
122public:
123 QQmlTypeLoaderNetworkAccessManagerData() = default;
124
125 QQmlNetworkAccessManagerFactory *networkAccessManagerFactory = nullptr;
126
127 // We need a separate mutex because the network access manger factory can be accessed not
128 // only from the engine thread and the type loader thread, but also from any WorkerScripts
129 // running in parallel to both.
130 mutable QMutex networkAccessManagerMutex;
131};
132#endif // QTCONFIG(qml_network)
133
135{
136 template<typename Data, typename LockedData>
138
139 template<typename Data, typename LockedData>
141
142 template<typename Data, typename LockedData>
144
145 template<typename Data, typename LockedData>
147 friend class QQmlNetworkAccessManagerFactoryPtr;
148
150public:
152
153 QQmlTypeLoaderThread *thread() const { return m_thread; }
154
155 void createThread(QQmlTypeLoader *loader)
156 {
157 Q_ASSERT(isCurrentJsEngineThread());
158 m_thread = new QQmlTypeLoaderThread(loader);
159 m_thread->startup();
160 }
161
163 {
164 Q_ASSERT(isCurrentJsEngineThread());
165 Q_ASSERT(m_thread);
166
167 // Shut it down first, then set it to nullptr, then delete it.
168 // This makes sure that any blobs deleted as part of the deletion
169 // do not see the thread anymore.
170 m_thread->shutdown();
171 delete std::exchange(m_thread, nullptr);
172 }
173
175 {
176 Q_ASSERT(isCurrentJsEngineThread());
177 return m_engine;
178 }
179
180private:
181 bool isCurrentJsEngineThread() const
182 {
183 if (QJSEngine *jsEngine = m_engine->jsEngine())
184 return jsEngine->thread()->isCurrentThread();
185
186 // If we can't determine the thread, assume it's the right one
187 return true;
188 }
189
190
191 QQmlTypeLoaderSharedData m_sharedData;
192 QQmlTypeLoaderThreadData m_threadData;
193 QQmlTypeLoaderConfiguredData m_configuredData;
194#if QT_CONFIG(qml_network)
196#endif
197
198 QV4::ExecutionEngine *m_engine = nullptr;
199 QQmlTypeLoaderThread *m_thread = nullptr;
200};
201
202template<typename Data, typename LockedData>
230
233using QQmlTypeLoaderSharedDataConstPtr
236template<typename Data, typename LockedData>
238{
240public:
242 {
243 Q_ASSERT(data);
244
245 // You have to either be on the type loader thread or shut it down before accessing this.
249 Data &operator*() const { return data->m_threadData; }
250 Data *operator->() const { return &data->m_threadData; }
251 operator Data *() const { return &data->m_threadData; }
252
253private:
254 LockedData *data = nullptr;
257using QQmlTypeLoaderThreadDataPtr
259using QQmlTypeLoaderThreadDataConstPtr
261
262
263template<typename Data, typename LockedData>
265{
267public:
269 {
270 Q_ASSERT(data);
271
272 if constexpr (!std::is_const_v<Data>) {
273 // const access is generally fine
274 // For mutable access we first need to make sure the thread is shut down.
275 if (data->thread())
279
280 Data &operator*() const { return data->m_configuredData; }
281 Data *operator->() const { return &data->m_configuredData; }
282 operator Data *() const { return &data->m_configuredData; }
283
284private:
285 LockedData *data = nullptr;
286};
287
288using QQmlTypeLoaderConfiguredDataPtr
290using QQmlTypeLoaderConfiguredDataConstPtr
292
293#if QT_CONFIG(qml_network)
294class QQmlEnginePublicAPIToken;
295template<typename Data, typename LockedData>
296class QQmlNetworkAccessManagerFactoryPtrBase
297{
298 Q_DISABLE_COPY_MOVE(QQmlNetworkAccessManagerFactoryPtrBase)
299public:
300 Q_NODISCARD_CTOR QQmlNetworkAccessManagerFactoryPtrBase(LockedData *data) : data(data)
301 {
302 Q_ASSERT(data);
303 data->m_networkAccessManagerData.networkAccessManagerMutex.lock();
304 }
305
306 ~QQmlNetworkAccessManagerFactoryPtrBase()
307 {
308 Q_ASSERT(data);
309 data->m_networkAccessManagerData.networkAccessManagerMutex.unlock();
310 }
311
312 QQmlNetworkAccessManagerFactory &operator*() const
313 {
314 return *data->m_networkAccessManagerData.networkAccessManagerFactory;
315 }
316
317 QQmlNetworkAccessManagerFactory *operator->() const
318 {
319 return data->m_networkAccessManagerData.networkAccessManagerFactory;
320 }
321
322 operator bool() const
323 {
324 return data->m_networkAccessManagerData.networkAccessManagerFactory != nullptr;
325 }
326
327 // This is dangerous since it allows you to subvert the locking.
328 // You must only do this when serving public API that can't be changed for now.
329 QQmlNetworkAccessManagerFactory *get(const QQmlEnginePublicAPIToken &) const
330 {
331 return data->m_networkAccessManagerData.networkAccessManagerFactory;
332 }
333
334protected:
335 LockedData *data = nullptr;
336};
337
338// This is const in the sense that you cannot reset the pointer. Therefore the "Const" postfix.
339// That's in contrast to the other *Ptr classes here that are const in the way that the _data_
340// pointed to cannot be modified.
341using QQmlNetworkAccessManagerFactoryPtrConst
342 = QQmlNetworkAccessManagerFactoryPtrBase<const QQmlTypeLoaderNetworkAccessManagerData, const QQmlTypeLoaderLockedData>;
343
344class QQmlNetworkAccessManagerFactoryPtr
345 : public QQmlNetworkAccessManagerFactoryPtrBase<QQmlTypeLoaderNetworkAccessManagerData, QQmlTypeLoaderLockedData>
346{
347 Q_DISABLE_COPY(QQmlNetworkAccessManagerFactoryPtr)
348public:
349 Q_NODISCARD_CTOR QQmlNetworkAccessManagerFactoryPtr(QQmlTypeLoaderLockedData *lockedData)
350 : QQmlNetworkAccessManagerFactoryPtrBase<QQmlTypeLoaderNetworkAccessManagerData, QQmlTypeLoaderLockedData>(lockedData)
351 {
352 }
353
354 void reset(QQmlNetworkAccessManagerFactory *factory)
355 {
356 data->m_networkAccessManagerData.networkAccessManagerFactory = factory;
357 }
358};
359#endif // QT_CONFIG(qml_network)
360
361QT_END_NAMESPACE
362
363#endif // QQMLTYPELOADERDATA_P_H
QList< QQmlAbstractUrlInterceptor * > urlInterceptors
QV4::ExecutionEngine::DiskCacheOptions diskCacheOptions
friend class QQmlNetworkAccessManagerFactoryPtrBase
friend class QQmlTypeLoaderConfiguredDataPtrBase
QQmlTypeLoaderThread * thread() const
void createThread(QQmlTypeLoader *loader)
QV4::ExecutionEngine * engine() const
QQmlTypeLoaderSharedData()=default
ImportQmlDirCache importQmlDirCache
QSet< QString > modulesForWhichPluginsHaveBeenProcessed
QQmlTypeLoaderThreadData()=default
QStringHash< QmldirInfo * > qmldirInfo
QQmlTypeLoaderSharedDataPtrBase< QQmlTypeLoaderSharedData, QQmlTypeLoaderLockedData > QQmlTypeLoaderSharedDataPtr