diff options
author | David Faure <faure@kde.org> | 2014-06-28 00:19:31 +0200 |
---|---|---|
committer | David Faure <faure@kde.org> | 2014-07-01 10:26:54 +0200 |
commit | 054d849879647fd4cf90c4f622877d3a11720bb2 (patch) | |
tree | 1d416f76dab387122f5eb45ffb0aad309bdd57cc | |
parent | 55c055470aa4f8e153688c7720811c6413d71346 (diff) | |
download | kconfig-054d849879647fd4cf90c4f622877d3a11720bb2.tar.gz kconfig-054d849879647fd4cf90c4f622877d3a11720bb2.tar.bz2 |
KSharedConfig: move mainConfig and wasTestEnabled to the thread storage.
This enables the mainConfig optimization in all threads,
and ensures the user warning only happens in the main thread.
The test-mode-enabled logic is only really useful in the main thread,
but it's simpler to just do it in all threads.
REVIEW: 118985
-rw-r--r-- | autotests/kconfigtest.cpp | 10 | ||||
-rw-r--r-- | src/core/ksharedconfig.cpp | 32 |
2 files changed, 28 insertions, 14 deletions
diff --git a/autotests/kconfigtest.cpp b/autotests/kconfigtest.cpp index b621ac55..3156aa5e 100644 --- a/autotests/kconfigtest.cpp +++ b/autotests/kconfigtest.cpp @@ -95,6 +95,9 @@ void KConfigTest::initTestCase() // to make sure all files from a previous failed run are deleted cleanupTestCase(); + KSharedConfigPtr mainConfig = KSharedConfig::openConfig(); + mainConfig->group("Main").writeEntry("Key", "Value"); + KConfig sc(TEST_SUBDIR "kconfigtest"); KConfigGroup cg(&sc, "AAA"); @@ -1411,6 +1414,11 @@ void KConfigTest::testSharedConfig() myConfigGroup = KConfigGroup(config, "Hello"); } QCOMPARE(myConfigGroup.readEntry("stringEntry1"), QString(STRINGENTRY1)); + + // Get the main config + KSharedConfigPtr mainConfig = KSharedConfig::openConfig(); + KConfigGroup mainGroup(mainConfig, "Main"); + QCOMPARE(mainGroup.readEntry("Key", QString()), QString("Value")); } void KConfigTest::testLocaleConfig() @@ -1676,6 +1684,8 @@ void KConfigTest::testThreads() futures << QtConcurrent::run(this, &KConfigTest::testAddConfigSources); futures << QtConcurrent::run(this, &KConfigTest::testSimple); futures << QtConcurrent::run(this, &KConfigTest::testDefaults); + futures << QtConcurrent::run(this, &KConfigTest::testSharedConfig); + futures << QtConcurrent::run(this, &KConfigTest::testSharedConfig); // QEXPECT_FAIL triggers race conditions, it should be fixed to use QThreadStorage... //futures << QtConcurrent::run(this, &KConfigTest::testDeleteWhenLocalized); //futures << QtConcurrent::run(this, &KConfigTest::testEntryMap); diff --git a/src/core/ksharedconfig.cpp b/src/core/ksharedconfig.cpp index b7d155d5..e059b87a 100644 --- a/src/core/ksharedconfig.cpp +++ b/src/core/ksharedconfig.cpp @@ -33,6 +33,7 @@ class GlobalSharedConfigList : public QList<KSharedConfig *> { public: GlobalSharedConfigList() + : wasTestModeEnabled(false) { if (!qApp || QThread::currentThread() == qApp->thread()) { // We want to force the sync() before the QCoreApplication @@ -41,11 +42,14 @@ public: // existent app... qAddPostRoutine(&_k_globalMainConfigSync); } + // In other threads, QThreadStorage takes care of deleting the GlobalSharedConfigList when + // the thread exits. } // in addition to the list, we need to hold the main config, // so that it's not created and destroyed all the time. KSharedConfigPtr mainConfig; + bool wasTestModeEnabled; }; static QThreadStorage<GlobalSharedConfigList *> s_storage; @@ -80,30 +84,30 @@ KSharedConfigPtr KSharedConfig::openConfig(const QString &_fileName, fileName = KConfig::mainConfigName(); } - static QBasicAtomicInt wasTestModeEnabled = Q_BASIC_ATOMIC_INITIALIZER(false); - if (!wasTestModeEnabled && QStandardPaths::isTestModeEnabled()) { - wasTestModeEnabled = true; + if (!list->wasTestModeEnabled && QStandardPaths::isTestModeEnabled()) { + list->wasTestModeEnabled = true; list->clear(); list->mainConfig = Q_NULLPTR; } - if (list) { - foreach (auto cfg, *static_cast<const GlobalSharedConfigList*>(list)) { - if (cfg->name() == fileName && - cfg->d_ptr->openFlags == flags && - cfg->locationType() == resType -// cfg->backend()->type() == backend - ) { - return KSharedConfigPtr(cfg); - } + foreach (auto cfg, *static_cast<const GlobalSharedConfigList*>(list)) { + if (cfg->name() == fileName && + cfg->d_ptr->openFlags == flags && + cfg->locationType() == resType +// cfg->backend()->type() == backend + ) { + return KSharedConfigPtr(cfg); } } + KSharedConfigPtr ptr(new KSharedConfig(fileName, flags, resType)); + if (_fileName.isEmpty() && flags == FullConfig && resType == QStandardPaths::GenericConfigLocation) { list->mainConfig = ptr; - static QBasicAtomicInt userWarned = Q_BASIC_ATOMIC_INITIALIZER(false); - if (!userWarned) { + const bool isMainThread = !qApp || QThread::currentThread() == qApp->thread(); + static bool userWarned = false; + if (isMainThread && !userWarned) { userWarned = true; QByteArray readOnly = qgetenv("KDE_HOME_READONLY"); if (readOnly.isEmpty() && QCoreApplication::applicationName() != QLatin1String("kdialog")) { |