[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdelibs/kdecore
From: David Faure <faure () kde ! org>
Date: 2009-02-24 22:01:36
Message-ID: 1235512896.874475.20251.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 931177 by dfaure:
Thread safety for KStandardDirs's const methods.
M +8 -5 kernel/kcmdlineargs.cpp
M +43 -37 kernel/kstandarddirs.cpp
M +13 -2 kernel/kstandarddirs.h
M +11 -9 tests/kstandarddirstest.cpp
--- trunk/KDE/kdelibs/kdecore/kernel/kcmdlineargs.cpp #931176:931177
@@ -101,8 +101,9 @@
public:
KCmdLineArgsList() { }
~KCmdLineArgsList() {
- while (count())
- delete takeFirst();
+ // Can't use qDeleteAll(*this), ~KCmdLineArgs is a friend of KCmdLineArgsList \
only. + while (count())
+ delete takeFirst();
}
};
@@ -171,7 +172,7 @@
char **argv; // The original argv
bool parsed : 1; // Whether we have parsed the arguments since calling init
bool ignoreUnknown : 1; // Ignore unknown options and arguments
- QString mCwd; // Current working directory. Important for KUnqiueApp!
+ QString mCwd; // Current working directory. Important for KUniqueApp!
KCmdLineArgs::StdCmdLineArgs mStdargs;
KCmdLineOptions qt_options;
@@ -263,8 +264,10 @@
mStdargs = 0;
// Text codec.
+ setlocale(LC_ALL, ""); // need to initialize "System" codec, i.e. iconv
+ extern Q_CORE_EXPORT bool qt_locale_initialized;
+ qt_locale_initialized = true;
codec = QTextCodec::codecForLocale();
- setlocale(LC_ALL, ""); // need to initialize "System" codec, i.e. iconv
// Qt options
//FIXME: Check if other options are specific to Qt/X11
@@ -579,7 +582,7 @@
QByteArray qCwd;
ds >> qCwd;
- s->mCwd = QFile::decodeName(qCwd); //FIXME: Is this proper decoding?
+ s->mCwd = QFile::decodeName(qCwd);
uint count;
ds >> count;
--- trunk/KDE/kdelibs/kdecore/kernel/kstandarddirs.cpp #931176:931177
@@ -2,6 +2,7 @@
Copyright (C) 1999 Sirtaj Singh Kang <taj@kde.org>
Copyright (C) 1999,2007 Stephan Kulow <coolo@kde.org>
Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
+ Copyright (C) 2009 David Faure <faure@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -59,6 +60,7 @@
#include <shlobj.h>
#endif
+#include <QMutex>
#include <QtCore/QRegExp>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
@@ -70,6 +72,7 @@
KStandardDirsPrivate(KStandardDirs* qq)
: m_restrictionsActive(false),
m_checkRestrictions(true),
+ m_cacheMutex(QMutex::Recursive), // resourceDirs is recursive
q(qq)
{ }
@@ -80,27 +83,27 @@
bool m_restrictionsActive : 1;
bool m_checkRestrictions : 1;
QMap<QByteArray, bool> m_restrictions;
+
QStringList xdgdata_prefixes;
QStringList xdgconf_prefixes;
+ QStringList m_prefixes;
- QStringList prefixes;
-
// Directory dictionaries
- QMap<QByteArray, QStringList> absolutes;
- QMap<QByteArray, QStringList> relatives;
+ QMap<QByteArray, QStringList> m_absolutes;
+ QMap<QByteArray, QStringList> m_relatives;
- mutable QMap<QByteArray, QStringList> dircache;
- mutable QMap<QByteArray, QString> savelocations;
+ // Caches (protected by mutex in const methods, cf ctor docu)
+ QMap<QByteArray, QStringList> m_dircache;
+ QMap<QByteArray, QString> m_savelocations;
+ QMutex m_cacheMutex;
KStandardDirs* q;
};
/* If you add a new resource type here, make sure to
- * 1) regenerate using "generate_string_table.pl types" and the data below.
+ * 1) regenerate using "kdesdk/scripts/generate_string_table.pl types < tmpfile" \
with the data below in tmpfile.
* 2) update the KStandardDirs class documentation
- * 3) update the kde_default code
- * 4) update the kde_default documentation
- * 5) update the list in kde-config.cpp
+ * 3) update the list in kde-config.cpp
data
share/apps
@@ -311,9 +314,9 @@
if (dir.at(dir.length() - 1) != '/')
dir += '/';
- if (!d->prefixes.contains(dir)) {
- priorityAdd(d->prefixes, dir, priority);
- d->dircache.clear();
+ if (!d->m_prefixes.contains(dir)) {
+ priorityAdd(d->m_prefixes, dir, priority);
+ d->m_dircache.clear();
}
}
@@ -333,7 +336,7 @@
if (!d->xdgconf_prefixes.contains(dir)) {
priorityAdd(d->xdgconf_prefixes, dir, priority);
- d->dircache.clear();
+ d->m_dircache.clear();
}
}
@@ -353,13 +356,13 @@
if (!d->xdgdata_prefixes.contains(dir)) {
priorityAdd(d->xdgdata_prefixes, dir, priority);
- d->dircache.clear();
+ d->m_dircache.clear();
}
}
QString KStandardDirs::kfsstnd_prefixes()
{
- return d->prefixes.join(QString(QChar(KPATH_SEPARATOR)));
+ return d->m_prefixes.join(QString(QChar(KPATH_SEPARATOR)));
}
QString KStandardDirs::kfsstnd_xdg_conf_prefixes()
@@ -394,14 +397,14 @@
if (copy.at(copy.length() - 1) != '/')
copy += '/';
- QStringList& rels = d->relatives[type]; // find or insert
+ QStringList& rels = d->m_relatives[type]; // find or insert
if (!rels.contains(copy)) {
if (priority)
rels.prepend(copy);
else
rels.append(copy);
- d->dircache.remove(type); // clean the cache
+ d->m_dircache.remove(type); // clean the cache
return true;
}
return false;
@@ -418,13 +421,13 @@
if (copy.at(copy.length() - 1) != '/')
copy += '/';
- QStringList &paths = d->absolutes[type];
+ QStringList &paths = d->m_absolutes[type];
if (!paths.contains(copy)) {
if (priority)
paths.prepend(copy);
else
paths.append(copy);
- d->dircache.remove(type); // clean the cache
+ d->m_dircache.remove(type); // clean the cache
return true;
}
return false;
@@ -439,8 +442,8 @@
#if 0
kDebug(180) << "Find resource: " << type;
- for (QStringList::ConstIterator pit = prefixes.begin();
- pit != prefixes.end();
+ for (QStringList::ConstIterator pit = m_prefixes.begin();
+ pit != m_prefixes.end();
++pit)
{
kDebug(180) << "Prefix: " << *pit;
@@ -871,7 +874,7 @@
char hostname[256];
hostname[0] = 0;
gethostname(hostname, 255);
- const QString localkdedir = prefixes.first();
+ const QString localkdedir = m_prefixes.first();
QString dir = QString("%1%2-%3").arg(localkdedir).arg(type).arg(hostname);
char link[1024];
link[1023] = 0;
@@ -941,15 +944,16 @@
QStringList KStandardDirs::KStandardDirsPrivate::resourceDirs(const char* type, \
const QString& subdirForRestrictions) {
+ QMutexLocker lock(&m_cacheMutex);
const bool dataRestrictionActive = m_restrictionsActive
&& (strcmp(type, "data") == 0)
&& \
hasDataRestrictions(subdirForRestrictions);
- QMap<QByteArray, QStringList>::const_iterator dirCacheIt = \
dircache.constFind(type); + QMap<QByteArray, QStringList>::const_iterator \
dirCacheIt = m_dircache.constFind(type);
QStringList candidates;
- if (dirCacheIt != dircache.constEnd() && !dataRestrictionActive) {
+ if (dirCacheIt != m_dircache.constEnd() && !dataRestrictionActive) {
//qDebug() << this << "resourceDirs(" << type << "), in cache already";
candidates = *dirCacheIt;
}
@@ -976,7 +980,7 @@
}
QStringList dirs;
- dirs = relatives.value(type);
+ dirs = m_relatives.value(type);
const QString typeInstallPath = installPath(type); // could be empty
const QString installdir = typeInstallPath.isEmpty() ? QString() : \
realPath(typeInstallPath); const QString installprefix = installPath("kdedir");
@@ -1012,7 +1016,7 @@
else if (strncmp(type, "xdgconf-", 8) == 0)
prefixList = &(xdgconf_prefixes);
else
- prefixList = &prefixes;
+ prefixList = &m_prefixes;
for (QStringList::ConstIterator pit = prefixList->begin();
pit != prefixList->end();
@@ -1057,7 +1061,7 @@
candidates.append(installdir);
}
- dirs = absolutes.value(type);
+ dirs = m_absolutes.value(type);
if (!dirs.isEmpty())
for (QStringList::ConstIterator it = dirs.constBegin();
it != dirs.constEnd(); ++it)
@@ -1075,7 +1079,7 @@
// Exception: data_subdir restrictions are per-subdir, so we can't store \
such results if (!dataRestrictionActive) {
//kDebug() << this << "Inserting" << type << candidates << "into \
dircache";
- dircache.insert(type, candidates);
+ m_dircache.insert(type, candidates);
}
}
@@ -1298,17 +1302,18 @@
const QString& suffix,
bool create) const
{
- QString path = d->savelocations.value(type);
+ QMutexLocker lock(&d->m_cacheMutex);
+ QString path = d->m_savelocations.value(type);
if (path.isEmpty())
{
- QStringList dirs = d->relatives.value(type);
+ QStringList dirs = d->m_relatives.value(type);
if (dirs.isEmpty() && (
(strcmp(type, "socket") == 0) ||
(strcmp(type, "tmp") == 0) ||
(strcmp(type, "cache") == 0) ))
{
(void) resourceDirs(type); // Generate socket|tmp|cache resource.
- dirs = d->relatives.value(type); // Search again.
+ dirs = d->m_relatives.value(type); // Search again.
}
if (!dirs.isEmpty())
{
@@ -1333,14 +1338,14 @@
}
}
else {
- dirs = d->absolutes.value(type);
+ dirs = d->m_absolutes.value(type);
if (dirs.isEmpty()) {
qFatal("KStandardDirs: The resource type %s is not registered", \
type); }
path = realPath(dirs.last());
}
- d->savelocations.insert(type, path.endsWith('/') ? path : path + '/');
+ d->m_savelocations.insert(type, path.endsWith('/') ? path : path + '/');
}
QString fullPath = path + suffix;
@@ -1357,13 +1362,14 @@
if(!makeDir(fullPath, 0700)) {
return fullPath;
}
- d->dircache.remove(type);
+ d->m_dircache.remove(type);
}
if (!fullPath.endsWith('/'))
fullPath += '/';
return fullPath;
}
+// KDE5: make the method const
QString KStandardDirs::relativeLocation(const char *type, const QString &absPath)
{
QString fullPath = absPath;
@@ -1848,7 +1854,7 @@
{
d->m_restrictionsActive = true;
d->m_restrictions.insert(key.toLatin1(), true);
- d->dircache.remove(key.toLatin1());
+ d->m_dircache.remove(key.toLatin1());
}
}
}
@@ -1864,7 +1870,7 @@
QString KStandardDirs::localkdedir() const
{
// Return the prefix to use for saving
- return d->prefixes.first();
+ return d->m_prefixes.first();
}
QString KStandardDirs::localxdgdatadir() const
--- trunk/KDE/kdelibs/kdecore/kernel/kstandarddirs.h #931176:931177
@@ -177,7 +177,18 @@
public:
/**
* KStandardDirs' constructor. It just initializes the caches.
- **/
+ * Note that you should normally not call this, but use KGlobal::dirs()
+ * instead, in order to reuse the same KStandardDirs object as much as possible.
+ *
+ * Creating other KStandardDirs instances can be useful in other threads.
+ *
+ * Thread safety note: using a shared KStandardDirs instance (such as \
KGlobal::dirs()) + * in multiple threads is thread-safe if you only call the \
readonly "lookup" methods + * (findExe, resourceDirs, findDirs, findResourceDir, \
findAllResources, saveLocation, + * relativeLocation). The methods that modify \
the object (all those starting with "add", + * basically all non-const methods) \
are obviously not thread-safe; set things up + * before creating threads.
+ */
KStandardDirs();
enum SearchOption { NoSearchOptions = 0,
@@ -189,7 +200,7 @@
/**
* KStandardDirs' destructor.
*/
- virtual ~KStandardDirs();
+ virtual ~KStandardDirs();
/**
* Adds another search dir to front of the @p fsstnd list.
--- trunk/KDE/kdelibs/kdecore/tests/kstandarddirstest.cpp #931176:931177
@@ -345,13 +345,15 @@
// To find multithreading bugs: valgrind --tool=helgrind ./kstandarddirstest \
testThreads void KStandarddirsTest::testThreads()
{
- QThreadPool::globalInstance()->setMaxThreadCount(5);
- QFuture<void> f1 = QtConcurrent::run(this, &KStandarddirsTest::testLocateLocal);
- QFuture<void> f2 = QtConcurrent::run(this, \
&KStandarddirsTest::testSaveLocation);
- QFuture<void> f3 = QtConcurrent::run(this, \
&KStandarddirsTest::testFindResource);
- QFuture<void> f4 = QtConcurrent::run(this, \
&KStandarddirsTest::testFindAllResources);
- f1.waitForFinished();
- f2.waitForFinished();
- f3.waitForFinished();
- f4.waitForFinished();
+ QThreadPool::globalInstance()->setMaxThreadCount(6);
+ QList<QFuture<void> > futures;
+ futures << QtConcurrent::run(this, &KStandarddirsTest::testLocateLocal);
+ futures << QtConcurrent::run(this, &KStandarddirsTest::testSaveLocation);
+ futures << QtConcurrent::run(this, &KStandarddirsTest::testAppData);
+ futures << QtConcurrent::run(this, &KStandarddirsTest::testFindResource);
+ futures << QtConcurrent::run(this, &KStandarddirsTest::testFindAllResources);
+ futures << QtConcurrent::run(this, &KStandarddirsTest::testLocate);
+ futures << QtConcurrent::run(this, &KStandarddirsTest::testRelativeLocation);
+ Q_FOREACH(QFuture<void> f, futures)
+ f.waitForFinished();
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic