diff options
Diffstat (limited to 'src/corelib/thread/qthread.h')
-rw-r--r-- | src/corelib/thread/qthread.h | 79 |
1 files changed, 22 insertions, 57 deletions
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h index 51cd3eadcc..641c8ef68a 100644 --- a/src/corelib/thread/qthread.h +++ b/src/corelib/thread/qthread.h @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QTHREAD_H #define QTHREAD_H @@ -45,10 +9,8 @@ #include <QtCore/qdeadlinetimer.h> // For QThread::create -#if QT_CONFIG(cxx11_future) -# include <future> // for std::async -# include <functional> // for std::invoke; no guard needed as it's a C++98 header -#endif +#include <future> // for std::async +#include <functional> // for std::invoke; no guard needed as it's a C++98 header // internal compiler error with mingw 8.1 #if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86) #include <intrin.h> @@ -60,6 +22,7 @@ QT_BEGIN_NAMESPACE class QThreadData; class QThreadPrivate; class QAbstractEventDispatcher; +class QEventLoopLocker; class Q_CORE_EXPORT QThread : public QObject { @@ -67,6 +30,7 @@ class Q_CORE_EXPORT QThread : public QObject public: static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION; static QThread *currentThread(); + static bool isMainThread(); static int idealThreadCount() noexcept; static void yieldCurrentThread(); @@ -105,10 +69,10 @@ public: bool event(QEvent *event) override; int loopLevel() const; -#if QT_CONFIG(cxx11_future) || defined(Q_CLANG_QDOC) + bool isCurrentThread() const; + template <typename Function, typename... Args> [[nodiscard]] static QThread *create(Function &&f, Args &&... args); -#endif public Q_SLOTS: void start(Priority = InheritPriority); @@ -120,7 +84,7 @@ public: bool wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever)); bool wait(unsigned long time) { - if (time == std::numeric_limits<unsigned long>::max()) + if (time == (std::numeric_limits<unsigned long>::max)()) return wait(QDeadlineTimer(QDeadlineTimer::Forever)); return wait(QDeadlineTimer(time)); } @@ -128,6 +92,7 @@ public: static void sleep(unsigned long); static void msleep(unsigned long); static void usleep(unsigned long); + static void sleep(std::chrono::nanoseconds nsec); Q_SIGNALS: void started(QPrivateSignal); @@ -144,17 +109,15 @@ protected: private: Q_DECLARE_PRIVATE(QThread) + friend class QEventLoopLocker; -#if QT_CONFIG(cxx11_future) [[nodiscard]] static QThread *createThreadImpl(std::future<void> &&future); -#endif static Qt::HANDLE currentThreadIdImpl() noexcept Q_DECL_PURE_FUNCTION; friend class QCoreApplication; friend class QThreadData; }; -#if QT_CONFIG(cxx11_future) template <typename Function, typename... Args> QThread *QThread::create(Function &&f, Args &&... args) { @@ -169,7 +132,6 @@ QThread *QThread::create(Function &&f, Args &&... args) std::move(threadFunction), std::forward<Args>(args)...)); } -#endif // QT_CONFIG(cxx11_future) /* On architectures and platforms we know, interpret the thread control @@ -181,22 +143,24 @@ QThread *QThread::create(Function &&f, Args &&... args) value for anything. In Qt we use the handle to check if threads are identical, for which the TCB is sufficient. - So we use the fastest possible way, rathern than spend time on returning + So we use the fastest possible way, rather than spend time on returning some pseudo-interoperable value. */ inline Qt::HANDLE QThread::currentThreadId() noexcept { + // define is undefed if we have to fall back to currentThreadIdImpl +#define QT_HAS_FAST_CURRENT_THREAD_ID Qt::HANDLE tid; // typedef to void* static_assert(sizeof(tid) == sizeof(void*)); // See https://akkadia.org/drepper/tls.pdf for x86 ABI -#if defined(Q_PROCESSOR_X86_32) && defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) // x86 32-bit always uses GS - __asm__("movl %%gs:0, %0" : "=r" (tid) : : ); -#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_DARWIN64) +#if defined(Q_PROCESSOR_X86_32) && ((defined(Q_OS_LINUX) && defined(__GLIBC__)) || defined(Q_OS_FREEBSD)) // x86 32-bit always uses GS + __asm__("mov %%gs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : ); +#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_DARWIN) // 64bit macOS uses GS, see https://github.com/apple/darwin-xnu/blob/master/libsyscall/os/tsd.h - __asm__("movq %%gs:0, %0" : "=r" (tid) : : ); -#elif defined(Q_PROCESSOR_X86_64) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)) && !defined(Q_OS_ANDROID) + __asm__("mov %%gs:0, %0" : "=r" (tid) : : ); +#elif defined(Q_PROCESSOR_X86_64) && ((defined(Q_OS_LINUX) && defined(__GLIBC__)) || defined(Q_OS_FREEBSD)) // x86_64 Linux, BSD uses FS - __asm__("movq %%fs:0, %0" : "=r" (tid) : : ); + __asm__("mov %%fs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : ); #elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_WIN) // See https://en.wikipedia.org/wiki/Win32_Thread_Information_Block // First get the pointer to the TIB @@ -219,6 +183,7 @@ inline Qt::HANDLE QThread::currentThreadId() noexcept // Then read the thread ID tid = *reinterpret_cast<Qt::HANDLE *>(tib + 0x24); #else +#undef QT_HAS_FAST_CURRENT_THREAD_ID tid = currentThreadIdImpl(); #endif return tid; |