diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 939965cff74..13108ceceab 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -525,6 +525,7 @@ void QCoreApplicationPrivate::eventDispatcherReady() } Q_CONSTINIT QBasicAtomicPointer QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(nullptr); +Q_CONSTINIT QBasicAtomicPointer 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 1c1577c9fff..bfd65d2c9a0 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 theMainThread; + static QBasicAtomicPointer theMainThreadId; static QThread *mainThread(); static bool threadRequiresCoreApplication(); diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 2cac443e53f..0ad402b77cf 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 @@ -425,6 +426,23 @@ QThread *QThread::currentThread() return data->thread.loadAcquire(); } +/*! + \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 @@ -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 fcef6deb598..641c8ef68a0 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 4b165eef9c6..8916da09b2a 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 ee3b94dc3b1..475a61bf655 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(),