diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2021-07-30 12:38:20 -0700 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-08-03 00:41:22 +0000 |
commit | a1e694b641aeeb8731f50f22e9223ea57c827c7a (patch) | |
tree | ec28856f3b387ecaec80b277376c17898e08cca0 /src/corelib/text | |
parent | 4b3ed8aa32c8f0cae5d6c177bf83f52bb64ab5be (diff) |
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 on f6425da424b1a0d5927ee56fa657a9b31ca5afd1
(5.12) even though we were supposed to be using QCollator since commit
5279134935e858e6fa8565c936b17e88d7bded50 (5.3).
Fixes: QTBUG-95050
Change-Id: I7e0b82c2d2fe464082d8fffd1696a8c9f74e5b30
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit 94de5f9b25e1816039885c765e2a5b312f7daa7e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/corelib/text')
-rw-r--r-- | src/corelib/text/qlocale.cpp | 3 | ||||
-rw-r--r-- | src/corelib/text/qlocale_p.h | 2 | ||||
-rw-r--r-- | src/corelib/text/qstring.cpp | 24 |
3 files changed, 25 insertions, 4 deletions
diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index d5cde8a69d..ca4f7733f3 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -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); } /*! diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h index be495eaf43..a547dad7b7 100644 --- a/src/corelib/text/qlocale_p.h +++ b/src/corelib/text/qlocale_p.h @@ -424,6 +424,8 @@ public: QBasicAtomicInt ref; const uint m_index; QLocale::NumberOptions m_numberOptions; + + static QBasicAtomicInt s_generation; }; #ifndef QT_NO_SYSTEMLOCALE diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 619a03a013..23cca86c52 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -6137,7 +6137,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 /*! @@ -6159,8 +6177,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); |