File indexing completed on 2025-01-05 04:46:59

0001 /*
0002     SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "akthread.h"
0010 #include "itemretrievalrequest.h"
0011 #include "itemretriever.h"
0012 #include "shared/akstd.h"
0013 
0014 #include <QHash>
0015 class QObject;
0016 #include <QReadWriteLock>
0017 #include <QWaitCondition>
0018 
0019 #include <unordered_map>
0020 
0021 class OrgFreedesktopAkonadiResourceInterface;
0022 
0023 namespace Akonadi
0024 {
0025 namespace Server
0026 {
0027 class Collection;
0028 class ItemRetrievalJob;
0029 class AbstractItemRetrievalJob;
0030 
0031 class AbstractItemRetrievalJobFactory
0032 {
0033 public:
0034     virtual ~AbstractItemRetrievalJobFactory() = default;
0035 
0036     virtual AbstractItemRetrievalJob *retrievalJob(ItemRetrievalRequest request, QObject *parent) = 0;
0037 
0038 protected:
0039     explicit AbstractItemRetrievalJobFactory() = default;
0040 
0041 private:
0042     Q_DISABLE_COPY_MOVE(AbstractItemRetrievalJobFactory)
0043 };
0044 
0045 /** Manages and processes item retrieval requests. */
0046 class ItemRetrievalManager : public AkThread
0047 {
0048     Q_OBJECT
0049 protected:
0050     /**
0051      * Use AkThread::create() to create and start a new ItemRetrievalManager thread.
0052      */
0053     explicit ItemRetrievalManager(QObject *parent = nullptr);
0054     explicit ItemRetrievalManager(std::unique_ptr<AbstractItemRetrievalJobFactory> factory, QObject *parent = nullptr);
0055 
0056 public:
0057     ~ItemRetrievalManager() override;
0058 
0059     /**
0060      * Added for convenience. ItemRetrievalManager takes ownership over the
0061      * pointer and deletes it when the request is processed.
0062      */
0063     virtual void requestItemDelivery(ItemRetrievalRequest request);
0064 
0065     void triggerCollectionSync(const QString &resource, qint64 colId);
0066     void triggerCollectionTreeSync(const QString &resource);
0067 
0068 Q_SIGNALS:
0069     void requestFinished(const Akonadi::Server::ItemRetrievalResult &result);
0070     void requestAdded();
0071 
0072 private:
0073     OrgFreedesktopAkonadiResourceInterface *resourceInterface(const QString &id);
0074     QList<AbstractItemRetrievalJob *> scheduleJobsForIdleResourcesLocked();
0075 
0076 private Q_SLOTS:
0077     void init() override;
0078 
0079     void serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
0080     void processRequest();
0081     void retrievalJobFinished(Akonadi::Server::AbstractItemRetrievalJob *job);
0082 
0083 protected:
0084     std::unique_ptr<AbstractItemRetrievalJobFactory> mJobFactory;
0085 
0086     /// Protects mPendingRequests and every Request object posted to it
0087     QReadWriteLock mLock;
0088     /// Used to let requesting threads wait until the request has been processed
0089     QWaitCondition mWaitCondition;
0090 
0091     /// Pending requests queues, one per resource
0092     std::unordered_map<QString, std::list<ItemRetrievalRequest>> mPendingRequests;
0093     /// Currently running jobs, one per resource
0094     QHash<QString, AbstractItemRetrievalJob *> mCurrentJobs;
0095 
0096     // resource dbus interface cache
0097     std::unordered_map<QString, std::unique_ptr<OrgFreedesktopAkonadiResourceInterface>> mResourceInterfaces;
0098 };
0099 
0100 } // namespace Server
0101 } // namespace Akonadi