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:
parent
7a705e9c60
commit
018d273557
@ -32,6 +32,8 @@
|
|||||||
# include "qwindowsfontenginedirectwrite_p.h"
|
# include "qwindowsfontenginedirectwrite_p.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
@ -847,7 +849,10 @@ QT_WARNING_POP
|
|||||||
UniqueFontData uniqueData;
|
UniqueFontData uniqueData;
|
||||||
uniqueData.handle = fontHandle;
|
uniqueData.handle = fontHandle;
|
||||||
uniqueData.refCount.ref();
|
uniqueData.refCount.ref();
|
||||||
m_uniqueFontData[uniqueFamilyName] = uniqueData;
|
{
|
||||||
|
const std::scoped_lock lock(m_uniqueFontDataMutex);
|
||||||
|
m_uniqueFontData[uniqueFamilyName] = uniqueData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RemoveFontMemResourceEx(fontHandle);
|
RemoveFontMemResourceEx(fontHandle);
|
||||||
@ -1107,6 +1112,7 @@ bool QWindowsFontDatabase::fontsAlwaysScalable() const
|
|||||||
|
|
||||||
void QWindowsFontDatabase::derefUniqueFont(const QString &uniqueFont)
|
void QWindowsFontDatabase::derefUniqueFont(const QString &uniqueFont)
|
||||||
{
|
{
|
||||||
|
const std::scoped_lock lock(m_uniqueFontDataMutex);
|
||||||
const auto it = m_uniqueFontData.find(uniqueFont);
|
const auto it = m_uniqueFontData.find(uniqueFont);
|
||||||
if (it != m_uniqueFontData.end()) {
|
if (it != m_uniqueFontData.end()) {
|
||||||
if (!it->refCount.deref()) {
|
if (!it->refCount.deref()) {
|
||||||
@ -1118,6 +1124,7 @@ void QWindowsFontDatabase::derefUniqueFont(const QString &uniqueFont)
|
|||||||
|
|
||||||
void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont)
|
void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont)
|
||||||
{
|
{
|
||||||
|
const std::scoped_lock lock(m_uniqueFontDataMutex);
|
||||||
const auto it = m_uniqueFontData.find(uniqueFont);
|
const auto it = m_uniqueFontData.find(uniqueFont);
|
||||||
if (it != m_uniqueFontData.end())
|
if (it != m_uniqueFontData.end())
|
||||||
it->refCount.ref();
|
it->refCount.ref();
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
#include <QtCore/QLoggingCategory>
|
#include <QtCore/QLoggingCategory>
|
||||||
#include <QtCore/qhashfunctions.h>
|
#include <QtCore/qhashfunctions.h>
|
||||||
|
#include <QtCore/qmutex.h>
|
||||||
#include <QtCore/qt_windows.h>
|
#include <QtCore/qt_windows.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -89,6 +90,7 @@ private:
|
|||||||
QAtomicInt refCount;
|
QAtomicInt refCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QMutex m_uniqueFontDataMutex; // protects m_uniqueFontData
|
||||||
QMap<QString, UniqueFontData> m_uniqueFontData;
|
QMap<QString, UniqueFontData> m_uniqueFontData;
|
||||||
|
|
||||||
static unsigned m_fontOptions;
|
static unsigned m_fontOptions;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user