21#include "QtCore/qthread.h"
23#include "QtCore/qcoreapplication.h"
24#include "private/qobject_p.h"
25#include "QtCore/qmap.h"
26#include "QtCore/qmutex.h"
27#include "QtCore/qstack.h"
30#include "private/qthreadstorage_p.h"
31#include "QtCore/qwaitcondition.h"
38class QAbstractEventDispatcher;
91
92
93
94
95
96
97
98
99
100
101
114 auto status = bindingStatus();
126 return !isNull(data) && !isList(data);
128 static bool isList(quintptr data)
noexcept {
return data & 1; }
129 static bool isNull(quintptr data)
noexcept {
return data == 0; }
135 const auto d = data.load(std::memory_order_acquire);
136 if (isBindingStatus(d))
137 return reinterpret_cast<QBindingStatus *>(d);
145 return decodeList(data.load(std::memory_order_relaxed));
149 static List *decodeList(quintptr ptr)
noexcept
152 return reinterpret_cast<List *>(ptr & ~1);
157 static quintptr encodeBindingStatus(QBindingStatus *status)
noexcept
159 return quintptr(status);
162 static quintptr encodeList(List *list)
noexcept
164 return quintptr(list) | 1;
167 std::atomic<quintptr> data;
174class Q_CORE_EXPORT QDaemonThread :
public QThread
177 QDaemonThread(QObject *parent =
nullptr);
181class Q_AUTOTEST_EXPORT QThreadPrivate :
public QObjectPrivate
183 Q_DECLARE_PUBLIC(QThread)
186 QThreadPrivate(QThreadData *d =
nullptr);
189 void setPriority(QThread::Priority prio);
190 Qt::HANDLE threadId()
const noexcept;
192 mutable QMutex mutex;
193 QAtomicInt quitLockRef;
195 enum State : quint8 {
204 State threadState = NotStarted;
206 std::atomic<
bool> interruptionRequested =
false;
208 bool terminated =
false;
215 std::underlying_type_t<QThread::Priority> priority = QThread::InheritPriority;
217 bool wait(QMutexLocker<QMutex> &locker, QDeadlineTimer deadline);
219 QThread::QualityOfService serviceLevel = QThread::QualityOfService::Auto;
220 void setQualityOfServiceLevel(QThread::QualityOfService qosLevel);
222 qos_class_t nativeQualityOfServiceClass()
const;
226 QWaitCondition thread_done;
229 static void *start(
void *arg);
235 static unsigned int __stdcall start(
void *)
noexcept;
236 void finish(
bool lockAnyway =
true)
noexcept;
239 bool terminationEnabled, terminatePending;
242 static int idealThreadCount;
246 static QAbstractEventDispatcher *createEventDispatcher(QThreadData *data);
255 if (!quitLockRef.deref() && threadState == Running) {
256 QCoreApplication::instance()->postEvent(q_ptr,
new QEvent(QEvent::Quit));
260 QBindingStatus *bindingStatus();
263
264
265 QBindingStatus *addObjectWithPendingBindingStatusChange(QObject *obj);
266 void removeObjectWithPendingBindingStatusChange(QObject *obj);
268#ifndef Q_OS_INTEGRITY
299 Q_DECLARE_PUBLIC(QThread)
316 if (QThreadData *data = currentThreadData()) Q_LIKELY_BRANCH
318 return createCurrentThreadData();
322 { Q_ASSERT_X(thread !=
nullptr,
"QThread",
"internal error");
return thread->d_func()->data; }
340 {
return eventDispatcher.loadRelaxed() !=
nullptr; }
344 QAbstractEventDispatcher *ed = eventDispatcher.loadRelaxed();
352 QMutexLocker locker(&postEventList.mutex);
360 auto status = m_statusOrPendingObjects.bindingStatus();
362 QtPrivate::setBindingStatus(status, {});
387 friend class QAbstractEventDispatcher;
388 friend class QBasicTimer;
398 : threadData(threadData)
407 Q_DECLARE_PRIVATE(QThread)
421inline QBindingStatus *QThreadPrivate::bindingStatus()
423 return data->m_statusOrPendingObjects.bindingStatus();
void addEvent(const QPostEvent &ev)
qsizetype insertionOffset
QPostEvent(QObject *r, QEvent *e, int p)
QScopedScopeLevelCounter(QThreadData *threadData)
~QScopedScopeLevelCounter()
QStack< QEventLoop * > eventLoops
QAtomicPointer< QAbstractEventDispatcher > eventDispatcher
QtPrivate::BindingStatusOrList m_statusOrPendingObjects
static QThreadData * current()
void reuseBindingStatusForNewNativeThread()
QThreadData(int initialRefCount=1)
bool requiresCoreApplication
static void clearCurrentThreadData()
QAtomicPointer< void > threadId
static QThreadData * get2(QThread *thread)
QAbstractEventDispatcher * ensureEventDispatcher()
QPostEventList postEventList
bool hasEventDispatcher() const
QAtomicPointer< QThread > thread
QAbstractEventDispatcher * createEventDispatcher()
static void setCurrentThread(QThread *)
static QAbstractEventDispatcher * createEventDispatcher(QThreadData *data)
QThreadPrivate(QThreadData *d=nullptr)
void removeObjectWithPendingBindingStatusChange(QObject *)
QBindingStatus * m_bindingStatus
QBindingStatus * bindingStatus()
QBindingStatus * addObjectWithPendingBindingStatusChange(QObject *)
List * list() const noexcept
static bool isBindingStatus(quintptr data) noexcept
static bool isNull(quintptr data) noexcept
void removeObject(QObject *object)
void setStatusAndClearList(QBindingStatus *status) noexcept
constexpr BindingStatusOrList() noexcept
QBindingStatus * addObjectUnlessAlreadyStatus(QObject *object)
BindingStatusOrList(QBindingStatus *status) noexcept
QBindingStatus * bindingStatus() const noexcept
static bool isList(quintptr data) noexcept
Q_DECLARE_TYPEINFO(QPostEvent, Q_RELOCATABLE_TYPE)
bool operator<(const QPostEvent &first, const QPostEvent &second)