diff options
-rw-r--r-- | src/plugins/coreplugin/mimedatabase.cpp | 50 | ||||
-rw-r--r-- | src/plugins/coreplugin/mimedatabase.h | 24 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager.cpp | 72 |
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); |