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// Qt-Security score:significant
4
5#ifndef QQMLTYPELOADERDATA_P_H
6#define QQMLTYPELOADERDATA_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <private/qqmlrefcount_p.h>
20#include <private/qqmltypeloaderqmldircontent_p.h>
21#include <private/qqmltypeloaderthread_p.h>
22#include <private/qv4engine_p.h>
23
24#include <QtQml/qtqmlglobal.h>
25#include <QtQml/qqmlengine.h>
26
27#include <QtCore/qcache.h>
28#include <QtCore/qthread.h>
29
30QT_BEGIN_NAMESPACE
31
32class QQmlProfiler;
33class QQmlQmldirData;
34class QQmlScriptBlob;
35class QQmlTypeData;
36
57
59{
61public:
64
71
73
76
77 // Maps from an import to a linked list of qmldir info.
78 // Used in locateLocalQmldir()
80
81 // Modules for which plugins have been loaded and processed in the context of this type
82 // loader's engine. Plugins can have engine-specific initialization callbacks. This is why
83 // we have to keep track of this.
85
86 // Plugins that have been initialized in the context of this engine. In theory, the same
87 // plugin can be used for multiple modules. Therefore, we need to keep track of this
88 // separately from modulesForWhichPluginsHaveBeenProcessed.
90
91#if QT_CONFIG(qml_network)
94#endif
95};
96
98{
100public:
102
105
106 // URL interceptors must be set before loading any types. Otherwise we get data races.
108
109#if QT_CONFIG(qml_debug)
111#endif
112
115 bool isDebugging = false;
116 bool initialized = false;
117};
118
119#if QT_CONFIG(qml_network)
120class QQmlTypeLoaderNetworkAccessManagerData
121{
122 Q_DISABLE_COPY_MOVE(QQmlTypeLoaderNetworkAccessManagerData)
123public:
124 QQmlTypeLoaderNetworkAccessManagerData() = default;
125
126 QQmlNetworkAccessManagerFactory *networkAccessManagerFactory = nullptr;
127
128 // We need a separate mutex because the network access manger factory can be accessed not
129 // only from the engine thread and the type loader thread, but also from any WorkerScripts
130 // running in parallel to both.
131 mutable QMutex networkAccessManagerMutex;
132};
133#endif // QTCONFIG(qml_network)
134
136{
137 template<typename Data, typename LockedData>
139
140 template<typename Data, typename LockedData>
142
143 template<typename Data, typename LockedData>
145
146 template<typename Data, typename LockedData>
148 friend class QQmlNetworkAccessManagerFactoryPtr;
149
151public:
153
154 QQmlTypeLoaderThread *thread() const { return m_thread; }
155
156 void createThread(QQmlTypeLoader *loader)
157 {
158 Q_ASSERT(isCurrentJsEngineThread());
159 m_thread = new QQmlTypeLoaderThread(loader);
160 m_thread->startup();
161 }
162
164 {
165 Q_ASSERT(isCurrentJsEngineThread());
166 Q_ASSERT(m_thread);
167
168 // Shut it down first, then set it to nullptr, then delete it.
169 // This makes sure that any blobs deleted as part of the deletion
170 // do not see the thread anymore.
171 m_thread->shutdown();
172 delete std::exchange(m_thread, nullptr);
173 }
174
176 {
177 Q_ASSERT(isCurrentJsEngineThread());
178 return m_engine;
179 }
180
181private:
182 bool isCurrentJsEngineThread() const
183 {
184 if (QJSEngine *jsEngine = m_engine->jsEngine())
185 return jsEngine->thread()->isCurrentThread();
186
187 // If we can't determine the thread, assume it's the right one
188 return true;
189 }
190
191
192 QQmlTypeLoaderSharedData m_sharedData;
193 QQmlTypeLoaderThreadData m_threadData;
194 QQmlTypeLoaderConfiguredData m_configuredData;
195#if QT_CONFIG(qml_network)
197#endif
198
199 QV4::ExecutionEngine *m_engine = nullptr;
200 QQmlTypeLoaderThread *m_thread = nullptr;
201};
202
203template<typename Data, typename LockedData>
231
234using QQmlTypeLoaderSharedDataConstPtr
237template<typename Data, typename LockedData>
239{
241public:
243 {
244 Q_ASSERT(data);
245
246 // You have to either be on the type loader thread or shut it down before accessing this.
250 Data &operator*() const { return data->m_threadData; }
251 Data *operator->() const { return &data->m_threadData; }
252 operator Data *() const { return &data->m_threadData; }
253
254private:
255 LockedData *data = nullptr;
258using QQmlTypeLoaderThreadDataPtr
260using QQmlTypeLoaderThreadDataConstPtr
262
263
264template<typename Data, typename LockedData>
266{
268public:
270 {
271 Q_ASSERT(data);
272
273 if constexpr (!std::is_const_v<Data>) {
274 // const access is generally fine
275 // For mutable access we first need to make sure the thread is shut down.
276 if (data->thread())
280
281 Data &operator*() const { return data->m_configuredData; }
282 Data *operator->() const { return &data->m_configuredData; }
283 operator Data *() const { return &data->m_configuredData; }
284
285private:
286 LockedData *data = nullptr;
287};
288
289using QQmlTypeLoaderConfiguredDataPtr
291using QQmlTypeLoaderConfiguredDataConstPtr
293
294#if QT_CONFIG(qml_network)
295class QQmlEnginePublicAPIToken;
296template<typename Data, typename LockedData>
297class QQmlNetworkAccessManagerFactoryPtrBase
298{
299 Q_DISABLE_COPY_MOVE(QQmlNetworkAccessManagerFactoryPtrBase)
300public:
301 Q_NODISCARD_CTOR QQmlNetworkAccessManagerFactoryPtrBase(LockedData *data) : data(data)
302 {
303 Q_ASSERT(data);
304 data->m_networkAccessManagerData.networkAccessManagerMutex.lock();
305 }
306
307 ~QQmlNetworkAccessManagerFactoryPtrBase()
308 {
309 Q_ASSERT(data);
310 data->m_networkAccessManagerData.networkAccessManagerMutex.unlock();
311 }
312
313 QQmlNetworkAccessManagerFactory &operator*() const
314 {
315 return *data->m_networkAccessManagerData.networkAccessManagerFactory;
316 }
317
318 QQmlNetworkAccessManagerFactory *operator->() const
319 {
320 return data->m_networkAccessManagerData.networkAccessManagerFactory;
321 }
322
323 operator bool() const
324 {
325 return data->m_networkAccessManagerData.networkAccessManagerFactory != nullptr;
326 }
327
328 // This is dangerous since it allows you to subvert the locking.
329 // You must only do this when serving public API that can't be changed for now.
330 QQmlNetworkAccessManagerFactory *get(const QQmlEnginePublicAPIToken &) const
331 {
332 return data->m_networkAccessManagerData.networkAccessManagerFactory;
333 }
334
335protected:
336 LockedData *data = nullptr;
337};
338
339// This is const in the sense that you cannot reset the pointer. Therefore the "Const" postfix.
340// That's in contrast to the other *Ptr classes here that are const in the way that the _data_
341// pointed to cannot be modified.
342using QQmlNetworkAccessManagerFactoryPtrConst
343 = QQmlNetworkAccessManagerFactoryPtrBase<const QQmlTypeLoaderNetworkAccessManagerData, const QQmlTypeLoaderLockedData>;
344
345class QQmlNetworkAccessManagerFactoryPtr
346 : public QQmlNetworkAccessManagerFactoryPtrBase<QQmlTypeLoaderNetworkAccessManagerData, QQmlTypeLoaderLockedData>
347{
348 Q_DISABLE_COPY(QQmlNetworkAccessManagerFactoryPtr)
349public:
350 Q_NODISCARD_CTOR QQmlNetworkAccessManagerFactoryPtr(QQmlTypeLoaderLockedData *lockedData)
351 : QQmlNetworkAccessManagerFactoryPtrBase<QQmlTypeLoaderNetworkAccessManagerData, QQmlTypeLoaderLockedData>(lockedData)
352 {
353 }
354
355 void reset(QQmlNetworkAccessManagerFactory *factory)
356 {
357 data->m_networkAccessManagerData.networkAccessManagerFactory = factory;
358 }
359};
360#endif // QT_CONFIG(qml_network)
361
362QT_END_NAMESPACE
363
364#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
Combined button and popup list for selecting options.
QQmlTypeLoaderSharedDataPtrBase< QQmlTypeLoaderSharedData, QQmlTypeLoaderLockedData > QQmlTypeLoaderSharedDataPtr