SVN commit 1196326 by dfaure: Calling KGlobal::locale() for the first time in a secondary thread was crashing already, but with lots of confusing Qt errors. Now make the behavior explicit and documented. Can't be changed, since we have to install the qtranslator in the main thread anyway. M +7 -1 kernel/kglobal.cpp M +20 -0 tests/kglobaltest.cpp --- trunk/KDE/kdelibs/kdecore/kernel/kglobal.cpp #1196325:1196326 @@ -28,6 +28,7 @@ #include "kglobal.h" #include "kglobal_p.h" +#include #include @@ -160,9 +161,14 @@ QTextCodec::setCodecForLocale(d->locale->codecForEncoding()); mainComponent().aboutData()->translateInternalProgramName(); QCoreApplication* coreApp = QCoreApplication::instance(); - if (coreApp) // testcase: kwrite --help: no qcore app + if (coreApp) { // testcase: kwrite --help: no qcore app + if (coreApp->thread() != QThread::currentThread()) { + qFatal("KGlobal::locale() must be called from the main thread before using i18n() in threads. KApplication takes care of this. If not using KApplication, call KGlobal::locale() during initialization."); + } else { QCoreApplication::installTranslator(new KDETranslator(coreApp)); } + } + } return d->locale; } --- trunk/KDE/kdelibs/kdecore/tests/kglobaltest.cpp #1196325:1196326 @@ -60,6 +60,26 @@ QVERIFY(!QTest::kWaitForSignal(this, SIGNAL(sigFoo()), 1)); } + // For testing from multiple threads in testThreads + void testLocale() + { + KGlobal::locale(); + KGlobal::locale()->setDecimalPlaces(2); + QCOMPARE(KGlobal::locale()->formatNumber(70), QString("70.00")); + } + + // Calling this directly aborts in KGlobal::locale(), this is intended. + // We have to install the qtranslator in the main thread. + void testThreads() + { + QThreadPool::globalInstance()->setMaxThreadCount(10); + QList > futures; + futures << QtConcurrent::run(this, &KGlobalTest::testLocale); + futures << QtConcurrent::run(this, &KGlobalTest::testLocale); + Q_FOREACH(QFuture f, futures) + f.waitForFinished(); + } + protected Q_SLOTS: void emitSigFoo() {