QString::localeAwareCompare: adapt to QLocale::setDefault() being called
Because we're using a thread-specific global static, we need to recreate the QCollator type every time setDefault() is called. Since one is stored per-thread, we simply increment a generational counter and check that the next time that QString::localeAwareCompare is called in each thread. The issue was introduced onbb10f6425da424(5.12) even though we were supposed to be using QCollator since commit5279134935(5.3). Fixes: QTBUG-95050 Pick-to: 6.2 Change-Id: I7e0b82c2d2fe464082d8fffd1696a8c9f74e5b30 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
parent
4d2e574fb0
commit
94de5f9b25
|
|
@ -780,9 +780,9 @@ QDataStream &operator>>(QDataStream &ds, QLocale &l)
|
||||||
}
|
}
|
||||||
#endif // QT_NO_DATASTREAM
|
#endif // QT_NO_DATASTREAM
|
||||||
|
|
||||||
|
|
||||||
static const int locale_data_size = sizeof(locale_data)/sizeof(QLocaleData) - 1;
|
static const int locale_data_size = sizeof(locale_data)/sizeof(QLocaleData) - 1;
|
||||||
|
|
||||||
|
QBasicAtomicInt QLocalePrivate::s_generation = Q_BASIC_ATOMIC_INITIALIZER(0);
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, defaultLocalePrivate,
|
Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, defaultLocalePrivate,
|
||||||
(new QLocalePrivate(defaultData(), defaultIndex())))
|
(new QLocalePrivate(defaultData(), defaultIndex())))
|
||||||
|
|
||||||
|
|
@ -1206,6 +1206,7 @@ void QLocale::setDefault(const QLocale &locale)
|
||||||
|
|
||||||
// update the cached private
|
// update the cached private
|
||||||
*defaultLocalePrivate = locale.d;
|
*defaultLocalePrivate = locale.d;
|
||||||
|
QLocalePrivate::s_generation.fetchAndAddRelaxed(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
||||||
|
|
@ -424,6 +424,8 @@ public:
|
||||||
QBasicAtomicInt ref;
|
QBasicAtomicInt ref;
|
||||||
const uint m_index;
|
const uint m_index;
|
||||||
QLocale::NumberOptions m_numberOptions;
|
QLocale::NumberOptions m_numberOptions;
|
||||||
|
|
||||||
|
static QBasicAtomicInt s_generation;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_SYSTEMLOCALE
|
#ifndef QT_NO_SYSTEMLOCALE
|
||||||
|
|
|
||||||
|
|
@ -6141,7 +6141,25 @@ int QString::localeAwareCompare(const QString &other) const
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(icu)
|
#if QT_CONFIG(icu)
|
||||||
Q_GLOBAL_STATIC(QThreadStorage<QCollator>, defaultCollator)
|
namespace {
|
||||||
|
class GenerationalCollator
|
||||||
|
{
|
||||||
|
QCollator theCollator;
|
||||||
|
int generation = QLocalePrivate::s_generation.loadRelaxed();
|
||||||
|
public:
|
||||||
|
QCollator &collator()
|
||||||
|
{
|
||||||
|
int currentGeneration = QLocalePrivate::s_generation.loadRelaxed();
|
||||||
|
if (Q_UNLIKELY(generation != currentGeneration)) {
|
||||||
|
// reinitialize the collator
|
||||||
|
generation = currentGeneration;
|
||||||
|
theCollator = QCollator();
|
||||||
|
}
|
||||||
|
return theCollator;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Q_GLOBAL_STATIC(QThreadStorage<GenerationalCollator>, defaultCollator)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -6163,8 +6181,8 @@ int QString::localeAwareCompare_helper(const QChar *data1, qsizetype length1,
|
||||||
|
|
||||||
#if QT_CONFIG(icu)
|
#if QT_CONFIG(icu)
|
||||||
if (!defaultCollator()->hasLocalData())
|
if (!defaultCollator()->hasLocalData())
|
||||||
defaultCollator()->setLocalData(QCollator());
|
defaultCollator()->setLocalData(GenerationalCollator());
|
||||||
return defaultCollator()->localData().compare(data1, length1, data2, length2);
|
return defaultCollator()->localData().collator().compare(data1, length1, data2, length2);
|
||||||
#else
|
#else
|
||||||
const QString lhs = QString::fromRawData(data1, length1).normalized(QString::NormalizationForm_C);
|
const QString lhs = QString::fromRawData(data1, length1).normalized(QString::NormalizationForm_C);
|
||||||
const QString rhs = QString::fromRawData(data2, length2).normalized(QString::NormalizationForm_C);
|
const QString rhs = QString::fromRawData(data2, length2).normalized(QString::NormalizationForm_C);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue