summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/coreplugin/mimedatabase.cpp50
-rw-r--r--src/plugins/coreplugin/mimedatabase.h24
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp72
3 files changed, 108 insertions, 38 deletions
diff --git a/src/plugins/coreplugin/mimedatabase.cpp b/src/plugins/coreplugin/mimedatabase.cpp
index b39eed1518..155fc75544 100644
--- a/src/plugins/coreplugin/mimedatabase.cpp
+++ b/src/plugins/coreplugin/mimedatabase.cpp
@@ -44,6 +44,7 @@
#include <QtCore/QSharedPointer>
#include <QtCore/QStringList>
#include <QtCore/QTextStream>
+#include <QtCore/QMutexLocker>
#include <QtXml/QXmlStreamReader>
@@ -1125,56 +1126,85 @@ MimeDatabase::~MimeDatabase()
MimeType MimeDatabase::findByType(const QString &typeOrAlias) const
{
- return m_d->findByType(typeOrAlias);
+ m_mutex.lock();
+ const MimeType rc = m_d->findByType(typeOrAlias);
+ m_mutex.unlock();
+ return rc;
}
-MimeType MimeDatabase::findByFile(const QFileInfo &f) const
+MimeType MimeDatabase::findByFileUnlocked(const QFileInfo &f) const
{
return m_d->findByFile(f);
}
+MimeType MimeDatabase::findByFile(const QFileInfo &f) const
+{
+ m_mutex.lock();
+ const MimeType rc = findByFileUnlocked(f);
+ m_mutex.unlock();
+ return rc;
+}
+
bool MimeDatabase::addMimeType(const MimeType &mt)
{
- return m_d->addMimeType(mt);
+ m_mutex.lock();
+ const bool rc = m_d->addMimeType(mt);
+ m_mutex.unlock();
+ return rc;
}
bool MimeDatabase::addMimeTypes(const QString &fileName, QString *errorMessage)
{
- return m_d->addMimeTypes(fileName, errorMessage);
+ m_mutex.lock();
+ const bool rc = m_d->addMimeTypes(fileName, errorMessage);
+ m_mutex.unlock();
+ return rc;
}
bool MimeDatabase::addMimeTypes(QIODevice *device, QString *errorMessage)
{
- return m_d->addMimeTypes(device, errorMessage);
+ m_mutex.lock();
+ const bool rc = m_d->addMimeTypes(device, errorMessage);
+ m_mutex.unlock();
+ return rc;
}
QStringList MimeDatabase::suffixes() const
{
- return m_d->suffixes();
+ m_mutex.lock();
+ const QStringList rc = m_d->suffixes();
+ m_mutex.unlock();
+ return rc;
}
QStringList MimeDatabase::filterStrings() const
{
- return m_d->filterStrings();
+ m_mutex.lock();
+ const QStringList rc = m_d->filterStrings();
+ m_mutex.unlock();
+ return rc;
}
QString MimeDatabase::preferredSuffixByType(const QString &type) const
{
if (const MimeType mt = findByType(type))
- return mt.preferredSuffix();
+ return mt.preferredSuffix(); // already does Mutex locking
return QString();
}
QString MimeDatabase::preferredSuffixByFile(const QFileInfo &f) const
{
if (const MimeType mt = findByFile(f))
- return mt.preferredSuffix();
+ return mt.preferredSuffix(); // already does Mutex locking
return QString();
}
bool MimeDatabase::setPreferredSuffix(const QString &typeOrAlias, const QString &suffix)
{
- return m_d->setPreferredSuffix(typeOrAlias, suffix);
+ m_mutex.lock();
+ const bool rc = m_d->setPreferredSuffix(typeOrAlias, suffix);
+ m_mutex.unlock();
+ return rc;
}
QDebug operator<<(QDebug d, const MimeDatabase &mt)
diff --git a/src/plugins/coreplugin/mimedatabase.h b/src/plugins/coreplugin/mimedatabase.h
index ed932a69c9..a7397e6384 100644
--- a/src/plugins/coreplugin/mimedatabase.h
+++ b/src/plugins/coreplugin/mimedatabase.h
@@ -35,6 +35,7 @@
#include <QtCore/QSharedDataPointer>
#include <QtCore/QSharedPointer>
#include <QtCore/QByteArray>
+#include <QtCore/QMutex>
QT_BEGIN_NAMESPACE
class QIODevice;
@@ -186,7 +187,7 @@ private:
/* A Mime data base to which the plugins can add the mime types they handle.
* When adding a "text/plain" to it, the mimetype will receive a magic matcher
* that checks for text files that do not match the globs by heuristics.
- *
+ * The class is protected by a QMutex and can therefore be accessed by threads.
* A good testcase is to run it over '/usr/share/mime/<*>/<*>.xml' on Linux. */
class CORE_EXPORT MimeDatabase
@@ -203,8 +204,15 @@ public:
// Returns a mime type or Null one if none found
MimeType findByType(const QString &type) const;
+
// Returns a mime type or Null one if none found
MimeType findByFile(const QFileInfo &f) const;
+ // Convenience that mutex-locks the DB and calls a function
+ // of the signature 'void f(const MimeType &, const QFileInfo &, const QString &)'
+ // for each filename of a sequence. This avoids locking the DB for each
+ // single file.
+ template <class Iterator, typename Function>
+ inline void findByFile(Iterator i1, const Iterator &i2, Function f) const;
// Convenience
QString preferredSuffixByType(const QString &type) const;
@@ -219,9 +227,23 @@ public:
friend QDebug operator<<(QDebug d, const MimeDatabase &mt);
private:
+ MimeType findByFileUnlocked(const QFileInfo &f) const;
+
MimeDatabasePrivate *m_d;
+ mutable QMutex m_mutex;
};
+template <class Iterator, typename Function>
+ void MimeDatabase::findByFile(Iterator i1, const Iterator &i2, Function f) const
+{
+ m_mutex.lock();
+ for ( ; i1 != i2; ++i1) {
+ const QFileInfo fi(*i1);
+ f(findByFileUnlocked(fi), fi, *i1);
+ }
+ m_mutex.unlock();
+}
+
} // namespace Core
#endif // MIMEDATABASE_H
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index ffd8fdb079..5d193738be 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -1227,6 +1227,41 @@ void CppModelManager::updateIncludesInPaths(QFutureInterface<void> &future,
future.reportFinished();
}
+// Function that sorts headers and sources apart to be used for
+// MimeDB::findByFile() on a sequence of file names.
+class HeaderSourceSorter {
+public:
+ explicit HeaderSourceSorter(QStringList *sources, QStringList *headers);
+ void operator()(const Core::MimeType &, const QFileInfo &, const QString &);
+
+private:
+ QStringList m_sourceMimeTypes;
+ QStringList m_headerMimeTypes;
+
+ QStringList *m_sources;
+ QStringList *m_headers;
+};
+
+HeaderSourceSorter::HeaderSourceSorter(QStringList *sources, QStringList *headers) :
+ m_sources(sources),
+ m_headers(headers)
+{
+ m_headerMimeTypes << QLatin1String("text/x-hdr") << QLatin1String("text/x-c++hdr");
+ m_sourceMimeTypes << QLatin1String("text/x-csrc") << QLatin1String("text/x-c++src")
+ << QLatin1String("text/x-objcsrc");
+}
+
+void HeaderSourceSorter::operator()(const Core::MimeType &mimeType, const QFileInfo &, const QString &name)
+{
+ if (mimeType) {
+ if (m_sourceMimeTypes.contains(mimeType.type())) {
+ m_sources->append(name);
+ } else if (m_headerMimeTypes.contains(mimeType.type())) {
+ m_headers->append(name);
+ }
+ }
+}
+
void CppModelManager::parse(QFutureInterface<void> &future,
CppPreprocessor *preproc,
QStringList files)
@@ -1234,31 +1269,17 @@ void CppModelManager::parse(QFutureInterface<void> &future,
if (files.isEmpty())
return;
- Core::MimeDatabase *db = Core::ICore::instance()->mimeDatabase();
- QStringList headers, sources;
- Core::MimeType cSourceTy = db->findByType(QLatin1String("text/x-csrc"));
- Core::MimeType cppSourceTy = db->findByType(QLatin1String("text/x-c++src"));
- Core::MimeType mSourceTy = db->findByType(QLatin1String("text/x-objcsrc"));
-
- Core::MimeType cHeaderTy = db->findByType(QLatin1String("text/x-hdr"));
- Core::MimeType cppHeaderTy = db->findByType(QLatin1String("text/x-c++hdr"));
-
- foreach (const QString &file, files) {
- const QFileInfo fileInfo(file);
-
- if (cSourceTy.matchesFile(fileInfo) || cppSourceTy.matchesFile(fileInfo) || mSourceTy.matchesFile(fileInfo))
- sources.append(file);
-
- else if (cHeaderTy.matchesFile(fileInfo) || cppHeaderTy.matchesFile(fileInfo))
- headers.append(file);
- }
-
- foreach (const QString &file, files) {
- preproc->snapshot.remove(file);
- }
+ QStringList sources;
+ QStringList headers;
+ const Core::MimeDatabase *mimeDb = Core::ICore::instance()->mimeDatabase();
+ mimeDb->findByFile(files.constBegin(), files.constEnd(),
+ HeaderSourceSorter(&sources, &headers));
+ const int sourceCount = sources.size();
files = sources;
files += headers;
+ foreach (const QString &file, files)
+ preproc->snapshot.remove(file);
preproc->setTodo(files);
@@ -1278,12 +1299,9 @@ void CppModelManager::parse(QFutureInterface<void> &future,
// Change the priority of the background parser thread to idle.
QThread::currentThread()->setPriority(QThread::IdlePriority);
- QString fileName = files.at(i);
-
- bool isSourceFile = false;
- if (cppSourceTy.matchesFile(fileName) || cSourceTy.matchesFile(fileName))
- isSourceFile = true;
+ const QString fileName = files.at(i);
+ const bool isSourceFile = i < sourceCount;
if (isSourceFile)
(void) preproc->run(conf);