From a1b55b1360acff00f9932d99ab48f4614754e3b8 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 13 Sep 2023 12:44:41 +0200 Subject: QWindowsFontDatabase: fix a data race QRawFont::loadFromData can be called from any thread. It calls into QPlatformFontDatabase::fontEngine. The code path may end up creating a UniqueFontData and storing it a QWindowsFontDatabase member (a QMap). Two threads calling loadFromData (on different QRawFont objects) will therefore race on the mutation of the map. Add the missing mutex protection. Change-Id: Ib38c2b3539679c820d997a6548e4b397cbc2bb73 Pick-to: 6.2 6.5 6.6 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/windows/qwindowsfontdatabase.cpp | 9 ++++++++- src/gui/text/windows/qwindowsfontdatabase_p.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp index 832107d827..40f7020d38 100644 --- a/src/gui/text/windows/qwindowsfontdatabase.cpp +++ b/src/gui/text/windows/qwindowsfontdatabase.cpp @@ -32,6 +32,8 @@ # include "qwindowsfontenginedirectwrite_p.h" #endif +#include + QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; @@ -847,7 +849,10 @@ QT_WARNING_POP UniqueFontData uniqueData; uniqueData.handle = fontHandle; uniqueData.refCount.ref(); - m_uniqueFontData[uniqueFamilyName] = uniqueData; + { + const std::scoped_lock lock(m_uniqueFontDataMutex); + m_uniqueFontData[uniqueFamilyName] = uniqueData; + } } } else { RemoveFontMemResourceEx(fontHandle); @@ -1107,6 +1112,7 @@ bool QWindowsFontDatabase::fontsAlwaysScalable() const void QWindowsFontDatabase::derefUniqueFont(const QString &uniqueFont) { + const std::scoped_lock lock(m_uniqueFontDataMutex); const auto it = m_uniqueFontData.find(uniqueFont); if (it != m_uniqueFontData.end()) { if (!it->refCount.deref()) { @@ -1118,6 +1124,7 @@ void QWindowsFontDatabase::derefUniqueFont(const QString &uniqueFont) void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont) { + const std::scoped_lock lock(m_uniqueFontDataMutex); const auto it = m_uniqueFontData.find(uniqueFont); if (it != m_uniqueFontData.end()) it->refCount.ref(); diff --git a/src/gui/text/windows/qwindowsfontdatabase_p.h b/src/gui/text/windows/qwindowsfontdatabase_p.h index 923f875336..6d6ce4cda4 100644 --- a/src/gui/text/windows/qwindowsfontdatabase_p.h +++ b/src/gui/text/windows/qwindowsfontdatabase_p.h @@ -21,6 +21,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -89,6 +90,7 @@ private: QAtomicInt refCount; }; + QMutex m_uniqueFontDataMutex; // protects m_uniqueFontData QMap m_uniqueFontData; static unsigned m_fontOptions; -- cgit v1.2.3