Commit 88f96002 authored by Daniel Vrátil's avatar Daniel Vrátil 🤖
Browse files

Use unique_ptr in AkonadiServer class

and few other small improvements around.
parent e589d4b7
......@@ -103,15 +103,6 @@ FakeAkonadiServer *FakeAkonadiServer::instance()
FakeAkonadiServer::FakeAkonadiServer()
: AkonadiServer()
, mDataStore(nullptr)
, mSearchManager(nullptr)
, mConnection(nullptr)
, mClient(nullptr)
, mRetrievalManager(nullptr)
, mServerLoop(nullptr)
, mNtfCollector(nullptr)
, mPopulateDb(true)
, mDisableItemRetrievalManager(false)
{
qputenv("AKONADI_INSTANCE", qPrintable(instanceName()));
qputenv("XDG_DATA_HOME", qPrintable(QString(basePath() + QLatin1String("/local"))));
......@@ -119,18 +110,12 @@ FakeAkonadiServer::FakeAkonadiServer()
qputenv("HOME", qPrintable(basePath()));
qputenv("KDEHOME", qPrintable(basePath() + QLatin1String("/kdehome")));
mClient = new FakeClient;
mClient = std::make_unique<FakeClient>();
FakeDataStore::registerFactory();
}
FakeAkonadiServer::~FakeAkonadiServer()
{
delete mClient;
delete mConnection;
delete mRetrievalManager;
delete mNtfCollector;
}
FakeAkonadiServer::~FakeAkonadiServer() = default;
QString FakeAkonadiServer::basePath()
{
......@@ -245,13 +230,13 @@ void FakeAkonadiServer::initFake()
PreprocessorManager::init();
PreprocessorManager::instance()->setEnabled(false);
mSearchManager = new FakeSearchManager();
mSearchManager = std::make_unique<FakeSearchManager>();
if (!mDisableItemRetrievalManager) {
mRetrievalManager = new FakeItemRetrievalManager();
mRetrievalManager = std::make_unique<FakeItemRetrievalManager>();
}
mIntervalCheck = new FakeIntervalCheck();
mIntervalCheck = std::make_unique<FakeIntervalCheck>();
qDebug() << "==== Fake Akonadi Server started ====";
}
......@@ -279,7 +264,7 @@ bool FakeAkonadiServer::quit()
mDataStore->close();
}
delete mIntervalCheck;
mIntervalCheck.reset();
qDebug() << "==== Fake Akonadi Server shut down ====";
return true;
......@@ -292,12 +277,12 @@ void FakeAkonadiServer::setScenarios(const TestScenario::List &scenarios)
void FakeAkonadiServer::newCmdConnection(quintptr socketDescriptor)
{
mConnection = new FakeConnection(socketDescriptor);
mConnection = std::make_unique<FakeConnection>(socketDescriptor);
// Connection is its own thread, so we have to make sure we get collector
// from DataStore of the Connection's thread, not ours
NotificationCollector *collector = nullptr;
QMetaObject::invokeMethod(mConnection, "notificationCollector", Qt::BlockingQueuedConnection,
QMetaObject::invokeMethod(mConnection.get(), "notificationCollector", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(Akonadi::Server::NotificationCollector*, collector));
mNtfCollector = dynamic_cast<InspectableNotificationCollector*>(collector);
Q_ASSERT(mNtfCollector);
......@@ -307,23 +292,20 @@ void FakeAkonadiServer::newCmdConnection(quintptr socketDescriptor)
void FakeAkonadiServer::runTest()
{
mCmdServer = new AkLocalServer(this);
connect(mCmdServer, static_cast<void(AkLocalServer::*)(quintptr)>(&AkLocalServer::newConnection),
mCmdServer = std::make_unique<AkLocalServer>();
connect(mCmdServer.get(), static_cast<void(AkLocalServer::*)(quintptr)>(&AkLocalServer::newConnection),
this, &FakeAkonadiServer::newCmdConnection);
QVERIFY(mCmdServer->listen(socketFile()));
mServerLoop = new QEventLoop(this);
connect(mClient, &QThread::finished, mServerLoop, &QEventLoop::quit);
QEventLoop serverLoop;
connect(mClient.get(), &QThread::finished, &serverLoop, &QEventLoop::quit);
// Start the client: the client will connect to the server and will
// start playing the scenario
mClient->start();
// Wait until the client disconnects, i.e. until the scenario is completed.
mServerLoop->exec();
mServerLoop->deleteLater();
mServerLoop = nullptr;
serverLoop.exec();
mCmdServer->close();
......
......@@ -26,6 +26,7 @@
#include <QSharedPointer>
#include <type_traits>
#include <memory>
#include <private/protocol_p.h>
......@@ -117,18 +118,17 @@ private:
void initFake();
FakeDataStore *mDataStore = nullptr;
FakeSearchManager *mSearchManager = nullptr;
FakeConnection *mConnection = nullptr;
FakeClient *mClient = nullptr;
FakeItemRetrievalManager *mRetrievalManager = nullptr;
std::unique_ptr<FakeSearchManager> mSearchManager;
std::unique_ptr<FakeConnection> mConnection;
std::unique_ptr<FakeClient> mClient;
std::unique_ptr<FakeItemRetrievalManager> mRetrievalManager;
QEventLoop *mServerLoop = nullptr;
InspectableNotificationCollector *mNtfCollector = nullptr;
QSharedPointer<QSignalSpy> mNotificationSpy;
bool mPopulateDb;
bool mDisableItemRetrievalManager;
bool mPopulateDb = true;
bool mDisableItemRetrievalManager = false;
static FakeAkonadiServer *sInstance;
};
......
......@@ -40,6 +40,7 @@
#include "search/searchtaskmanager.h"
#include "aklocalserver.h"
#include <memory>
#include <private/standarddirs_p.h>
#include <private/protocol_p.h>
#include <private/dbus_p.h>
......@@ -102,14 +103,15 @@ bool AkonadiServer::init()
const QString connectionSettingsFile = StandardDirs::connectionConfigFile(StandardDirs::WriteOnly);
QSettings connectionSettings(connectionSettingsFile, QSettings::IniFormat);
mCmdServer = new AkLocalServer(this);
connect(mCmdServer, QOverload<quintptr>::of(&AkLocalServer::newConnection), this, &AkonadiServer::newCmdConnection);
mCmdServer = std::make_unique<AkLocalServer>(this);
connect(mCmdServer.get(), QOverload<quintptr>::of(&AkLocalServer::newConnection), this, &AkonadiServer::newCmdConnection);
mNotificationManager = new NotificationManager();
mNtfServer = new AkLocalServer(this);
mNotificationManager = std::make_unique<NotificationManager>();
mNtfServer = std::make_unique<AkLocalServer>(this);
// Note: this is a queued connection, as NotificationManager lives in its
// own thread
connect(mNtfServer, QOverload<quintptr>::of(&AkLocalServer::newConnection), mNotificationManager, &NotificationManager::registerConnection);
connect(mNtfServer.get(), QOverload<quintptr>::of(&AkLocalServer::newConnection),
mNotificationManager.get(), &NotificationManager::registerConnection);
// TODO: share socket setup with client
#ifdef Q_OS_WIN
......@@ -194,17 +196,17 @@ bool AkonadiServer::init()
}
if (settings.value(QStringLiteral("Cache/EnableCleaner"), true).toBool()) {
mCacheCleaner = new CacheCleaner();
mCacheCleaner = std::make_unique<CacheCleaner>();
}
mIntervalCheck = new IntervalCheck();
mStorageJanitor = new StorageJanitor();
mItemRetrieval = new ItemRetrievalManager();
mAgentSearchManager = new SearchTaskManager();
mIntervalCheck = std::make_unique<IntervalCheck>();
mStorageJanitor = std::make_unique<StorageJanitor>();
mItemRetrieval = std::make_unique<ItemRetrievalManager>();
mAgentSearchManager = std::make_unique<SearchTaskManager>();
const QStringList searchManagers = settings.value(QStringLiteral("Search/Manager"),
QStringList() << QStringLiteral("Agent")).toStringList();
mSearchManager = new SearchManager(searchManagers);
mSearchManager = std::make_unique<SearchManager>(searchManagers);
new ServerAdaptor(this);
QDBusConnection::sessionBus().registerObject(QStringLiteral("/Server"), this);
......@@ -241,19 +243,7 @@ bool AkonadiServer::init()
return true;
}
AkonadiServer::~AkonadiServer()
{
}
template <typename T> static void quitThread(T &thread)
{
if (thread) {
thread->quit();
thread->wait();
delete thread;
thread = nullptr;
}
}
AkonadiServer::~AkonadiServer() = default;
bool AkonadiServer::quit()
{
......@@ -263,17 +253,16 @@ bool AkonadiServer::quit()
mAlreadyShutdown = true;
qCDebug(AKONADISERVER_LOG) << "terminating connection threads";
qDeleteAll(mConnections);
mConnections.clear();
qCDebug(AKONADISERVER_LOG) << "terminating service threads";
delete mCacheCleaner;
delete mIntervalCheck;
delete mStorageJanitor;
delete mItemRetrieval;
delete mAgentSearchManager;
delete mSearchManager;
delete mNotificationManager;
mCacheCleaner.reset();
mIntervalCheck.reset();
mStorageJanitor.reset();
mItemRetrieval.reset();
mAgentSearchManager.reset();
mSearchManager.reset();
mNotificationManager.reset();
// Terminate the preprocessor manager before the database but after all connections are gone
PreprocessorManager::done();
......@@ -310,17 +299,18 @@ void AkonadiServer::newCmdConnection(quintptr socketDescriptor)
return;
}
Connection *connection = new Connection(socketDescriptor);
connect(connection, &Connection::disconnected,
auto connection = std::make_unique<Connection>(socketDescriptor);
connect(connection.get(), &Connection::disconnected,
this, &AkonadiServer::connectionDisconnected);
mConnections.append(connection);
mConnections.push_back(std::move(connection));
}
void AkonadiServer::connectionDisconnected()
{
auto conn = qobject_cast<Connection *>(sender());
mConnections.removeOne(conn);
delete conn;
auto it = std::find_if(mConnections.begin(), mConnections.end(),
[this](const auto &ptr) { return ptr.get() == sender(); });
Q_ASSERT(it != mConnections.end());
mConnections.erase(it);
}
AkonadiServer *AkonadiServer::instance()
......@@ -398,17 +388,17 @@ void AkonadiServer::stopDatabaseProcess()
CacheCleaner *AkonadiServer::cacheCleaner()
{
return mCacheCleaner;
return mCacheCleaner.get();
}
IntervalCheck *AkonadiServer::intervalChecker()
{
return mIntervalCheck;
return mIntervalCheck.get();
}
NotificationManager *AkonadiServer::notificationManager()
{
return mNotificationManager;
return mNotificationManager.get();
}
QString AkonadiServer::serverPath() const
......
......@@ -97,18 +97,18 @@ protected:
std::unique_ptr<QDBusServiceWatcher> mControlWatcher;
AkLocalServer *mCmdServer = nullptr;
AkLocalServer *mNtfServer = nullptr;
NotificationManager *mNotificationManager = nullptr;
CacheCleaner *mCacheCleaner = nullptr;
IntervalCheck *mIntervalCheck = nullptr;
StorageJanitor *mStorageJanitor = nullptr;
ItemRetrievalManager *mItemRetrieval = nullptr;
SearchTaskManager *mAgentSearchManager = nullptr;
QProcess *mDatabaseProcess = nullptr;
QVector<Connection *> mConnections;
SearchManager *mSearchManager = nullptr;
std::unique_ptr<AkLocalServer> mCmdServer;
std::unique_ptr<AkLocalServer> mNtfServer;
std::unique_ptr<NotificationManager> mNotificationManager;
std::unique_ptr<CacheCleaner> mCacheCleaner;
std::unique_ptr<IntervalCheck> mIntervalCheck;
std::unique_ptr<StorageJanitor> mStorageJanitor;
std::unique_ptr<ItemRetrievalManager> mItemRetrieval;
std::unique_ptr<SearchTaskManager> mAgentSearchManager;
std::unique_ptr<SearchManager> mSearchManager;
std::vector<std::unique_ptr<Connection>> mConnections;
bool mAlreadyShutdown = false;
static AkonadiServer *s_instance;
......
......@@ -46,9 +46,7 @@ AkThread::AkThread(const QString &objectName, QThread::Priority priority, QObjec
{
}
AkThread::~AkThread()
{
}
AkThread::~AkThread() = default;
void AkThread::startThread()
{
......@@ -60,8 +58,9 @@ void AkThread::startThread()
void AkThread::quitThread()
{
if (m_startMode == NoThread)
if (m_startMode == NoThread) {
return;
}
qCDebug(AKONADISERVER_LOG) << "Shutting down" << objectName() << "...";
const bool invoke = QMetaObject::invokeMethod(this, &AkThread::quit, Qt::QueuedConnection);
......
......@@ -54,7 +54,7 @@ protected Q_SLOTS:
virtual void quit();
private:
StartMode m_startMode;
StartMode m_startMode = AutoStart;
};
}
......
......@@ -25,11 +25,6 @@
using namespace Akonadi;
using namespace Akonadi::Server;
CommandContext::CommandContext()
: mTagId(-1)
{
}
void CommandContext::setResource(const Resource &resource)
{
mResource = resource;
......@@ -88,21 +83,18 @@ void CommandContext::setTag(qint64 tagId)
mTagId = tagId;
}
qint64 CommandContext::tagId() const
akOptional<qint64> CommandContext::tagId() const
{
return mTagId;
}
Tag CommandContext::tag() const
{
if (mTagId == -1) {
return Tag();
}
return Tag::retrieveById(mTagId);
return mTagId.has_value() ? Tag::retrieveById(mTagId.value()) : Tag();
}
bool CommandContext::isEmpty() const
{
return !mCollection.isValid() && mTagId < 0;
return !mCollection.isValid() && !mTagId.has_value();
}
......@@ -22,6 +22,8 @@
#include "entities.h"
#include <shared/akoptional.h>
namespace Akonadi
{
......@@ -36,7 +38,7 @@ namespace Server
class CommandContext
{
public:
CommandContext();
CommandContext() = default;
void setResource(const Resource &resource);
Resource resource() const;
......@@ -48,7 +50,7 @@ public:
Collection collection() const;
void setTag(qint64 tagId);
qint64 tagId() const;
akOptional<qint64> tagId() const;
Tag tag() const;
bool isEmpty() const;
......@@ -56,7 +58,7 @@ public:
private:
Resource mResource;
Collection mCollection;
qint64 mTagId;
akOptional<qint64> mTagId;
};
}
......
......@@ -61,6 +61,7 @@ class SearchTaskManager : public AkThread
Q_OBJECT
public:
explicit SearchTaskManager();
static SearchTaskManager *instance();
~SearchTaskManager();
......@@ -91,7 +92,6 @@ private:
static SearchTaskManager *sInstance;
explicit SearchTaskManager();
bool mShouldStop;
TasksMap::Iterator cancelRunningTask(TasksMap::Iterator &iter);
......@@ -107,8 +107,6 @@ private:
QMap<QString /* resource */, ResourceTask *> mRunningTasks;
QVector<ResourceTask *> mPendingResults;
friend class AkonadiServer;
};
AKONADI_EXCEPTION_MAKE_INSTANCE(SearchException);
......
......@@ -56,7 +56,8 @@ void ItemQueryHelper::itemSetToQuery(const ImapSet &set, CommandContext *context
itemSetToQuery(set, qb);
}
if (context->tagId() >= 0) {
const auto tagId = context->tagId();
if (tagId.has_value()) {
//When querying for items by tag, only return matches from that resource
if (context->resource().isValid()) {
qb.addJoin(QueryBuilder::InnerJoin, Collection::tableName(),
......@@ -65,7 +66,7 @@ void ItemQueryHelper::itemSetToQuery(const ImapSet &set, CommandContext *context
}
qb.addJoin(QueryBuilder::InnerJoin, PimItemTagRelation::tableName(),
PimItem::idFullColumnName(), PimItemTagRelation::leftFullColumnName());
qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, context->tagId());
qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, tagId.value());
}
}
......@@ -85,10 +86,12 @@ void ItemQueryHelper::remoteIdToQuery(const QStringList &rids, CommandContext *c
if (context->collectionId() > 0) {
qb.addValueCondition(PimItem::collectionIdFullColumnName(), Query::Equals, context->collectionId());
}
if (context->tagId() > 0) {
const auto tagId = context->tagId();
if (tagId.has_value()) {
qb.addJoin(QueryBuilder::InnerJoin, PimItemTagRelation::tableName(),
PimItem::idFullColumnName(), PimItemTagRelation::leftFullColumnName());
qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, context->tagId());
qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, tagId.value());
}
}
......@@ -100,7 +103,8 @@ void ItemQueryHelper::gidToQuery(const QStringList &gids, CommandContext *contex
qb.addValueCondition(PimItem::gidFullColumnName(), Query::In, gids);
}
if (context->tagId() > 0) {
const auto tagId = context->tagId();
if (tagId.has_value()) {
//When querying for items by tag, only return matches from that resource
if (context->resource().isValid()) {
qb.addJoin(QueryBuilder::InnerJoin, Collection::tableName(),
......@@ -109,7 +113,7 @@ void ItemQueryHelper::gidToQuery(const QStringList &gids, CommandContext *contex
}
qb.addJoin(QueryBuilder::InnerJoin, PimItemTagRelation::tableName(),
PimItem::idFullColumnName(), PimItemTagRelation::leftFullColumnName());
qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, context->tagId());
qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, tagId.value());
}
}
......
Markdown is supported
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