File indexing completed on 2024-11-24 04:44:35

0001 /*  This file is part of the KDE project
0002     SPDX-FileCopyrightText: 2009 Kevin Krammer <kevin.krammer@gmx.at>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "sessionimpls_p.h"
0008 
0009 #include "collectioncreatejob.h"
0010 #include "collectiondeletejob.h"
0011 #include "collectionfetchjob.h"
0012 #include "collectionmodifyjob.h"
0013 #include "collectionmovejob.h"
0014 #include "itemcreatejob.h"
0015 #include "itemdeletejob.h"
0016 #include "itemfetchjob.h"
0017 #include "itemmodifyjob.h"
0018 #include "itemmovejob.h"
0019 #include "storecompactjob.h"
0020 
0021 #include <QQueue>
0022 #include <QTimer>
0023 
0024 using namespace Akonadi;
0025 
0026 class AbstractEnqueueVisitor : public FileStore::Job::Visitor
0027 {
0028 public:
0029     bool visit(FileStore::Job *job) override
0030     {
0031         enqueue(job, "Job");
0032         return true;
0033     }
0034 
0035     bool visit(FileStore::CollectionCreateJob *job) override
0036     {
0037         enqueue(job, "CollectionCreateJob");
0038         return true;
0039     }
0040 
0041     bool visit(FileStore::CollectionDeleteJob *job) override
0042     {
0043         enqueue(job, "CollectionDeleteJob");
0044         return true;
0045     }
0046 
0047     bool visit(FileStore::CollectionFetchJob *job) override
0048     {
0049         enqueue(job, "CollectionFetchJob");
0050         return true;
0051     }
0052 
0053     bool visit(FileStore::CollectionModifyJob *job) override
0054     {
0055         enqueue(job, "CollectionModifyJob");
0056         return true;
0057     }
0058 
0059     bool visit(FileStore::CollectionMoveJob *job) override
0060     {
0061         enqueue(job, "CollectionMoveJob");
0062         return true;
0063     }
0064 
0065     bool visit(FileStore::ItemCreateJob *job) override
0066     {
0067         enqueue(job, "ItemCreateJob");
0068         return true;
0069     }
0070 
0071     bool visit(FileStore::ItemDeleteJob *job) override
0072     {
0073         enqueue(job, "ItemDeleteJob");
0074         return true;
0075     }
0076 
0077     bool visit(FileStore::ItemFetchJob *job) override
0078     {
0079         enqueue(job, "ItemFetchJob");
0080         return true;
0081     }
0082 
0083     bool visit(FileStore::ItemModifyJob *job) override
0084     {
0085         enqueue(job, "ItemModifyJob");
0086         return true;
0087     }
0088 
0089     bool visit(FileStore::ItemMoveJob *job) override
0090     {
0091         enqueue(job, "ItemMoveJob");
0092         return true;
0093     }
0094 
0095     bool visit(FileStore::StoreCompactJob *job) override
0096     {
0097         enqueue(job, "StoreCompactJob");
0098         return true;
0099     }
0100 
0101 protected:
0102     virtual void enqueue(FileStore::Job *job, const char *className) = 0;
0103 };
0104 
0105 class FileStore::FiFoQueueJobSessionPrivate : public AbstractEnqueueVisitor
0106 {
0107 public:
0108     explicit FiFoQueueJobSessionPrivate(FileStore::FiFoQueueJobSession *parent)
0109         : mParent(parent)
0110     {
0111         QObject::connect(&mJobRunTimer, &QTimer::timeout, mParent, [this]() {
0112             runNextJob();
0113         });
0114     }
0115 
0116     void runNextJob()
0117     {
0118         /*      qDebug() << "Queue with" << mJobQueue.count() << "entries";*/
0119         if (mJobQueue.isEmpty()) {
0120             mJobRunTimer.stop();
0121             return;
0122         }
0123 
0124         FileStore::Job *job = mJobQueue.dequeue();
0125         while (job != nullptr && job->error() != 0) {
0126             /*        qDebug() << "Dequeued job" << job << "has error ("
0127                              << job->error() << "," << job->errorText() << ")";*/
0128             mParent->emitResult(job);
0129             if (!mJobQueue.isEmpty()) {
0130                 job = mJobQueue.dequeue();
0131             } else {
0132                 job = nullptr;
0133             }
0134         }
0135 
0136         if (job != nullptr) {
0137             /*        qDebug() << "Dequeued job" << job << "is ready";*/
0138             QList<FileStore::Job *> jobs;
0139             jobs << job;
0140 
0141             Q_EMIT mParent->jobsReady(jobs);
0142         } else {
0143             /*        qDebug() << "Queue now empty";*/
0144             mJobRunTimer.stop();
0145         }
0146     }
0147 
0148 public:
0149     QQueue<FileStore::Job *> mJobQueue;
0150 
0151     QTimer mJobRunTimer;
0152 
0153 protected:
0154     void enqueue(FileStore::Job *job, const char *className) override
0155     {
0156         Q_UNUSED(className)
0157         mJobQueue.enqueue(job);
0158 
0159         //       qDebug() << "adding" << className << ". Queue now with"
0160         //                << mJobQueue.count() << "entries";
0161 
0162         mJobRunTimer.start(0);
0163     }
0164 
0165 private:
0166     FileStore::FiFoQueueJobSession *mParent = nullptr;
0167 };
0168 
0169 FileStore::FiFoQueueJobSession::FiFoQueueJobSession(QObject *parent)
0170     : FileStore::AbstractJobSession(parent)
0171     , d(new FiFoQueueJobSessionPrivate(this))
0172 {
0173 }
0174 
0175 FileStore::FiFoQueueJobSession::~FiFoQueueJobSession()
0176 {
0177     cancelAllJobs();
0178 }
0179 
0180 void FileStore::FiFoQueueJobSession::addJob(FileStore::Job *job)
0181 {
0182     job->accept(d.get());
0183 }
0184 
0185 void FileStore::FiFoQueueJobSession::cancelAllJobs()
0186 {
0187     // KJob::kill() also deletes the job
0188     for (FileStore::Job *job : std::as_const(d->mJobQueue)) {
0189         job->kill(KJob::EmitResult);
0190     }
0191 
0192     d->mJobQueue.clear();
0193 }
0194 
0195 void FileStore::FiFoQueueJobSession::removeJob(FileStore::Job *job)
0196 {
0197     d->mJobQueue.removeAll(job);
0198 }
0199 
0200 #include "moc_sessionimpls_p.cpp"