summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAram So <aram.so@lge.com>2016-11-14 16:42:32 +0900
committerSimon Hausmann <simon.hausmann@qt.io>2017-07-06 18:26:41 +0000
commit06904a7a772357479a1b78b8345716f8d0711b4c (patch)
tree94cbcdb03c148e1832d31aa3ee3a0b2de68e4e66 /src
parent8143f60026456f98aaf2b6afaf1edadfbeb2f1e7 (diff)
Make calling QCoreApplication::translate() thread-safe
Fixed crash on QCoreApplication::translate() call from qqmlThread while QCoreApplication::{install,remove}Translator() is called from the GUI thread. [ChangeLog][QtCore][QCoreApplication] Calling QCoreApplication::translate() is now thread-safe. Task-number: QTBUG-57095 Change-Id: Ie5340a42040a829f311c01332e05d4bbaf60462c Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp44
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h2
2 files changed, 26 insertions, 20 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index a5bd2513b6..a08021be96 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -1931,7 +1931,10 @@ bool QCoreApplication::installTranslator(QTranslator *translationFile)
if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
return false;
QCoreApplicationPrivate *d = self->d_func();
- d->translators.prepend(translationFile);
+ {
+ QWriteLocker locker(&d->translateMutex);
+ d->translators.prepend(translationFile);
+ }
#ifndef QT_NO_TRANSLATION_BUILDER
if (translationFile->isEmpty())
@@ -1963,8 +1966,10 @@ bool QCoreApplication::removeTranslator(QTranslator *translationFile)
if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
return false;
QCoreApplicationPrivate *d = self->d_func();
+ QWriteLocker locker(&d->translateMutex);
if (d->translators.removeAll(translationFile)) {
#ifndef QT_NO_QOBJECT
+ locker.unlock();
if (!self->closingDown()) {
QEvent ev(QEvent::LanguageChange);
QCoreApplication::sendEvent(self, &ev);
@@ -2000,7 +2005,7 @@ static void replacePercentN(QString *result, int n)
}
/*!
- \reentrant
+ \threadsafe
Returns the translation text for \a sourceText, by querying the
installed translation files. The translation files are searched
@@ -2029,13 +2034,7 @@ static void replacePercentN(QString *result, int n)
This function is not virtual. You can use alternative translation
techniques by subclassing \l QTranslator.
- \warning This method is reentrant only if all translators are
- installed \e before calling this method. Installing or removing
- translators while performing translations is not supported. Doing
- so will most likely result in crashes or other undesirable
- behavior.
-
- \sa QObject::tr(), installTranslator()
+ \sa QObject::tr(), installTranslator(), removeTranslator(), translate(), isTranslatorInstalled()
*/
QString QCoreApplication::translate(const char *context, const char *sourceText,
const char *disambiguation, int n)
@@ -2045,14 +2044,18 @@ QString QCoreApplication::translate(const char *context, const char *sourceText,
if (!sourceText)
return result;
- if (self && !self->d_func()->translators.isEmpty()) {
- QList<QTranslator*>::ConstIterator it;
- QTranslator *translationFile;
- for (it = self->d_func()->translators.constBegin(); it != self->d_func()->translators.constEnd(); ++it) {
- translationFile = *it;
- result = translationFile->translate(context, sourceText, disambiguation, n);
- if (!result.isNull())
- break;
+ if (self) {
+ QCoreApplicationPrivate *d = self->d_func();
+ QReadLocker locker(&d->translateMutex);
+ if (!d->translators.isEmpty()) {
+ QList<QTranslator*>::ConstIterator it;
+ QTranslator *translationFile;
+ for (it = d->translators.constBegin(); it != d->translators.constEnd(); ++it) {
+ translationFile = *it;
+ result = translationFile->translate(context, sourceText, disambiguation, n);
+ if (!result.isNull())
+ break;
+ }
}
}
@@ -2076,8 +2079,11 @@ QString qtTrId(const char *id, int n)
bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
{
- return QCoreApplication::self
- && QCoreApplication::self->d_func()->translators.contains(translator);
+ if (!QCoreApplication::self)
+ return false;
+ QCoreApplicationPrivate *d = QCoreApplication::self->d_func();
+ QReadLocker locker(&d->translateMutex);
+ return d->translators.contains(translator);
}
#else
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index da6ce1249f..963aec70e8 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -142,7 +142,7 @@ public:
#ifndef QT_NO_TRANSLATION
QTranslatorList translators;
-
+ QReadWriteLock translateMutex;
static bool isTranslatorInstalled(QTranslator *translator);
#endif