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
qthread.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6#ifndef QTHREAD_H
7#define QTHREAD_H
8
9#include <QtCore/qobject.h>
10#include <QtCore/qdeadlinetimer.h>
11
12// For QThread::create
13#include <future> // for std::async
14#include <functional> // for std::invoke; no guard needed as it's a C++98 header
15// internal compiler error with mingw 8.1
16#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86)
17#include <intrin.h>
18#endif
19
20QT_BEGIN_NAMESPACE
21
22
23class QThreadData;
24class QThreadPrivate;
25class QAbstractEventDispatcher;
27
28class Q_CORE_EXPORT QThread : public QObject
29{
30 Q_OBJECT
31public:
32 Q_DECL_PURE_FUNCTION static Qt::HANDLE currentThreadId() noexcept;
33 static QThread *currentThread();
34 static bool isMainThread() noexcept;
35 static int idealThreadCount() noexcept;
36 static void yieldCurrentThread();
37
38 explicit QThread(QObject *parent = nullptr);
39 ~QThread();
40
41 enum Priority {
42 IdlePriority,
43
44 LowestPriority,
45 LowPriority,
46 NormalPriority,
47 HighPriority,
48 HighestPriority,
49
50 TimeCriticalPriority,
51
52 InheritPriority
53 };
54
55 enum class QualityOfService {
56 Auto,
57 High,
58 Eco,
59 };
60 Q_ENUM(QualityOfService)
61
62 void setPriority(Priority priority);
63 Priority priority() const;
64
65 bool isFinished() const;
66 bool isRunning() const;
67
68 void requestInterruption();
69 bool isInterruptionRequested() const;
70
71 void setStackSize(uint stackSize);
72 uint stackSize() const;
73
74 QAbstractEventDispatcher *eventDispatcher() const;
75 void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher);
76
77 bool event(QEvent *event) override;
78 int loopLevel() const;
79
80 bool isCurrentThread() const noexcept;
81
82 void setServiceLevel(QualityOfService serviceLevel);
83 QualityOfService serviceLevel() const;
84
85 template <typename Function, typename... Args>
86 [[nodiscard]] static QThread *create(Function &&f, Args &&... args);
87
88public Q_SLOTS:
89 void start(Priority = InheritPriority);
90 void terminate();
91 void exit(int retcode = 0);
92 void quit();
93
94public:
95 bool wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever));
96 bool wait(unsigned long time)
97 {
98 if (time == (std::numeric_limits<unsigned long>::max)())
99 return wait(QDeadlineTimer(QDeadlineTimer::Forever));
100 return wait(QDeadlineTimer(time));
101 }
102
103 static void sleep(unsigned long);
104 static void msleep(unsigned long);
105 static void usleep(unsigned long);
106 static void sleep(std::chrono::nanoseconds nsec);
107
108Q_SIGNALS:
109 void started(QPrivateSignal);
110 void finished(QPrivateSignal);
111
112protected:
113 virtual void run();
114 int exec();
115
116 static void setTerminationEnabled(bool enabled = true);
117
118protected:
119 QThread(QThreadPrivate &dd, QObject *parent = nullptr);
120
121private:
122 Q_DECLARE_PRIVATE(QThread)
123 friend class QEventLoopLocker;
124
125 [[nodiscard]] static QThread *createThreadImpl(std::future<void> &&future);
126 Q_DECL_PURE_FUNCTION static Qt::HANDLE currentThreadIdImpl() noexcept;
127
128 friend class QCoreApplication;
129 friend class QThreadData;
130};
131
132template <typename Function, typename... Args>
133QThread *QThread::create(Function &&f, Args &&... args)
134{
135 using DecayedFunction = typename std::decay<Function>::type;
136 auto threadFunction =
137 [f = static_cast<DecayedFunction>(std::forward<Function>(f))](auto &&... largs) mutable -> void
138 {
139 (void)std::invoke(std::move(f), std::forward<decltype(largs)>(largs)...);
140 };
141
142 return createThreadImpl(std::async(std::launch::deferred,
143 std::move(threadFunction),
144 std::forward<Args>(args)...));
145}
146
147/*
148 On architectures and platforms we know, interpret the thread control
149 block (TCB) as a unique identifier for a thread within a process. Otherwise,
150 fall back to a slower but safe implementation.
151
152 As per the documentation of currentThreadId, we return an opaque handle
153 as a thread identifier, and application code is not supposed to use that
154 value for anything. In Qt we use the handle to check if threads are identical,
155 for which the TCB is sufficient.
156
157 So we use the fastest possible way, rather than spend time on returning
158 some pseudo-interoperable value.
159*/
160inline Qt::HANDLE QThread::currentThreadId() noexcept
161{
162 // define is undefed if we have to fall back to currentThreadIdImpl
163#define QT_HAS_FAST_CURRENT_THREAD_ID
164 Qt::HANDLE tid; // typedef to void*
165 static_assert(sizeof(tid) == sizeof(void*));
166 // See https://akkadia.org/drepper/tls.pdf for x86 ABI
167#if defined(Q_PROCESSOR_X86_32) && ((defined(Q_OS_LINUX) && defined(__GLIBC__)) || defined(Q_OS_FREEBSD)) // x86 32-bit always uses GS
168 __asm__("mov %%gs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : );
169#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_DARWIN)
170 // 64bit macOS uses GS, see https://github.com/apple/darwin-xnu/blob/master/libsyscall/os/tsd.h
171 __asm__("mov %%gs:0, %0" : "=r" (tid) : : );
172#elif defined(Q_PROCESSOR_X86_64) && ((defined(Q_OS_LINUX) && defined(__GLIBC__)) || defined(Q_OS_FREEBSD))
173 // x86_64 Linux, BSD uses FS
174 __asm__("mov %%fs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : );
175#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_WIN)
176 // See https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
177 // First get the pointer to the TIB
178 quint8 *tib;
179# if defined(Q_CC_MINGW) // internal compiler error when using the intrinsics
180 __asm__("movq %%gs:0x30, %0" : "=r" (tib) : :);
181# else
182 tib = reinterpret_cast<quint8 *>(__readgsqword(0x30));
183# endif
184 // Then read the thread ID
185 tid = *reinterpret_cast<Qt::HANDLE *>(tib + 0x48);
186#elif defined(Q_PROCESSOR_X86_32) && defined(Q_OS_WIN)
187 // First get the pointer to the TIB
188 quint8 *tib;
189# if defined(Q_CC_MINGW) // internal compiler error when using the intrinsics
190 __asm__("movl %%fs:0x18, %0" : "=r" (tib) : :);
191# else
192 tib = reinterpret_cast<quint8 *>(__readfsdword(0x18));
193# endif
194 // Then read the thread ID
195 tid = *reinterpret_cast<Qt::HANDLE *>(tib + 0x24);
196#else
197#undef QT_HAS_FAST_CURRENT_THREAD_ID
198 tid = currentThreadIdImpl();
199#endif
200 return tid;
201}
202
203QT_END_NAMESPACE
204
205#endif // QTHREAD_H
QByteArray & operator*() noexcept
Definition qbytearray.h:797
QByteArray::Base64DecodingStatus decodingStatus
Definition qbytearray.h:782
friend bool operator==(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
Returns true if lhs and rhs are equal, otherwise returns false.
Definition qbytearray.h:801
void swap(QByteArray::FromBase64Result &other) noexcept
Definition qbytearray.h:784
operator bool() const noexcept
\variable QByteArray::FromBase64Result::decoded
Definition qbytearray.h:790
const QByteArray & operator*() const noexcept
Returns the decoded byte array.
Definition qbytearray.h:798
friend bool operator!=(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
Returns true if lhs and rhs are different, otherwise returns false.
Definition qbytearray.h:812
\inmodule QtCore
Definition qbytearray.h:58
\inmodule QtCore\reentrant
Definition qdatastream.h:50
\inmodule QtCore
Definition qeventloop.h:59
int initFrom(const QMessageLogContext &logContext)
void populateBacktrace(int frameCount)
QInternalMessageLogContext(const QMessageLogContext &logContext, const QLoggingCategory &categoryOverride)
Definition qlogging_p.h:65
std::optional< BacktraceStorage > backtrace
Definition qlogging_p.h:57
static constexpr int DefaultBacktraceDepth
Definition qlogging_p.h:47
Definition qlist.h:80
\inmodule QtCore
Definition qlogging.h:43
constexpr QMessageLogContext(const char *fileName, int lineNumber, const char *functionName, const char *categoryName) noexcept
Definition qlogging.h:48
const char * category
Definition qlogging.h:55
constexpr QMessageLogContext() noexcept=default
const char * function
Definition qlogging.h:54
const char * file
Definition qlogging.h:53
\inmodule QtCore
Definition qlogging.h:73
QDebug debug(CategoryFunction catFunc) const
QDebug debug(const QLoggingCategory &cat) const
Logs a debug message into category cat using a QDebug stream.
Definition qlogging.cpp:525
void void void void Q_DECL_COLD_FUNCTION void Q_DECL_COLD_FUNCTION void Q_DECL_COLD_FUNCTION void Q_DECL_COLD_FUNCTION void QT_MESSAGE_LOGGER_NORETURN Q_DECL_COLD_FUNCTION void QT_MESSAGE_LOGGER_NORETURN Q_DECL_COLD_FUNCTION void QDebug debug() const
Logs a debug message using a QDebug stream.
Definition qlogging.cpp:511
QDebug info(const QLoggingCategory &cat) const
Logs an informational message into the category cat using a QDebug stream.
Definition qlogging.cpp:614
QDebug info() const
Logs an informational message using a QDebug stream.
Definition qlogging.cpp:600
QNoDebug noDebug(...) const noexcept
QDebug info(CategoryFunction catFunc) const
static Q_CONSTINIT thread_local bool msgHandlerGrabbed
static const char ifCriticalTokenC[]
static bool grabMessageHandler()
void qt_message_output(QtMsgType msgType, const QMessageLogContext &context, const QString &message)
static const char emptyTokenC[]
static Q_NEVER_INLINE void qt_message(QtMsgType msgType, const QMessageLogContext &context, const char *msg, va_list ap)
Definition qlogging.cpp:408
static void preformattedMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &formattedMessage)
static bool systemHasStderr()
Returns true if writing to stderr is supported.
Definition qlogging.cpp:262
static const char endifTokenC[]
static bool isDefaultCategory(const char *category)
Definition qlogging.cpp:954
static const char messageTokenC[]
static bool qt_append_thread_name_to(QString &message)
Definition qlogging.cpp:247
static constexpr SystemMessageSink systemMessageSink
static void qt_maybe_message_fatal(QtMsgType, const QMessageLogContext &context, String &&message)
\inmodule QtCore \title Qt Logging Types
#define HANDLE_IF_TOKEN(LEVEL)
Q_DECLARE_TYPEINFO(QMessagePattern::BacktraceParams, Q_RELOCATABLE_TYPE)
static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &buf)
static const char timeTokenC[]
static bool isFatalCountDown(const char *varname, QBasicAtomicInt &n)
Definition qlogging.cpp:152
void qErrnoWarning(int code, const char *msg,...)
static const char qthreadptrTokenC[]
static const char fileTokenC[]
static const char ifDebugTokenC[]
static const char ifFatalTokenC[]
static const char categoryTokenC[]
static void stderr_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &formattedMessage)
static const char lineTokenC[]
static const char typeTokenC[]
static void ungrabMessageHandler()
static void copyInternalContext(QInternalMessageLogContext *self, const QMessageLogContext &logContext) noexcept
static const char ifCategoryTokenC[]
static int checked_var_value(const char *varname)
Definition qlogging.cpp:138
static const char threadnameTokenC[]
static const char pidTokenC[]
Q_TRACE_POINT(qtcore, qt_message_print, int type, const char *category, const char *function, const char *file, int line, const QString &message)
static const char threadidTokenC[]
static QString formatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)
static const char backtraceTokenC[]
void qErrnoWarning(const char *msg,...)
static const char functionTokenC[]
#define IF_TOKEN(LEVEL)
static const char ifWarningTokenC[]
static const char appnameTokenC[]
static bool isFatal(QtMsgType msgType)
Definition qlogging.cpp:186
static const char ifInfoTokenC[]
QtMessageHandler qInstallMessageHandler(QtMessageHandler h)
static void qt_message_print(QtMsgType, const QMessageLogContext &context, const QString &message)
static bool stderrHasConsoleAttached()
Returns true if writing to stderr will end up in a console/terminal visible to the user.
Definition qlogging.cpp:287
void qSetMessagePattern(const QString &pattern)
QDebug printAssociativeContainer(QDebug debug, const char *which, const AssociativeContainer &c)
Definition qdebug.h:385
bool shouldLogToStderr()
Returns true if logging stderr should be ensured.
Definition qlogging.cpp:340
QDebug printSequentialContainer(QDebug debug, const char *which, const SequentialContainer &c)
Definition qdebug.h:367
QByteArray operator""_ba(const char *str, size_t size) noexcept
Definition qbytearray.h:847
Definition qcompare.h:76
QT_BEGIN_NAMESPACE Q_NORETURN void qAbort()
Definition qassert.cpp:24
QByteArray operator+(const QByteArray &a1, const char *a2)
Definition qbytearray.h:703
QByteArray qUncompress(const QByteArray &data)
Definition qbytearray.h:772
QByteArray operator+(char a1, const QByteArray &a2)
Definition qbytearray.h:713
QByteArray operator+(QByteArray &&lhs, char rhs)
Definition qbytearray.h:709
QByteArray operator+(const QByteArray &a1, char a2)
Definition qbytearray.h:707
QByteArray operator+(const char *a1, const QByteArray &a2)
Definition qbytearray.h:711
QByteArray operator+(QByteArray &&lhs, const QByteArray &rhs)
Definition qbytearray.h:701
qsizetype erase_if(QByteArray &ba, Predicate pred)
Definition qbytearray.h:830
QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
Definition qbytearray.h:699
QByteArray qCompress(const QByteArray &data, int compressionLevel=-1)
Definition qbytearray.h:770
#define QT5_NULL_STRINGS
Definition qbytearray.h:26
qsizetype erase(QByteArray &ba, const T &t)
Definition qbytearray.h:824
QByteArray operator+(QByteArray &&lhs, const char *rhs)
Definition qbytearray.h:705
#define __has_builtin(x)
#define __has_include(x)
#define __has_cpp_attribute(x)
void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, Int value)
Definition qdebug.h:614
Q_CORE_EXPORT void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, quint64 value)
Definition qdebug.cpp:1428
Q_CORE_EXPORT void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, uint value)
Definition qdebug.cpp:1419
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2568
#define QT_MESSAGELOG_FUNC
Definition qlogging.h:161
#define QT_MESSAGELOG_FILE
Definition qlogging.h:159
#define QT_MESSAGE_LOGGER_NORETURN
Definition qlogging.h:69
#define QT_MESSAGELOG_LINE
Definition qlogging.h:160
Q_CORE_EXPORT void qSetMessagePattern(const QString &messagePattern)
#define QT_MESSAGELOGCONTEXT
Definition qlogging.h:154
QtMsgType
Definition qlogging.h:29
@ QtCriticalMsg
Definition qlogging.h:33
@ QtFatalMsg
Definition qlogging.h:34
@ QtDebugMsg
Definition qlogging.h:30
Q_CORE_EXPORT void qt_message_output(QtMsgType, const QMessageLogContext &context, const QString &message)
void(* QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &)
Definition qlogging.h:196
QMutex QBasicMutex
Definition qmutex.h:360
void setPattern(const QString &pattern)
std::unique_ptr< std::unique_ptr< const char[]>[]> literals
std::chrono::steady_clock::time_point appStartTime
std::unique_ptr< const char *[]> tokens
QList< QString > timeArgs
static QBasicMutex mutex
void setDefaultPattern()
static constexpr bool Value
Definition qdebug.h:679
static constexpr bool Value
Definition qdebug.h:675