7#include <private/qfieldlist_p.h>
8#include <private/qtqmlglobal_p.h>
10#include <QtCore/qmutex.h>
11#include <QtCore/qthread.h>
12#include <QtCore/qcoreevent.h>
13#include <QtCore/qwaitcondition.h>
14#include <QtCore/qcoreapplication.h>
21
22
23
24
26class QQmlThreadPrivate :
public QThread
29 struct ThreadObject :
public QObject
31 ThreadObject(QQmlThreadPrivate *p);
32 bool event(QEvent *e) override;
36 QQmlThreadPrivate(QQmlThread *);
39 inline void lock() { _mutex.lock(); }
40 inline void unlock() { _mutex.unlock(); }
41 inline void wait() { _wait.wait(&_mutex); }
42 inline void wakeOne() { _wait.wakeOne(); }
44 bool m_threadProcessing =
false;
45 bool m_mainProcessing =
false;
46 bool m_mainThreadWaiting =
false;
47 bool m_shutdown =
false;
49 typedef QFieldList<QQmlThread::Message, &QQmlThread::Message::next> MessageList;
50 MessageList threadList;
53 QQmlThread::Message *mainSync =
nullptr;
54 ThreadObject m_threadObject;
56 void triggerMainEvent();
57 void triggerThreadEvent();
63 bool event(QEvent *) override;
79 QCoreApplication::postEvent(
this,
new QEvent(QEvent::User));
86 QCoreApplication::postEvent(&m_threadObject,
new QEvent(QEvent::User));
91 if (e->type() == QEvent::User)
93 return QObject::event(e);
98 setObjectName(QStringLiteral(
"QQmlThread"));
101 setStackSize(8 * 1024 * 1024);
106 if (e->type() == QEvent::User)
108 return QThread::event(e);
115 m_mainProcessing =
true;
117 while (!mainList.isEmpty() || mainSync) {
118 bool isSync = mainSync !=
nullptr;
119 QQmlThread::Message *message = isSync?mainSync:mainList.takeFirst();
133 m_mainProcessing =
false;
143 if (!threadList.isEmpty()) {
144 m_threadProcessing =
true;
146 QQmlThread::Message *message = threadList.first();
154 delete threadList.takeFirst();
158 m_threadProcessing =
false;
178
179
180
183 Q_ASSERT(!d->m_shutdown);
185 d->m_threadObject.moveToThread(d);
197 if (!d->mainList.isEmpty() || d->mainSync)
198 QCoreApplication::postEvent(d,
new QEvent(QEvent::User));
200 if (!d->threadList.isEmpty())
201 d->triggerThreadEvent();
213 Q_ASSERT(!d->m_shutdown);
214 d->m_shutdown =
true;
224 d->m_shutdown =
false;
229 return d->isRunning();
254 return d->isCurrentThread();
260 return d->thread()->isCurrentThread();
265 return const_cast<QThread *>(
static_cast<
const QThread *>(d));
269
270
271
272
275 return &d->m_threadObject;
278void QQmlThread::internalCallMethodInThread(Message *message)
282 Q_ASSERT(d->m_mainThreadWaiting ==
false);
284 bool wasEmpty = d->threadList.isEmpty();
285 d->threadList.append(message);
286 if (wasEmpty && d->m_threadProcessing ==
false)
287 d->triggerThreadEvent();
289 d->m_mainThreadWaiting =
true;
298 d->mainSync =
nullptr;
303 }
while (d->mainSync || !d->threadList.isEmpty());
305 d->m_mainThreadWaiting =
false;
310
311
312
313
314
315
316void QQmlThread::internalCallMethodInMain(Message *message)
321 Q_ASSERT(d->mainSync ==
nullptr);
322 d->mainSync = message;
324 if (d->m_mainThreadWaiting) {
326 }
else if (d->m_mainProcessing) {
329 d->triggerMainEvent();
332 while (d->mainSync) {
335 d->mainSync =
nullptr;
344void QQmlThread::internalPostMethodToThread(Message *message)
348 bool wasEmpty = d->threadList.isEmpty();
349 d->threadList.append(message);
350 if (wasEmpty && d->m_threadProcessing ==
false)
351 d->triggerThreadEvent();
355void QQmlThread::internalPostMethodToMain(Message *message)
359 bool wasEmpty = d->mainList.isEmpty();
360 d->mainList.append(message);
361 if (wasEmpty && d->m_mainProcessing ==
false)
362 d->triggerMainEvent();
367
368
369
370
371
372
373
374
375
376
380 Q_ASSERT(d->m_mainThreadWaiting ==
false);
382 d->m_mainThreadWaiting =
true;
384 if (d->mainSync || !d->threadList.isEmpty()) {
391 d->mainSync =
nullptr;
398 d->m_mainThreadWaiting =
false;
402
403
404
405
406
407
411 if (Message *mainSync = std::exchange(d->mainSync,
nullptr))
413 while (!d->mainList.isEmpty())
414 delete d->mainList.takeFirst();
415 while (!d->threadList.isEmpty())
416 delete d->threadList.takeFirst();
QQmlThreadPrivate(QQmlThread *q)
QFieldList< QQmlThread::Message, &QQmlThread::Message::next > MessageList
bool event(QEvent *e) override
This virtual function receives events to an object and should return true if the event e was recogniz...
bool isThisThread() const
void waitForNextMessage()
bool isParentThread() const
QObject * threadObject() const
QT_REQUIRE_CONFIG(liburing)