summaryrefslogtreecommitdiffstats
path: root/src/testlib
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2023-10-13 13:41:16 +0200
committerMårten Nordheim <marten.nordheim@qt.io>2024-01-19 22:28:00 +0000
commitc60db318836cf22b0f00b78ea189ba33fcf7b1c7 (patch)
tree501c3be0424b189a9c03a5ec126eb13dc403c485 /src/testlib
parent6ce6ff1c529a7a4a09f211980cc749c2b3aa0dab (diff)
SignalDumper: protect access to ignoreClasses
It's a shared list that, in theory, can be written to by multiple threads. Protect it with a mutex. To make the change in a clean way, move all the .contains() checks into a separate function so we can simply hold the lock in there. Pick-to: 6.7 6.6 6.5 Change-Id: I99ff185346d52e43a3f59f2910a7b2fa6031e3e4 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/testlib')
-rw-r--r--src/testlib/qsignaldumper.cpp23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/testlib/qsignaldumper.cpp b/src/testlib/qsignaldumper.cpp
index 54b608ed50..9a6412ffc2 100644
--- a/src/testlib/qsignaldumper.cpp
+++ b/src/testlib/qsignaldumper.cpp
@@ -24,10 +24,21 @@ inline static void qPrintMessage(const QByteArray &ba)
}
Q_GLOBAL_STATIC(QList<QByteArray>, ignoreClasses)
+Q_CONSTINIT static QBasicMutex ignoreClassesMutex;
Q_CONSTINIT thread_local int iLevel = 0;
Q_CONSTINIT thread_local int ignoreLevel = 0;
enum { IndentSpacesCount = 4 };
+static bool classIsIgnored(const char *className)
+{
+ if (Q_LIKELY(!ignoreClasses.exists()))
+ return false;
+ QMutexLocker locker(&ignoreClassesMutex);
+ if (ignoreClasses()->isEmpty())
+ return false;
+ return ignoreClasses()->contains(QByteArrayView(className));
+}
+
static void qSignalDumperCallback(QObject *caller, int signal_index, void **argv)
{
Q_ASSERT(caller);
@@ -38,7 +49,7 @@ static void qSignalDumperCallback(QObject *caller, int signal_index, void **argv
QMetaMethod member = QMetaObjectPrivate::signal(mo, signal_index);
Q_ASSERT(member.isValid());
- if (QTest::ignoreClasses() && QTest::ignoreClasses()->contains(mo->className())) {
+ if (classIsIgnored(mo->className())) {
++QTest::ignoreLevel;
return;
}
@@ -98,8 +109,7 @@ static void qSignalDumperCallbackSlot(QObject *caller, int method_index, void **
if (!member.isValid())
return;
- if (QTest::ignoreLevel ||
- (QTest::ignoreClasses() && QTest::ignoreClasses()->contains(mo->className())))
+ if (QTest::ignoreLevel || classIsIgnored(mo->className()))
return;
QByteArray str;
@@ -122,8 +132,7 @@ static void qSignalDumperCallbackSlot(QObject *caller, int method_index, void **
static void qSignalDumperCallbackEndSignal(QObject *caller, int /*signal_index*/)
{
Q_ASSERT(caller); Q_ASSERT(caller->metaObject());
- if (QTest::ignoreClasses()
- && QTest::ignoreClasses()->contains(caller->metaObject()->className())) {
+ if (classIsIgnored(caller->metaObject()->className())) {
--QTest::ignoreLevel;
Q_ASSERT(QTest::ignoreLevel >= 0);
return;
@@ -156,13 +165,15 @@ void QSignalDumper::endDump()
void QSignalDumper::ignoreClass(const QByteArray &klass)
{
+ QMutexLocker locker(&QTest::ignoreClassesMutex);
if (QTest::ignoreClasses())
QTest::ignoreClasses()->append(klass);
}
void QSignalDumper::clearIgnoredClasses()
{
- if (QTest::ignoreClasses())
+ QMutexLocker locker(&QTest::ignoreClassesMutex);
+ if (QTest::ignoreClasses.exists())
QTest::ignoreClasses()->clear();
}