Warning, file /include/QtCore/qthread.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006 #ifndef QTHREAD_H
0007 #define QTHREAD_H
0008
0009 #include <QtCore/qobject.h>
0010 #include <QtCore/qdeadlinetimer.h>
0011
0012
0013 #include <future> // for std::async
0014 #include <functional> // for std::invoke; no guard needed as it's a C++98 header
0015
0016 #if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86)
0017 #include <intrin.h>
0018 #endif
0019
0020 QT_BEGIN_NAMESPACE
0021
0022
0023 class QThreadData;
0024 class QThreadPrivate;
0025 class QAbstractEventDispatcher;
0026 class QEventLoopLocker;
0027
0028 class Q_CORE_EXPORT QThread : public QObject
0029 {
0030 Q_OBJECT
0031 public:
0032 static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION;
0033 static QThread *currentThread();
0034 static bool isMainThread() noexcept;
0035 static int idealThreadCount() noexcept;
0036 static void yieldCurrentThread();
0037
0038 explicit QThread(QObject *parent = nullptr);
0039 ~QThread();
0040
0041 enum Priority {
0042 IdlePriority,
0043
0044 LowestPriority,
0045 LowPriority,
0046 NormalPriority,
0047 HighPriority,
0048 HighestPriority,
0049
0050 TimeCriticalPriority,
0051
0052 InheritPriority
0053 };
0054
0055 enum class QualityOfService {
0056 Auto,
0057 High,
0058 Eco,
0059 };
0060 Q_ENUM(QualityOfService)
0061
0062 void setPriority(Priority priority);
0063 Priority priority() const;
0064
0065 bool isFinished() const;
0066 bool isRunning() const;
0067
0068 void requestInterruption();
0069 bool isInterruptionRequested() const;
0070
0071 void setStackSize(uint stackSize);
0072 uint stackSize() const;
0073
0074 QAbstractEventDispatcher *eventDispatcher() const;
0075 void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher);
0076
0077 bool event(QEvent *event) override;
0078 int loopLevel() const;
0079
0080 bool isCurrentThread() const noexcept;
0081
0082 void setServiceLevel(QualityOfService serviceLevel);
0083 QualityOfService serviceLevel() const;
0084
0085 template <typename Function, typename... Args>
0086 [[nodiscard]] static QThread *create(Function &&f, Args &&... args);
0087
0088 public Q_SLOTS:
0089 void start(Priority = InheritPriority);
0090 void terminate();
0091 void exit(int retcode = 0);
0092 void quit();
0093
0094 public:
0095 bool wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever));
0096 bool wait(unsigned long time)
0097 {
0098 if (time == (std::numeric_limits<unsigned long>::max)())
0099 return wait(QDeadlineTimer(QDeadlineTimer::Forever));
0100 return wait(QDeadlineTimer(time));
0101 }
0102
0103 static void sleep(unsigned long);
0104 static void msleep(unsigned long);
0105 static void usleep(unsigned long);
0106 static void sleep(std::chrono::nanoseconds nsec);
0107
0108 Q_SIGNALS:
0109 void started(QPrivateSignal);
0110 void finished(QPrivateSignal);
0111
0112 protected:
0113 virtual void run();
0114 int exec();
0115
0116 static void setTerminationEnabled(bool enabled = true);
0117
0118 protected:
0119 QThread(QThreadPrivate &dd, QObject *parent = nullptr);
0120
0121 private:
0122 Q_DECLARE_PRIVATE(QThread)
0123 friend class QEventLoopLocker;
0124
0125 [[nodiscard]] static QThread *createThreadImpl(std::future<void> &&future);
0126 static Qt::HANDLE currentThreadIdImpl() noexcept Q_DECL_PURE_FUNCTION;
0127
0128 friend class QCoreApplication;
0129 friend class QThreadData;
0130 };
0131
0132 template <typename Function, typename... Args>
0133 QThread *QThread::create(Function &&f, Args &&... args)
0134 {
0135 using DecayedFunction = typename std::decay<Function>::type;
0136 auto threadFunction =
0137 [f = static_cast<DecayedFunction>(std::forward<Function>(f))](auto &&... largs) mutable -> void
0138 {
0139 (void)std::invoke(std::move(f), std::forward<decltype(largs)>(largs)...);
0140 };
0141
0142 return createThreadImpl(std::async(std::launch::deferred,
0143 std::move(threadFunction),
0144 std::forward<Args>(args)...));
0145 }
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 inline Qt::HANDLE QThread::currentThreadId() noexcept
0161 {
0162
0163 #define QT_HAS_FAST_CURRENT_THREAD_ID
0164 Qt::HANDLE tid;
0165 static_assert(sizeof(tid) == sizeof(void*));
0166
0167 #if defined(Q_PROCESSOR_X86_32) && ((defined(Q_OS_LINUX) && defined(__GLIBC__)) || defined(Q_OS_FREEBSD))
0168 __asm__("mov %%gs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : );
0169 #elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_DARWIN)
0170
0171 __asm__("mov %%gs:0, %0" : "=r" (tid) : : );
0172 #elif defined(Q_PROCESSOR_X86_64) && ((defined(Q_OS_LINUX) && defined(__GLIBC__)) || defined(Q_OS_FREEBSD))
0173
0174 __asm__("mov %%fs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : );
0175 #elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_WIN) && defined(Q_CC_MSVC)
0176
0177 tid = reinterpret_cast<Qt::HANDLE>(__readgsqword(0x48));
0178 #elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_WIN)
0179 __asm__("mov %%gs:0x48, %0" : "=r" (tid));
0180 #elif defined(Q_PROCESSOR_X86_32) && defined(Q_OS_WIN) && defined(Q_CC_MSVC)
0181 tid = reinterpret_cast<Qt::HANDLE>(__readfsdword(0x24));
0182 #elif defined(Q_PROCESSOR_X86_32) && defined(Q_OS_WIN)
0183 __asm__("mov %%fs:0x24, %0" : "=r" (tid));
0184 #else
0185 #undef QT_HAS_FAST_CURRENT_THREAD_ID
0186 tid = currentThreadIdImpl();
0187 #endif
0188 return tid;
0189 }
0190
0191 QT_END_NAMESPACE
0192
0193 #endif