Commit c809e5f5 authored by Milian Wolff's avatar Milian Wolff
Browse files

Move locking fully out of ItemRepository

Instead, add lock/unlock API that operates on the internal
mutex and use that from the ItemRepositoryRegistry where we are
calling the AbstractItemRepository API which used to lock internally.
parent b043083f
......@@ -33,6 +33,11 @@ public:
virtual int finalCleanup() = 0;
virtual QString repositoryName() const = 0;
virtual QString printStatistics() const = 0;
/// lock the repository
virtual void lock() = 0;
/// unlock the repository
virtual void unlock() = 0;
};
/// Internal helper class that wraps around a repository object and manages its lifetime.
......
......@@ -1017,8 +1017,6 @@ private:
* to re-lock anything internally, thus is capable to work with a non-recursive mutex.
* If desired, a recursive mutex can be used too though as needed.
*
* Note that the mutex will be locked internally when the repo is accessed through the AbstractItemRepository API.
*
* @tparam Item See ExampleItem
* @tparam ItemRequest See ExampleReqestItem
* @tparam fixedItemSize When this is true, all inserted items must have the same size.
......@@ -1028,7 +1026,7 @@ private:
* repository that does on-disk reference counting, like IndexedString,
* IndexedIdentifier, etc.
* @tparam mutex The mutex type to use internally. It has to be locked externally before accessing the item repository
* from multiple threads. Except for the store
* from multiple threads.
*/
template <class Item, class ItemRequest, bool markForReferenceCounting = true, typename Mutex = QMutex,
......@@ -1566,8 +1564,6 @@ public:
QString printStatistics() const final
{
// lock for usage from ItemRepositoryRegistry, will be cleaned up in follow up patch
QMutexLocker lock(m_mutex);
return statistics().print();
}
......@@ -1705,12 +1701,14 @@ public:
Mutex* mutex() const { return m_mutex; }
void lock() final { m_mutex->lock(); }
void unlock() final { m_mutex->unlock(); }
private:
///Synchronizes the state on disk to the one in memory, and does some memory-management.
///Should be called on a regular basis. Can be called centrally from the global item repository registry.
void store() final
{
QMutexLocker lock(m_mutex);
if (m_file) {
if (!m_file->open(QFile::ReadWrite) || !m_dynamicFile->open(QFile::ReadWrite)) {
qFatal("cannot re-open repository file for storing");
......@@ -1767,8 +1765,7 @@ private:
bool open(const QString& path) final
{
QMutexLocker lock(m_mutex);
closeLocked();
close();
// qDebug() << "opening repository" << m_repositoryName << "at" << path;
QDir dir(path);
m_file = new QFile(dir.absoluteFilePath(m_repositoryName));
......@@ -1884,13 +1881,6 @@ private:
///@warning by default, this does not store the current state to disk.
void close(bool doStore = false) final
{
QMutexLocker lock(m_mutex);
closeLocked(doStore);
}
///@warning by default, this does not store the current state to disk.
void closeLocked(bool doStore = false)
{
if (doStore)
store();
......@@ -1915,7 +1905,6 @@ private:
int finalCleanup() final
{
QMutexLocker lock(m_mutex);
int changed = 0;
for (int a = 1; a <= m_currentBucket; ++a) {
MyBucket* bucket = bucketForIndex(a);
......
......@@ -21,6 +21,8 @@
#include "abstractitemrepository.h"
#include "debug.h"
#include <mutex>
using namespace KDevelop;
namespace {
......@@ -204,6 +206,7 @@ void ItemRepositoryRegistry::registerRepository(AbstractItemRepository* reposito
QMutexLocker lock(&d->m_mutex);
d->m_repositories.insert(repository, manager);
if (!d->m_path.isEmpty()) {
std::scoped_lock repoLock(*repository);
if (!repository->open(d->m_path)) {
d->deleteDataDirectory(d->m_path);
qCritical() << "failed to open a repository";
......@@ -257,7 +260,10 @@ void ItemRepositoryRegistry::unRegisterRepository(AbstractItemRepository* reposi
QMutexLocker lock(&d->m_mutex);
Q_ASSERT(d->m_repositories.contains(repository));
repository->close();
{
std::scoped_lock repoLock(*repository);
repository->close();
}
d->m_repositories.remove(repository);
}
......@@ -295,7 +301,9 @@ bool ItemRepositoryRegistryPrivate::open(const QString& path)
QDir().mkpath(path);
for (auto it = m_repositories.constBegin(), end = m_repositories.constEnd(); it != end; ++it) {
if (!it.key()->open(path)) {
auto* const repository = it.key();
std::scoped_lock repoLock(*repository);
if (!repository->open(path)) {
deleteDataDirectory(path);
qCritical() << "failed to open a repository";
abort();
......@@ -327,7 +335,9 @@ void ItemRepositoryRegistry::store()
QMutexLocker lock(&d->m_mutex);
for (auto it = d->m_repositories.constBegin(), end = d->m_repositories.constEnd(); it != end; ++it) {
it.key()->store();
auto* const repository = it.key();
std::scoped_lock repoLock(*repository);
repository->store();
}
QFile versionFile(d->m_path + QStringLiteral("/version_%1").arg(staticItemRepositoryVersion()));
......@@ -360,6 +370,7 @@ void ItemRepositoryRegistry::printAllStatistics() const
QMutexLocker lock(&d->m_mutex);
for (auto it = d->m_repositories.constBegin(), end = d->m_repositories.constEnd(); it != end; ++it) {
AbstractItemRepository* repository = it.key();
std::scoped_lock repoLock(*repository);
qCDebug(SERIALIZATION) << "statistics in" << repository->repositoryName() << ":";
qCDebug(SERIALIZATION) << repository->printStatistics();
}
......@@ -373,6 +384,7 @@ int ItemRepositoryRegistry::finalCleanup()
int changed = false;
for (auto it = d->m_repositories.constBegin(), end = d->m_repositories.constEnd(); it != end; ++it) {
AbstractItemRepository* repository = it.key();
std::scoped_lock repoLock(*repository);
int added = repository->finalCleanup();
changed += added;
qCDebug(SERIALIZATION) << "cleaned in" << repository->repositoryName() << ":" << added;
......@@ -386,7 +398,9 @@ void ItemRepositoryRegistryPrivate::close()
QMutexLocker lock(&m_mutex);
for (auto it = m_repositories.constBegin(), end = m_repositories.constEnd(); it != end; ++it) {
it.key()->close();
auto* const repository = it.key();
std::scoped_lock repoLock(*repository);
repository->close();
}
m_path.clear();
......
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