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.5 6.2
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit a1b55b1360acff00f9932d99ab48f4614754e3b8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Giuseppe D'Angelo 2023-09-13 12:44:41 +02:00 committed by Qt Cherry-pick Bot
parent 7a705e9c60
commit 018d273557
2 changed files with 10 additions and 1 deletions

View File

@ -32,6 +32,8 @@
# include "qwindowsfontenginedirectwrite_p.h"
#endif
#include <mutex>
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();

View File

@ -21,6 +21,7 @@
#include <QtCore/QSharedPointer>
#include <QtCore/QLoggingCategory>
#include <QtCore/qhashfunctions.h>
#include <QtCore/qmutex.h>
#include <QtCore/qt_windows.h>
QT_BEGIN_NAMESPACE
@ -89,6 +90,7 @@ private:
QAtomicInt refCount;
};
QMutex m_uniqueFontDataMutex; // protects m_uniqueFontData
QMap<QString, UniqueFontData> m_uniqueFontData;
static unsigned m_fontOptions;