Fix race condition with QTest::ignoreMessage

If another spawned thread will log at the same time
a crash was possible because IgnoreResultList
was not thread-safe.

Task-number: QTBUG-104840
Pick-to: 6.4 6.3 6.2 5.15
Change-Id: I251c83bb28cb75e55d477706bf2524c061a6eab7
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
André Klitzing 2022-07-08 11:35:37 +02:00 committed by Edward Welbourne
parent 4b165c6bcc
commit d1dd944239

View File

@ -24,6 +24,7 @@
#include <QtCore/qbytearray.h> #include <QtCore/qbytearray.h>
#include <QtCore/qelapsedtimer.h> #include <QtCore/qelapsedtimer.h>
#include <QtCore/qlist.h> #include <QtCore/qlist.h>
#include <QtCore/qmutex.h>
#include <QtCore/qvariant.h> #include <QtCore/qvariant.h>
#if QT_CONFIG(regularexpression) #if QT_CONFIG(regularexpression)
#include <QtCore/QRegularExpression> #include <QtCore/QRegularExpression>
@ -138,6 +139,7 @@ namespace QTest {
}; };
static IgnoreResultList *ignoreResultList = nullptr; static IgnoreResultList *ignoreResultList = nullptr;
Q_CONSTINIT static QBasicMutex mutex;
static std::vector<QVariant> failOnWarningList; static std::vector<QVariant> failOnWarningList;
@ -151,6 +153,8 @@ namespace QTest {
static bool handleIgnoredMessage(QtMsgType type, const QString &message) static bool handleIgnoredMessage(QtMsgType type, const QString &message)
{ {
const QMutexLocker mutexLocker(&QTest::mutex);
if (!ignoreResultList) if (!ignoreResultList)
return false; return false;
IgnoreResultList *last = nullptr; IgnoreResultList *last = nullptr;
@ -270,6 +274,7 @@ void QTestLog::enterTestData(QTestData *data)
int QTestLog::unhandledIgnoreMessages() int QTestLog::unhandledIgnoreMessages()
{ {
const QMutexLocker mutexLocker(&QTest::mutex);
int i = 0; int i = 0;
QTest::IgnoreResultList *list = QTest::ignoreResultList; QTest::IgnoreResultList *list = QTest::ignoreResultList;
while (list) { while (list) {
@ -290,6 +295,7 @@ void QTestLog::leaveTestFunction()
void QTestLog::printUnhandledIgnoreMessages() void QTestLog::printUnhandledIgnoreMessages()
{ {
const QMutexLocker mutexLocker(&QTest::mutex);
QString message; QString message;
QTest::IgnoreResultList *list = QTest::ignoreResultList; QTest::IgnoreResultList *list = QTest::ignoreResultList;
while (list) { while (list) {
@ -310,6 +316,7 @@ void QTestLog::printUnhandledIgnoreMessages()
void QTestLog::clearIgnoreMessages() void QTestLog::clearIgnoreMessages()
{ {
const QMutexLocker mutexLocker(&QTest::mutex);
QTest::IgnoreResultList::clearList(QTest::ignoreResultList); QTest::IgnoreResultList::clearList(QTest::ignoreResultList);
} }
@ -594,6 +601,7 @@ void QTestLog::ignoreMessage(QtMsgType type, const char *msg)
{ {
QTEST_ASSERT(msg); QTEST_ASSERT(msg);
const QMutexLocker mutexLocker(&QTest::mutex);
QTest::IgnoreResultList::append(QTest::ignoreResultList, type, QString::fromUtf8(msg)); QTest::IgnoreResultList::append(QTest::ignoreResultList, type, QString::fromUtf8(msg));
} }
@ -602,6 +610,7 @@ void QTestLog::ignoreMessage(QtMsgType type, const QRegularExpression &expressio
{ {
QTEST_ASSERT(expression.isValid()); QTEST_ASSERT(expression.isValid());
const QMutexLocker mutexLocker(&QTest::mutex);
QTest::IgnoreResultList::append(QTest::ignoreResultList, type, QVariant(expression)); QTest::IgnoreResultList::append(QTest::ignoreResultList, type, QVariant(expression));
} }
#endif // QT_CONFIG(regularexpression) #endif // QT_CONFIG(regularexpression)