summaryrefslogtreecommitdiffstats
path: root/src/corelib/codecs/qtextcodec.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2012-07-25 10:16:59 +0200
committerQt by Nokia <qt-info@nokia.com>2012-07-31 11:12:35 +0200
commit34721c4d3690335d2d9fe79620e566fda78de25b (patch)
tree1f4b00499b8bc5749b503f25a13bb103f97443bf /src/corelib/codecs/qtextcodec.cpp
parent88d2e92b39ffd4a6ea9446498ad5a1cb208022a6 (diff)
Make codecForLocale atomic
Change-Id: I8017b1c2aa1df8d613e83919a945fd5f320713d6 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/codecs/qtextcodec.cpp')
-rw-r--r--src/corelib/codecs/qtextcodec.cpp71
1 files changed, 35 insertions, 36 deletions
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index b3607d421f..3b0afdd6cc 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -158,20 +158,25 @@ static QTextCodec *setupLocaleMapper()
{
QCoreGlobalData *globalData = QCoreGlobalData::instance();
- QMutexLocker locker(textCodecsMutex());
- if (globalData->codecForLocale)
+ QTextCodec *locale = globalData->codecForLocale.loadAcquire();
+ if (locale)
// already setup
- return globalData->codecForLocale;
- setup();
+ return locale;
+
+ {
+ QMutexLocker locker(textCodecsMutex());
+ if (globalData->allCodecs.isEmpty())
+ setup();
+ }
#if !defined(QT_BOOTSTRAPPED)
QCoreApplicationPrivate::initLocale();
#endif
#if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
- globalData->codecForLocale = QTextCodec::codecForName("System");
+ locale = QTextCodec::codecForName("System");
#elif defined(Q_OS_MAC) || defined(Q_OS_IOS) || defined(Q_OS_LINUX_ANDROID) || defined(Q_OS_QNX)
- globalData->codecForLocale = QTextCodec::codecForName("UTF-8");
+ locale = QTextCodec::codecForName("UTF-8");
#else
// First try getting the codecs name from nl_langinfo and see
@@ -183,17 +188,17 @@ static QTextCodec *setupLocaleMapper()
#if defined (_XOPEN_UNIX) && !defined(Q_OS_OSF)
char *charset = nl_langinfo(CODESET);
if (charset)
- globalData->codecForLocale = QTextCodec::codecForName(charset);
+ locale = QTextCodec::codecForName(charset);
#endif
#if !defined(QT_NO_ICONV) && !defined(QT_BOOTSTRAPPED)
- if (!globalData->codecForLocale) {
+ if (!locale) {
// no builtin codec for the locale found, let's try using iconv
(void) new QIconvCodec();
- globalData->codecForLocale = QTextCodec::codecForName("System");
+ locale = QTextCodec::codecForName("System");
}
#endif
- if (!globalData->codecForLocale) {
+ if (!locale) {
// Very poorly defined and followed standards causes lots of
// code to try to get all the cases... This logic is
// duplicated in QIconvCodec, so if you change it here, change
@@ -229,33 +234,34 @@ static QTextCodec *setupLocaleMapper()
// 1. CODESET from ctype if it contains a .CODESET part (e.g. en_US.ISO8859-15)
int indexOfDot = ctype.indexOf('.');
if (indexOfDot != -1)
- globalData->codecForLocale = checkForCodec( ctype.mid(indexOfDot + 1) );
+ locale = checkForCodec( ctype.mid(indexOfDot + 1) );
// 2. CODESET from lang if it contains a .CODESET part
- if (!globalData->codecForLocale) {
+ if (!locale) {
indexOfDot = lang.indexOf('.');
if (indexOfDot != -1)
- globalData->codecForLocale = checkForCodec( lang.mid(indexOfDot + 1) );
+ locale = checkForCodec( lang.mid(indexOfDot + 1) );
}
// 3. ctype (maybe the locale is named "ISO-8859-1" or something)
- if (!globalData->codecForLocale && !ctype.isEmpty() && ctype != "C")
- globalData->codecForLocale = checkForCodec(ctype);
+ if (!locale && !ctype.isEmpty() && ctype != "C")
+ locale = checkForCodec(ctype);
// 4. locale (ditto)
- if (!globalData->codecForLocale && !lang.isEmpty())
- globalData->codecForLocale = checkForCodec(lang);
+ if (!locale && !lang.isEmpty())
+ locale = checkForCodec(lang);
// 5. "@euro"
- if ((!globalData->codecForLocale && ctype.contains("@euro")) || lang.contains("@euro"))
- globalData->codecForLocale = checkForCodec("ISO 8859-15");
+ if ((!locale && ctype.contains("@euro")) || lang.contains("@euro"))
+ locale = checkForCodec("ISO 8859-15");
}
// If everything failed, we default to 8859-1
- if (!globalData->codecForLocale)
- globalData->codecForLocale = QTextCodec::codecForName("ISO 8859-1");
+ if (!locale)
+ locale = QTextCodec::codecForName("ISO 8859-1");
#endif
- return globalData->codecForLocale;
+ globalData->codecForLocale.storeRelease(locale);
+ return locale;
}
// textCodecsMutex need to be locked to enter this function
@@ -269,9 +275,7 @@ static void setup()
for (int i = 0; i < QSimpleTextCodec::numSimpleCodecs; ++i)
(void)new QSimpleTextCodec(i);
-# if !defined(QT_NO_BIG_CODECS)
-
-# ifndef Q_OS_INTEGRITY
+# if !defined(QT_NO_BIG_CODECS) && !defined(Q_OS_INTEGRITY)
(void)new QGb18030Codec;
(void)new QGbkCodec;
(void)new QGb2312Codec;
@@ -282,20 +286,15 @@ static void setup()
(void)new QCP949Codec;
(void)new QBig5Codec;
(void)new QBig5hkscsCodec;
-# endif // !Q_OS_INTEGRITY
-
-# endif // !QT_NO_BIG_CODECS
-#endif // !QT_NO_CODECS && !QT_BOOTSTRAPPED
-#endif
-
-#if !defined(QT_BOOTSTRAPPED)
+# endif // !QT_NO_BIG_CODECS && !Q_OS_INTEGRITY
+#endif // QT_USE_ICU
#if !defined(QT_NO_ICONV)
(void) new QIconvCodec;
#endif
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
(void) new QWindowsLocalCodec;
#endif // Q_OS_WIN32
-#endif
+#endif // !QT_NO_CODECS && !QT_BOOTSTRAPPED
(void)new QUtf16Codec;
(void)new QUtf16BECodec;
@@ -659,7 +658,7 @@ QList<int> QTextCodec::availableMibs()
*/
void QTextCodec::setCodecForLocale(QTextCodec *c)
{
- QCoreGlobalData::instance()->codecForLocale = c;
+ QCoreGlobalData::instance()->codecForLocale.storeRelease(c);
}
/*!
@@ -678,8 +677,8 @@ QTextCodec* QTextCodec::codecForLocale()
if (!globalData)
return 0;
- QTextCodec *codec = globalData->codecForLocale;
- if (!globalData->codecForLocale)
+ QTextCodec *codec = globalData->codecForLocale.loadAcquire();
+ if (!codec)
codec = setupLocaleMapper();
return codec;