Commit 76b4acfa authored by Milian Wolff's avatar Milian Wolff
Browse files

Refactor ItemRepository to explicitly set mutex from outside

Instead of having m_ownMutex and a way to optionally override
that from the outside, always force the mutex to be provided
from the outside.

This is by itself not a functional change, but it will allow us
to get rid of the (deprecated) recursive mutices one by one, just
like we have established already in the indexedstring.cpp code.
I.e. all of the mutices we are providing are still recursive.
parent 743dfbc9
......@@ -165,13 +165,11 @@ public:
class CodeModelPrivate
{
public:
CodeModelPrivate() : m_repository(QStringLiteral("Code Model"))
{
}
QMutex m_mutex = QMutex(QMutex::Recursive);
//Maps declaration-ids to items
using Repo = ItemRepository<CodeModelRepositoryItem, CodeModelRequestItem>;
// mutable as things like findIndex are not const
mutable ItemRepository<CodeModelRepositoryItem, CodeModelRequestItem> m_repository;
mutable Repo m_repository{QStringLiteral("Code Model"), &m_mutex};
};
CodeModel::CodeModel()
......
......@@ -54,7 +54,8 @@ DeclarationData::DeclarationData()
///@todo Use reference counting
static Repositories::StringRepository& commentRepository()
{
static Repositories::StringRepository commentRepositoryObject(QStringLiteral("Comment Repository"));
static auto mutex = QMutex(QMutex::Recursive);
static Repositories::StringRepository commentRepositoryObject(QStringLiteral("Comment Repository"), &mutex);
return commentRepositoryObject;
}
......
......@@ -149,13 +149,11 @@ private:
class DefinitionsPrivate
{
public:
DefinitionsPrivate() : m_definitions(QStringLiteral("Definition Map"))
{
}
QMutex m_mutex = QMutex(QMutex::Recursive);
//Maps declaration-ids to definitions
using Repo = ItemRepository<DefinitionsItem, DefinitionsRequestItem>;
// mutable as things like findIndex are not const
mutable ItemRepository<DefinitionsItem, DefinitionsRequestItem> m_definitions;
mutable Repo m_definitions{QStringLiteral("Definition Map"), &m_mutex};
};
Definitions::Definitions()
......
......@@ -328,8 +328,8 @@ public:
: instance(nullptr)
, m_cleanupDisabled(false)
, m_destroyed(false)
, m_environmentListInfo(QStringLiteral("Environment Lists"))
, m_environmentInfo(QStringLiteral("Environment Information"))
, m_environmentListInfo(QStringLiteral("Environment Lists"), &m_environmentListInfoMutex)
, m_environmentInfo(QStringLiteral("Environment Information"), &m_environmentInfoMutex)
{
#if defined(TEST_NO_CLEANUP)
m_cleanupDisabled = true;
......@@ -1185,8 +1185,10 @@ private:
///The following repositories are thread-safe, and m_chainsMutex should not be locked when using them, because
///they may trigger I/O. Still it may be required to lock their local mutexes.
///Maps filenames to a list of top-contexts/environment-information.
QMutex m_environmentListInfoMutex = QMutex(QMutex::Recursive);
ItemRepository<EnvironmentInformationListItem, EnvironmentInformationListRequest> m_environmentListInfo;
///Maps top-context-indices to environment-information item.
QMutex m_environmentInfoMutex = QMutex(QMutex::Recursive);
ItemRepository<EnvironmentInformationItem, EnvironmentInformationRequest> m_environmentInfo;
};
......
......@@ -150,7 +150,8 @@ struct IdentifierItemRequest
using IdentifierRepository = RepositoryManager<ItemRepository<ConstantIdentifierPrivate, IdentifierItemRequest>, false>;
static IdentifierRepository& identifierRepository()
{
static IdentifierRepository identifierRepositoryObject(QStringLiteral("Identifier Repository"));
static auto mutex = QMutex(QMutex::Recursive);
static IdentifierRepository identifierRepositoryObject(QStringLiteral("Identifier Repository"), &mutex);
return identifierRepositoryObject;
}
......@@ -322,10 +323,8 @@ using QualifiedIdentifierRepository = RepositoryManager<ItemRepository<ConstantQ
static QualifiedIdentifierRepository& qualifiedidentifierRepository()
{
static QualifiedIdentifierRepository repo(QStringLiteral("Qualified Identifier Repository"), 1,
[]() -> AbstractRepositoryManager* {
return &identifierRepository();
});
static QualifiedIdentifierRepository repo(QStringLiteral("Qualified Identifier Repository"),
identifierRepository().repositoryMutex());
return repo;
}
......
......@@ -105,13 +105,11 @@ public:
class ImportersPrivate
{
public:
ImportersPrivate() : m_importers(QStringLiteral("Importer Map"))
{
}
//Maps declaration-ids to Importers
using Repo = ItemRepository<ImportersItem, ImportersRequestItem>;
QMutex m_mutex = QMutex(QMutex::Recursive);
// mutable as things like findIndex are not const
mutable ItemRepository<ImportersItem, ImportersRequestItem> m_importers;
mutable Repo m_importers{QStringLiteral("Importer Map"), &m_mutex};
};
Importers::Importers()
......
......@@ -125,9 +125,10 @@ AbstractRepositoryManager* returnTypeRepository()
static KDevelop::RepositoryManager<KDevelop::ItemRepository<InstantiationInformation,
AppendedListItemRequest<InstantiationInformation>>>& instantiationInformationRepository()
{
static KDevelop::RepositoryManager<KDevelop::ItemRepository<InstantiationInformation,
AppendedListItemRequest<InstantiationInformation>>> instantiationInformationRepositoryObject(QStringLiteral(
"Instantiation Information Repository"), 1, &returnTypeRepository);
static KDevelop::RepositoryManager<
KDevelop::ItemRepository<InstantiationInformation, AppendedListItemRequest<InstantiationInformation>>>
instantiationInformationRepositoryObject(QStringLiteral("Instantiation Information Repository"),
returnTypeRepository()->repositoryMutex());
return instantiationInformationRepositoryObject;
}
......
......@@ -45,8 +45,9 @@ constexpr TextStreamFunction endl = ::endl;
Utils::BasicSetRepository* RecursiveImportCacheRepository::repository()
{
static Utils::BasicSetRepository recursiveImportCacheRepositoryObject(QStringLiteral(
"Recursive Imports Cache"), nullptr, false);
static auto mutex = QMutex(QMutex::Recursive);
static Utils::BasicSetRepository recursiveImportCacheRepositoryObject(QStringLiteral("Recursive Imports Cache"),
&mutex, nullptr, false);
return &recursiveImportCacheRepositoryObject;
}
......@@ -154,13 +155,11 @@ struct CacheEntry
class PersistentSymbolTablePrivate
{
public:
PersistentSymbolTablePrivate() : m_declarations(QStringLiteral("Persistent Declaration Table"))
{
}
//Maps declaration-ids to declarations
using Repo = ItemRepository<PersistentSymbolTableItem, PersistentSymbolTableRequestItem, true, false>;
QMutex m_mutex = QMutex(QMutex::Recursive);
// mutable as things like findIndex are not const
mutable ItemRepository<PersistentSymbolTableItem, PersistentSymbolTableRequestItem, true, false> m_declarations;
mutable Repo m_declarations{QStringLiteral("Persistent Declaration Table"), &m_mutex};
mutable QHash<IndexedQualifiedIdentifier, CacheEntry<IndexedDeclaration>> m_declarationsCache;
......
......@@ -88,7 +88,8 @@ void TestDUChain::testStringSets()
const unsigned int choiceCount = 40;
const unsigned int itemCount = 120;
BasicSetRepository rep(QStringLiteral("test repository"));
auto mutex = QMutex(QMutex::Recursive);
BasicSetRepository rep(QStringLiteral("test repository"), &mutex);
// qDebug() << "Start repository-layout: \n" << rep.dumpDotGraph();
......
......@@ -38,8 +38,9 @@ const uint maxApplyAliasesRecursion = 100;
namespace KDevelop {
Utils::BasicSetRepository* RecursiveImportRepository::repository()
{
static Utils::BasicSetRepository recursiveImportRepositoryObject(QStringLiteral(
"Recursive Imports"), &KDevelop::globalItemRepositoryRegistry());
static auto mutex = QMutex(QMutex::Recursive);
static Utils::BasicSetRepository recursiveImportRepositoryObject(QStringLiteral("Recursive Imports"), &mutex,
&KDevelop::globalItemRepositoryRegistry());
return &recursiveImportRepositoryObject;
}
......
......@@ -87,8 +87,9 @@ public:
//The object is created in a function, to prevent initialization-order issues
static RepositoryManager<ItemRepository<AbstractTypeData, AbstractTypeDataRequest>, false>& typeRepository()
{
static RepositoryManager<ItemRepository<AbstractTypeData, AbstractTypeDataRequest>, false> repository(QStringLiteral(
"Type Repository"));
static auto mutex = QMutex(QMutex::Recursive);
static RepositoryManager<ItemRepository<AbstractTypeData, AbstractTypeDataRequest>, false> repository(
QStringLiteral("Type Repository"), &mutex);
return repository;
}
......
......@@ -105,13 +105,11 @@ public:
class UsesPrivate
{
public:
UsesPrivate() : m_uses(QStringLiteral("Use Map"))
{
}
//Maps declaration-ids to Uses
using Repo = ItemRepository<UsesItem, UsesRequestItem>;
QMutex m_mutex = QMutex(QMutex::Recursive);
// mutable as things like findIndex are not const
mutable ItemRepository<UsesItem, UsesRequestItem> m_uses;
mutable Repo m_uses{QStringLiteral("Use Map"), &m_mutex};
};
Uses::Uses()
......
......@@ -97,8 +97,8 @@ using FileModificationPairRepository = KDevelop::ItemRepository<FileModification
static FileModificationPairRepository& fileModificationPairRepository()
{
static FileModificationPairRepository rep(QStringLiteral("file modification repository"));
rep.setMutex(&modificationRevisionSetMutex);
static FileModificationPairRepository rep(QStringLiteral("file modification repository"),
&modificationRevisionSetMutex);
return rep;
}
......@@ -119,8 +119,9 @@ void ModificationRevisionSet::clearCache()
struct FileModificationSetRepository
: public Utils::BasicSetRepository
{
FileModificationSetRepository() : Utils::BasicSetRepository(QStringLiteral(
"file modification sets"), &globalItemRepositoryRegistry(), true)
FileModificationSetRepository(QMutex *mutex)
: Utils::BasicSetRepository(QStringLiteral("file modification sets"), mutex,
&globalItemRepositoryRegistry(), true)
{
}
void itemRemovedFromSets(uint index) override;
......@@ -132,7 +133,8 @@ struct FileModificationSetRepositoryRepresenter
{
static FileModificationSetRepository& repository()
{
static FileModificationSetRepository fileModificationSetRepository;
static QMutex mutex(QMutex::Recursive);
static FileModificationSetRepository fileModificationSetRepository(&mutex);
return fileModificationSetRepository;
}
};
......
......@@ -179,7 +179,8 @@ struct KDEVPLATFORMLANGUAGE_EXPORT SetDataRepository
: public SetDataRepositoryBase
{
SetDataRepository(BasicSetRepository* _setRepository, const QString& name,
KDevelop::ItemRepositoryRegistry* registry) : SetDataRepositoryBase(name, registry)
KDevelop::ItemRepositoryRegistry* registry, QMutex* mutex)
: SetDataRepositoryBase(name, mutex, registry)
, setRepository(_setRepository)
{
}
......@@ -271,8 +272,8 @@ class KDEVPLATFORMLANGUAGE_EXPORT BasicSetRepository
public:
///@param name The name must be unique, and is used for loading and storing the data
///@param registry Where the repository should be registered. If you give zero, it won't be registered, and thus won't be saved to disk.
explicit BasicSetRepository(const QString& name,
KDevelop::ItemRepositoryRegistry* registry = & KDevelop::globalItemRepositoryRegistry(),
explicit BasicSetRepository(const QString& name, QMutex* mutex,
KDevelop::ItemRepositoryRegistry* registry = &KDevelop::globalItemRepositoryRegistry(),
bool delayedDeletion = delayedDeletionByDefault);
virtual ~BasicSetRepository();
using Index = unsigned int;
......
......@@ -941,9 +941,9 @@ Set BasicSetRepository::createSet(const std::set<Index>& indices)
return createSetFromIndices(indicesVector);
}
BasicSetRepository::BasicSetRepository(const QString& name, KDevelop::ItemRepositoryRegistry* registry,
BasicSetRepository::BasicSetRepository(const QString& name, QMutex* mutex, KDevelop::ItemRepositoryRegistry* registry,
bool delayedDeletion)
: m_dataRepository(this, name, registry)
: m_dataRepository(this, name, registry, mutex)
, m_mutex(nullptr)
, m_delayedDeletion(delayedDeletion)
{
......@@ -1173,7 +1173,8 @@ void Set::staticUnref()
unrefNode(m_tree);
}
StringSetRepository::StringSetRepository(const QString& name) : Utils::BasicSetRepository(name)
StringSetRepository::StringSetRepository(const QString& name, QMutex* mutex)
: Utils::BasicSetRepository(name, mutex)
{
}
......
......@@ -532,7 +532,7 @@ private:
struct KDEVPLATFORMLANGUAGE_EXPORT StringSetRepository
: public Utils::BasicSetRepository
{
explicit StringSetRepository(const QString& name);
explicit StringSetRepository(const QString& name, QMutex* mutex);
void itemRemovedFromSets(uint index) override;
void itemAddedToSets(uint index) override;
};
......
......@@ -139,9 +139,8 @@ class IndexedStringRepositoryManager
{
public:
IndexedStringRepositoryManager()
: IndexedStringRepositoryManagerBase(QStringLiteral("String Index"))
: IndexedStringRepositoryManagerBase(QStringLiteral("String Index"), &m_mutex)
{
repository()->setMutex(&m_mutex);
}
private:
......
......@@ -1064,11 +1064,10 @@ public:
///@param registry May be zero, then the repository will not be registered at all. Else, the repository will register itself to that registry.
/// If this is zero, you have to care about storing the data using store() and/or close() by yourself. It does not happen automatically.
/// For the global standard registry, the storing/loading is triggered from within duchain, so you don't need to care about it.
explicit ItemRepository(const QString& repositoryName,
ItemRepositoryRegistry* registry = & globalItemRepositoryRegistry(),
explicit ItemRepository(const QString& repositoryName, QMutex* mutex,
ItemRepositoryRegistry* registry = &globalItemRepositoryRegistry(),
uint repositoryVersion = 1, AbstractRepositoryManager* manager = nullptr)
: m_ownMutex(QMutex::Recursive)
, m_mutex(&m_ownMutex)
: m_mutex(mutex)
, m_repositoryName(repositoryName)
, m_registry(registry)
, m_file(nullptr)
......@@ -1805,12 +1804,6 @@ public:
return m_mutex;
}
///With this, you can replace the internal mutex with another one.
void setMutex(QMutex* mutex)
{
m_mutex = mutex;
}
QString repositoryName() const override
{
return m_repositoryName;
......@@ -2309,7 +2302,6 @@ private:
}
bool m_metaDataChanged;
mutable QMutex m_ownMutex;
mutable QMutex* m_mutex;
QString m_repositoryName;
mutable int m_currentBucket;
......
......@@ -19,14 +19,12 @@ struct RepositoryManager
{
public:
///@param shareMutex Option repository from where this repository should take the thread-safety mutex
explicit RepositoryManager(const QString& name,
int version = 1,
AbstractRepositoryManager*(*shareMutex)() = nullptr,
ItemRepositoryRegistry& registry = globalItemRepositoryRegistry()) :
m_name(name)
explicit RepositoryManager(const QString& name, QMutex* mutex, int version = 1,
ItemRepositoryRegistry& registry = globalItemRepositoryRegistry())
: m_name(name)
, m_version(version)
, m_registry(registry)
, m_shareMutex(shareMutex)
, m_mutex(mutex)
{
if (!lazy) {
createRepository();
......@@ -51,10 +49,7 @@ public:
return repository();
}
QMutex* repositoryMutex() const override
{
return (*this)->mutex();
}
QMutex* repositoryMutex() const override { return m_mutex; }
private:
void createRepository() const
......@@ -62,11 +57,8 @@ private:
if (!m_repository) {
QMutexLocker lock(&m_registry.mutex());
if (!m_repository) {
m_repository =
new ItemRepositoryType(m_name, &m_registry, m_version, const_cast<RepositoryManager*>(this));
if (m_shareMutex) {
(*this)->setMutex(m_shareMutex()->repositoryMutex());
}
m_repository = new ItemRepositoryType(m_name, m_mutex, &m_registry, m_version,
const_cast<RepositoryManager*>(this));
(*this)->setUnloadingEnabled(unloadingEnabled);
}
}
......@@ -75,7 +67,7 @@ private:
QString m_name;
int m_version;
ItemRepositoryRegistry& m_registry;
AbstractRepositoryManager* (* m_shareMutex)();
QMutex* m_mutex;
};
}
......
......@@ -123,7 +123,8 @@ static QVector<uint> insertData(const QVector<QString>& data, TestDataRepository
void BenchItemRepository::insert()
{
TestDataRepository repo("TestDataRepositoryInsert");
auto mutex = QMutex(QMutex::Recursive);
TestDataRepository repo("TestDataRepositoryInsert", &mutex);
const QVector<QString> data = generateData();
QVector<uint> indices;
QBENCHMARK_ONCE {
......@@ -136,7 +137,8 @@ void BenchItemRepository::insert()
void BenchItemRepository::remove()
{
TestDataRepository repo("TestDataRepositoryRemove");
auto mutex = QMutex(QMutex::Recursive);
TestDataRepository repo("TestDataRepositoryRemove", &mutex);
const QVector<QString> data = generateData();
const QVector<uint> indices = insertData(data, repo);
repo.store();
......@@ -160,12 +162,13 @@ void BenchItemRepository::removeDisk()
{
const QVector<QString> data = generateData();
QVector<uint> indices;
auto mutex = QMutex(QMutex::Recursive);
{
TestDataRepository repo("TestDataRepositoryRemoveDisk");
TestDataRepository repo("TestDataRepositoryRemoveDisk", &mutex);
indices = insertData(data, repo);
repo.store();
}
TestDataRepository repo("TestDataRepositoryRemoveDisk");
TestDataRepository repo("TestDataRepositoryRemoveDisk", &mutex);
QVERIFY(repo.statistics().totalItems == static_cast<uint>(data.size()));
QBENCHMARK_ONCE {
for (uint index : qAsConst(indices)) {
......@@ -179,7 +182,8 @@ void BenchItemRepository::removeDisk()
void BenchItemRepository::lookupKey()
{
TestDataRepository repo("TestDataRepositoryLookupKey");
auto mutex = QMutex(QMutex::Recursive);
TestDataRepository repo("TestDataRepositoryLookupKey", &mutex);
const QVector<QString> data = generateData();
QVector<uint> indices = insertData(data, repo);
std::shuffle(indices.begin(), indices.end(), std::default_random_engine(0));
......@@ -192,7 +196,8 @@ void BenchItemRepository::lookupKey()
void BenchItemRepository::lookupValue()
{
TestDataRepository repo("TestDataRepositoryLookupValue");
auto mutex = QMutex(QMutex::Recursive);
TestDataRepository repo("TestDataRepositoryLookupValue", &mutex);
const QVector<QString> data = generateData();
QVector<uint> indices = insertData(data, repo);
std::shuffle(indices.begin(), indices.end(), std::default_random_engine(0));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment