summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2024-03-18 21:19:02 +0100
committerJarek Kobus <jaroslaw.kobus@qt.io>2024-04-26 18:19:39 +0200
commita3d50112e44bc42b310d9d3a8e6c7805ef31ef53 (patch)
tree71d7b3ff4efa587d0c21b790d887350672ba3502
parent7a374c38d288435b3c0a76b82a1c2ca53ea9c003 (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.cpp1
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h1
-rw-r--r--src/corelib/thread/qthread.cpp26
-rw-r--r--src/corelib/thread/qthread.h1
-rw-r--r--src/corelib/thread/qthread_unix.cpp4
-rw-r--r--src/corelib/thread/qthread_win.cpp1
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(),