diff options
author | Jarek Kobus <jaroslaw.kobus@qt.io> | 2024-03-18 21:19:02 +0100 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@qt.io> | 2024-04-26 18:19:39 +0200 |
commit | a3d50112e44bc42b310d9d3a8e6c7805ef31ef53 (patch) | |
tree | 71d7b3ff4efa587d0c21b790d887350672ba3502 | |
parent | 7a374c38d288435b3c0a76b82a1c2ca53ea9c003 (diff) |
QThread: Introduce static isMainThread() helper
Useful for QtCreator, as a replacement for
Utils::isMainThread() inside threadutils.h,
may serve for other projects, too.
Introduce static QCoreApplicationPrivate::theMainThreadId
atomic helper field holding the id of the main thread.
Change-Id: Iccc0302f423f47b5ecad86c4cd3de4d1ee36155f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication_p.h | 1 | ||||
-rw-r--r-- | src/corelib/thread/qthread.cpp | 26 | ||||
-rw-r--r-- | src/corelib/thread/qthread.h | 1 | ||||
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 4 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 1 |
6 files changed, 30 insertions, 4 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 939965cff7..13108cecea 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -525,6 +525,7 @@ void QCoreApplicationPrivate::eventDispatcherReady() } Q_CONSTINIT QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(nullptr); +Q_CONSTINIT QBasicAtomicPointer<void> QCoreApplicationPrivate::theMainThreadId = Q_BASIC_ATOMIC_INITIALIZER(nullptr); QThread *QCoreApplicationPrivate::mainThread() { Q_ASSERT(theMainThread.loadRelaxed() != nullptr); diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 1c1577c9ff..bfd65d2c9a 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -108,6 +108,7 @@ public: virtual void quit(); static QBasicAtomicPointer<QThread> theMainThread; + static QBasicAtomicPointer<void> theMainThreadId; static QThread *mainThread(); static bool threadRequiresCoreApplication(); diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 2cac443e53..0ad402b77c 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -66,8 +66,9 @@ QThreadData::~QThreadData() // safeguard the main thread here.. This fix is a bit crude, but it solves // the problem... if (this->thread.loadAcquire() == QCoreApplicationPrivate::theMainThread.loadAcquire()) { - QCoreApplicationPrivate::theMainThread.storeRelease(nullptr); - QThreadData::clearCurrentThreadData(); + QCoreApplicationPrivate::theMainThread.storeRelease(nullptr); + QCoreApplicationPrivate::theMainThreadId.storeRelaxed(nullptr); + QThreadData::clearCurrentThreadData(); } // ~QThread() sets thread to nullptr, so if it isn't null here, it's @@ -426,6 +427,23 @@ QThread *QThread::currentThread() } /*! + \since 6.8 + + Returns whether the currently executing thread is the main thread. + + The main thread is the thread in which QCoreApplication was created. + This is usually the thread that called the \c{main()} function, but not necessarily so. + It is the thread that is processing the GUI events and in which graphical objects + (QWindow, QWidget) can be created. + + \sa currentThread(), QCoreApplication::instance() +*/ +bool QThread::isMainThread() +{ + return currentThreadId() == QCoreApplicationPrivate::theMainThreadId.loadRelaxed(); +} + +/*! Constructs a new QThread to manage a new thread. The \a parent takes ownership of the QThread. The thread does not begin executing until start() is called. @@ -1066,8 +1084,10 @@ QThreadData *QThreadData::current(bool createIfNecessary) data->threadId.storeRelaxed(Qt::HANDLE(data->thread.loadAcquire())); data->deref(); data->isAdopted = true; - if (!QCoreApplicationPrivate::theMainThread.loadAcquire()) + if (!QCoreApplicationPrivate::theMainThread.loadAcquire()) { QCoreApplicationPrivate::theMainThread.storeRelease(data->thread.loadRelaxed()); + QCoreApplicationPrivate::theMainThreadId.storeRelaxed(data->threadId.loadRelaxed()); + } } return data; } diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h index fcef6deb59..641c8ef68a 100644 --- a/src/corelib/thread/qthread.h +++ b/src/corelib/thread/qthread.h @@ -30,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(); diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 4b165eef9c..8916da09b2 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -191,8 +191,10 @@ QThreadData *QThreadData::current(bool createIfNecessary) data->deref(); data->isAdopted = true; data->threadId.storeRelaxed(to_HANDLE(pthread_self())); - if (!QCoreApplicationPrivate::theMainThread.loadAcquire()) + if (!QCoreApplicationPrivate::theMainThread.loadAcquire()) { QCoreApplicationPrivate::theMainThread.storeRelease(data->thread.loadRelaxed()); + QCoreApplicationPrivate::theMainThreadId.storeRelaxed(data->threadId.loadRelaxed()); + } } return data; } diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index ee3b94dc3b..475a61bf65 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -89,6 +89,7 @@ QThreadData *QThreadData::current(bool createIfNecessary) if (!QCoreApplicationPrivate::theMainThread) { QCoreApplicationPrivate::theMainThread = threadData->thread.loadRelaxed(); + QCoreApplicationPrivate::theMainThreadId.storeRelaxed(threadData->threadId.loadRelaxed()); } else { HANDLE realHandle = INVALID_HANDLE_VALUE; DuplicateHandle(GetCurrentProcess(), |