Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
5#ifndef QTHREAD_H
6#define QTHREAD_H
7
8#include <QtCore/qobject.h>
9#include <QtCore/qdeadlinetimer.h>
10
11// For QThread::create
12#include <future> // for std::async
13#include <functional> // for std::invoke; no guard needed as it's a C++98 header
14// internal compiler error with mingw 8.1
15#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86)
16#include <intrin.h>
17#endif
18
20
21
22class QThreadData;
23class QThreadPrivate;
26
27class Q_CORE_EXPORT QThread : public QObject
28{
30public:
31 static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION;
32 static QThread *currentThread();
33 static bool isMainThread();
34 static int idealThreadCount() noexcept;
35 static void yieldCurrentThread();
36
37 explicit QThread(QObject *parent = nullptr);
38 ~QThread();
39
53
54 void setPriority(Priority priority);
56
57 bool isFinished() const;
58 bool isRunning() const;
59
60 void requestInterruption();
61 bool isInterruptionRequested() const;
62
63 void setStackSize(uint stackSize);
64 uint stackSize() const;
65
66 QAbstractEventDispatcher *eventDispatcher() const;
67 void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher);
68
69 bool event(QEvent *event) override;
70 int loopLevel() const;
71
72 bool isCurrentThread() const;
73
74 template <typename Function, typename... Args>
75 [[nodiscard]] static QThread *create(Function &&f, Args &&... args);
76
77public Q_SLOTS:
78 void start(Priority = InheritPriority);
79 void terminate();
80 void exit(int retcode = 0);
81 void quit();
82
83public:
85 bool wait(unsigned long time)
86 {
87 if (time == (std::numeric_limits<unsigned long>::max)())
89 return wait(QDeadlineTimer(time));
90 }
91
92 static void sleep(unsigned long);
93 static void msleep(unsigned long);
94 static void usleep(unsigned long);
95 static void sleep(std::chrono::nanoseconds nsec);
96
98 void started(QPrivateSignal);
99 void finished(QPrivateSignal);
100
101protected:
102 virtual void run();
103 int exec();
104
105 static void setTerminationEnabled(bool enabled = true);
106
107protected:
108 QThread(QThreadPrivate &dd, QObject *parent = nullptr);
109
110private:
111 Q_DECLARE_PRIVATE(QThread)
112 friend class QEventLoopLocker;
113
114 [[nodiscard]] static QThread *createThreadImpl(std::future<void> &&future);
115 static Qt::HANDLE currentThreadIdImpl() noexcept Q_DECL_PURE_FUNCTION;
116
117 friend class QCoreApplication;
118 friend class QThreadData;
119};
120
121template <typename Function, typename... Args>
123{
124 using DecayedFunction = typename std::decay<Function>::type;
125 auto threadFunction =
126 [f = static_cast<DecayedFunction>(std::forward<Function>(f))](auto &&... largs) mutable -> void
127 {
128 (void)std::invoke(std::move(f), std::forward<decltype(largs)>(largs)...);
129 };
130
131 return createThreadImpl(std::async(std::launch::deferred,
132 std::move(threadFunction),
133 std::forward<Args>(args)...));
134}
135
136/*
137 On architectures and platforms we know, interpret the thread control
138 block (TCB) as a unique identifier for a thread within a process. Otherwise,
139 fall back to a slower but safe implementation.
140
141 As per the documentation of currentThreadId, we return an opaque handle
142 as a thread identifier, and application code is not supposed to use that
143 value for anything. In Qt we use the handle to check if threads are identical,
144 for which the TCB is sufficient.
145
146 So we use the fastest possible way, rather than spend time on returning
147 some pseudo-interoperable value.
148*/
150{
151 // define is undefed if we have to fall back to currentThreadIdImpl
152#define QT_HAS_FAST_CURRENT_THREAD_ID
153 Qt::HANDLE tid; // typedef to void*
154 static_assert(sizeof(tid) == sizeof(void*));
155 // See https://akkadia.org/drepper/tls.pdf for x86 ABI
156#if defined(Q_PROCESSOR_X86_32) && ((defined(Q_OS_LINUX) && defined(__GLIBC__)) || defined(Q_OS_FREEBSD)) // x86 32-bit always uses GS
157 __asm__("mov %%gs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : );
158#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_DARWIN)
159 // 64bit macOS uses GS, see https://github.com/apple/darwin-xnu/blob/master/libsyscall/os/tsd.h
160 __asm__("mov %%gs:0, %0" : "=r" (tid) : : );
161#elif defined(Q_PROCESSOR_X86_64) && ((defined(Q_OS_LINUX) && defined(__GLIBC__)) || defined(Q_OS_FREEBSD))
162 // x86_64 Linux, BSD uses FS
163 __asm__("mov %%fs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : );
164#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_WIN)
165 // See https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
166 // First get the pointer to the TIB
167 quint8 *tib;
168# if defined(Q_CC_MINGW) // internal compiler error when using the intrinsics
169 __asm__("movq %%gs:0x30, %0" : "=r" (tib) : :);
170# else
171 tib = reinterpret_cast<quint8 *>(__readgsqword(0x30));
172# endif
173 // Then read the thread ID
174 tid = *reinterpret_cast<Qt::HANDLE *>(tib + 0x48);
175#elif defined(Q_PROCESSOR_X86_32) && defined(Q_OS_WIN)
176 // First get the pointer to the TIB
177 quint8 *tib;
178# if defined(Q_CC_MINGW) // internal compiler error when using the intrinsics
179 __asm__("movl %%fs:0x18, %0" : "=r" (tib) : :);
180# else
181 tib = reinterpret_cast<quint8 *>(__readfsdword(0x18));
182# endif
183 // Then read the thread ID
184 tid = *reinterpret_cast<Qt::HANDLE *>(tib + 0x24);
185#else
186#undef QT_HAS_FAST_CURRENT_THREAD_ID
187 tid = currentThreadIdImpl();
188#endif
189 return tid;
190}
191
193
194#endif // QTHREAD_H
\inmodule QtCore
\inmodule QtCore
static constexpr ForeverConstant Forever
\inmodule QtCore
Definition qeventloop.h:59
\inmodule QtCore
Definition qcoreevent.h:45
\inmodule QtCore
Definition qobject.h:103
static bool isMainThread()
bool wait(unsigned long time)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qthread.h:85
static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION
Definition qthread.h:149
@ LowPriority
Definition qthread.h:44
@ LowestPriority
Definition qthread.h:43
@ TimeCriticalPriority
Definition qthread.h:49
@ HighestPriority
Definition qthread.h:47
@ IdlePriority
Definition qthread.h:41
@ NormalPriority
Definition qthread.h:45
@ HighPriority
Definition qthread.h:46
Priority priority() const
void finished(QPrivateSignal)
void setPriority(Priority priority)
int loopLevel() const
void started(QPrivateSignal)
Combined button and popup list for selecting options.
Definition qcompare.h:63
void * HANDLE
#define Q_DECL_PURE_FUNCTION
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
GLuint start
struct _cl_event * event
static bool isRunning()
Definition main.cpp:452
#define Q_OBJECT
#define Q_SLOTS
#define Q_SIGNALS
unsigned int uint
Definition qtypes.h:34
unsigned char quint8
Definition qtypes.h:46
#define explicit
QFuture< void > future
[5]
QDeadlineTimer deadline(30s)
dialog exec()
view create()
QJSValueList args