File indexing completed on 2024-06-09 05:18:09
0001 /* 0002 * SPDX-FileCopyrightText: 2004 David Faure <faure@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "mailcommon_export.h" 0010 0011 #include <QObject> 0012 0013 #include <QList> 0014 #include <QTimer> 0015 0016 #include "folderjob.h" 0017 #include <Akonadi/Collection> 0018 // If this define is set, JobScheduler will show debug output, and related kmkernel 0019 // timers will be shortened. 0020 // This is for debugging purposes only, don't commit with it. 0021 //#define DEBUG_SCHEDULER 0022 0023 namespace MailCommon 0024 { 0025 class FolderJob; 0026 class ScheduledJob; 0027 0028 /** 0029 * A scheduled task is some information about a folder job that should be run later. 0030 * As long as it's not running, it's called a "task", i.e. something that needs to be done. 0031 * Tasks are managed by the JobScheduler. 0032 */ 0033 class MAILCOMMON_EXPORT ScheduledTask 0034 { 0035 public: 0036 /** 0037 * Creates a scheduled task for a given folder. 0038 * If @p immediate is true, the scheduler will run this task as soon 0039 * as possible (but won't interrupt a currently running job for it). 0040 */ 0041 ScheduledTask(const Akonadi::Collection &folder, bool immediate); 0042 virtual ~ScheduledTask(); 0043 0044 /** 0045 * Run this task, i.e. create a job for it. 0046 * Important: the job's execute() method must either call open() on the folder 0047 * or storage immediately, or abort (deleting itself). 0048 * Usually, that job should also be cancellable. 0049 * Otherwise (if the open() is delayed) an unrelated open() could happen first 0050 * and mess things up. 0051 * If for some reason (e.g. a folder is deleted) nothing should be done, return 0. 0052 */ 0053 virtual ScheduledJob *run() = 0; 0054 0055 /** 0056 * An identifier for the type of task (a bit like QListViewItem::rtti). 0057 * This allows to automatically prevent two identical tasks from being scheduled 0058 * for the same folder. To circumvent this feature and make every task unique, 0059 * return 0 here. 0060 */ 0061 virtual int taskTypeId() const = 0; 0062 0063 /** 0064 * The folder which this task is supposed to handle, 0 if it was deleted meanwhile. 0065 */ 0066 [[nodiscard]] Akonadi::Collection folder() const; 0067 0068 [[nodiscard]] bool isImmediate() const; 0069 0070 private: 0071 const Akonadi::Collection mCurrentFolder; 0072 const bool mImmediate; 0073 }; 0074 0075 /** 0076 * The unique JobScheduler instance (owned by kmkernel) implements "background processing" 0077 * of folder operations (like expiration and compaction). Tasks (things to be done) 0078 * are registered with the JobScheduler, and it will execute them one at a time, 0079 * separated by a 1-minute timer. The jobs themselves should use timers to avoid 0080 * using too much CPU for too long. Tasks for opened folders are not executed until 0081 * the folder is closed. 0082 */ 0083 class MAILCOMMON_EXPORT JobScheduler : public QObject 0084 { 0085 Q_OBJECT 0086 public: 0087 explicit JobScheduler(QObject *parent); 0088 ~JobScheduler() override; 0089 0090 /** 0091 * Register a task to be done for a given folder. The ownership of the task is transferred 0092 * to the JobScheduler. 0093 */ 0094 void registerTask(ScheduledTask *task); 0095 0096 // D-Bus calls, called from KMKernel 0097 void pause(); 0098 void resume(); 0099 0100 private: 0101 // Called by a timer to run the next job 0102 MAILCOMMON_NO_EXPORT void slotRunNextJob(); 0103 0104 // Called when the current job terminates 0105 MAILCOMMON_NO_EXPORT void slotJobFinished(); 0106 MAILCOMMON_NO_EXPORT void restartTimer(); 0107 MAILCOMMON_NO_EXPORT void interruptCurrentTask(); 0108 MAILCOMMON_NO_EXPORT void runTaskNow(ScheduledTask *task); 0109 using TaskList = QList<ScheduledTask *>; 0110 MAILCOMMON_NO_EXPORT void removeTask(TaskList::Iterator &it); 0111 0112 private: 0113 TaskList mTaskList; // FIFO of tasks to be run 0114 0115 QTimer mTimer; 0116 int mPendingImmediateTasks = 0; 0117 0118 /// Information about the currently running job, if any 0119 ScheduledTask *mCurrentTask = nullptr; 0120 ScheduledJob *mCurrentJob = nullptr; 0121 }; 0122 0123 /** 0124 * Base class for scheduled jobs. 0125 */ 0126 class MAILCOMMON_EXPORT ScheduledJob : public FolderJob 0127 { 0128 public: 0129 ScheduledJob(const Akonadi::Collection &folder, bool immediate); 0130 ~ScheduledJob() override; 0131 0132 protected: 0133 bool mImmediate; 0134 }; 0135 }