6#include <private/qfieldlist_p.h>
7#include <private/qtqmlglobal_p.h>
9#include <QtCore/qmutex.h>
10#include <QtCore/qthread.h>
11#include <QtCore/qcoreevent.h>
12#include <QtCore/qwaitcondition.h>
13#include <QtCore/qcoreapplication.h>
19class QQmlThreadPrivate :
public QThread
22 struct ThreadObject :
public QObject
24 ThreadObject(QQmlThreadPrivate *p);
25 bool event(QEvent *e) override;
29 QQmlThreadPrivate(QQmlThread *);
32 inline void lock() { _mutex.lock(); }
33 inline void unlock() { _mutex.unlock(); }
34 inline void wait() { _wait.wait(&_mutex); }
35 inline void wakeOne() { _wait.wakeOne(); }
37 bool m_threadProcessing =
false;
38 bool m_mainProcessing =
false;
39 bool m_mainThreadWaiting =
false;
40 bool m_shutdown =
false;
42 typedef QFieldList<QQmlThread::Message, &QQmlThread::Message::next> MessageList;
43 MessageList threadList;
46 QQmlThread::Message *mainSync =
nullptr;
47 ThreadObject m_threadObject;
49 void triggerMainEvent();
50 void triggerThreadEvent();
56 bool event(QEvent *) override;
63QQmlThreadPrivate::ThreadObject::ThreadObject(QQmlThreadPrivate *p)
69void QQmlThreadPrivate::triggerMainEvent()
72 QCoreApplication::postEvent(
this,
new QEvent(QEvent::User));
76void QQmlThreadPrivate::triggerThreadEvent()
79 QCoreApplication::postEvent(&m_threadObject,
new QEvent(QEvent::User));
82bool QQmlThreadPrivate::ThreadObject::event(QEvent *e)
84 if (e->type() == QEvent::User)
86 return QObject::event(e);
91 setObjectName(QStringLiteral(
"QQmlThread"));
94 setStackSize(8 * 1024 * 1024);
97bool QQmlThreadPrivate::
event(QEvent *e)
99 if (e->type() == QEvent::User)
101 return QThread::event(e);
104void QQmlThreadPrivate::mainEvent()
108 m_mainProcessing =
true;
110 while (!mainList.isEmpty() || mainSync) {
111 bool isSync = mainSync !=
nullptr;
112 QQmlThread::Message *message = isSync?mainSync:mainList.takeFirst();
126 m_mainProcessing =
false;
131void QQmlThreadPrivate::threadEvent()
136 if (!threadList.isEmpty()) {
137 m_threadProcessing =
true;
139 QQmlThread::Message *message = threadList.first();
147 delete threadList.takeFirst();
151 m_threadProcessing =
false;
161: d(
new QQmlThreadPrivate
(this))
171
172
173
176 Q_ASSERT(!d->m_shutdown);
178 d->m_threadObject.moveToThread(d);
188 Q_ASSERT(!d->m_shutdown);
189 d->m_shutdown =
true;
203 d->m_shutdown =
false;
228 return d->isCurrentThread();
233 return const_cast<QThread *>(
static_cast<
const QThread *>(d));
237
238
241 return &d->m_threadObject;
244void QQmlThread::internalCallMethodInThread(Message *message)
248 Q_ASSERT(d->m_mainThreadWaiting ==
false);
250 bool wasEmpty = d->threadList.isEmpty();
251 d->threadList.append(message);
252 if (wasEmpty && d->m_threadProcessing ==
false)
253 d->triggerThreadEvent();
255 d->m_mainThreadWaiting =
true;
264 d->mainSync =
nullptr;
269 }
while (d->mainSync || !d->threadList.isEmpty());
271 d->m_mainThreadWaiting =
false;
276
277
278
279
280
281
282void QQmlThread::internalCallMethodInMain(Message *message)
287 Q_ASSERT(d->mainSync ==
nullptr);
288 d->mainSync = message;
290 if (d->m_mainThreadWaiting) {
292 }
else if (d->m_mainProcessing) {
295 d->triggerMainEvent();
298 while (d->mainSync) {
301 d->mainSync =
nullptr;
310void QQmlThread::internalPostMethodToThread(Message *message)
314 bool wasEmpty = d->threadList.isEmpty();
315 d->threadList.append(message);
316 if (wasEmpty && d->m_threadProcessing ==
false)
317 d->triggerThreadEvent();
321void QQmlThread::internalPostMethodToMain(Message *message)
325 bool wasEmpty = d->mainList.isEmpty();
326 d->mainList.append(message);
327 if (wasEmpty && d->m_mainProcessing ==
false)
328 d->triggerMainEvent();
333
334
335
336
337
338
339
340
341
342
346 Q_ASSERT(d->m_mainThreadWaiting ==
false);
348 d->m_mainThreadWaiting =
true;
350 if (d->mainSync || !d->threadList.isEmpty()) {
357 d->mainSync =
nullptr;
364 d->m_mainThreadWaiting =
false;
368
369
370
371
372
373
377 if (Message *mainSync = std::exchange(d->mainSync,
nullptr))
379 while (!d->mainList.isEmpty())
380 delete d->mainList.takeFirst();
381 while (!d->threadList.isEmpty())
382 delete d->threadList.takeFirst();
QQmlThreadPrivate(QQmlThread *q)
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()
QObject * threadObject() const
And object living in the QML thread, in case you want to parent other objects to it.
QT_REQUIRE_CONFIG(itemmodel)