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
|
||||
|
||||
|
||||
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,
|
||||
(new QLocalePrivate(defaultData(), defaultIndex())))
|
||||
|
||||
|
|
@ -1206,6 +1206,7 @@ void QLocale::setDefault(const QLocale &locale)
|
|||
|
||||
// update the cached private
|
||||
*defaultLocalePrivate = locale.d;
|
||||
QLocalePrivate::s_generation.fetchAndAddRelaxed(1);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -424,6 +424,8 @@ public:
|
|||
QBasicAtomicInt ref;
|
||||
const uint m_index;
|
||||
QLocale::NumberOptions m_numberOptions;
|
||||
|
||||
static QBasicAtomicInt s_generation;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
|
|
|
|||
|
|
@ -6141,7 +6141,25 @@ int QString::localeAwareCompare(const QString &other) const
|
|||
}
|
||||
|
||||
#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
|
||||
|
||||
/*!
|
||||
|
|
@ -6163,8 +6181,8 @@ int QString::localeAwareCompare_helper(const QChar *data1, qsizetype length1,
|
|||
|
||||
#if QT_CONFIG(icu)
|
||||
if (!defaultCollator()->hasLocalData())
|
||||
defaultCollator()->setLocalData(QCollator());
|
||||
return defaultCollator()->localData().compare(data1, length1, data2, length2);
|
||||
defaultCollator()->setLocalData(GenerationalCollator());
|
||||
return defaultCollator()->localData().collator().compare(data1, length1, data2, length2);
|
||||
#else
|
||||
const QString lhs = QString::fromRawData(data1, length1).normalized(QString::NormalizationForm_C);
|
||||
const QString rhs = QString::fromRawData(data2, length2).normalized(QString::NormalizationForm_C);
|
||||
|
|
|
|||
Loading…
Reference in New Issue