File indexing completed on 2024-04-21 03:55:11

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2009, 2010 Andreas Hartmetz <ahartmetz@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 #ifndef SCHEDULER_P_H
0009 #define SCHEDULER_P_H
0010 
0011 #include "kiocore_export.h"
0012 
0013 #include <QSet>
0014 #include <QTimer>
0015 // #define SCHEDULER_DEBUG
0016 
0017 namespace KIO
0018 {
0019 // The worker manager manages the list of idle workers that can be reused
0020 class WorkerManager : public QObject
0021 {
0022     Q_OBJECT
0023 public:
0024     WorkerManager();
0025     ~WorkerManager() override;
0026     void returnWorker(KIO::Worker *worker);
0027     // pick suitable worker for job and return it, return null if no worker found.
0028     // the worker is removed from the manager.
0029     KIO::Worker *takeWorkerForJob(KIO::SimpleJob *job);
0030     // remove worker from manager
0031     bool removeWorker(KIO::Worker *worker);
0032     // remove all workers from manager
0033     void clear();
0034     QList<KIO::Worker *> allWorkers() const;
0035 
0036 private:
0037     void scheduleGrimReaper();
0038 
0039 private Q_SLOTS:
0040     void grimReaper();
0041 
0042 private:
0043     QMultiHash<QString, KIO::Worker *> m_idleWorkers;
0044     QTimer m_grimTimer;
0045 };
0046 
0047 class HostQueue
0048 {
0049 public:
0050     int lowestSerial() const;
0051 
0052     bool isQueueEmpty() const
0053     {
0054         return m_queuedJobs.isEmpty();
0055     }
0056     bool isEmpty() const
0057     {
0058         return m_queuedJobs.isEmpty() && m_runningJobs.isEmpty();
0059     }
0060     int runningJobsCount() const
0061     {
0062         return m_runningJobs.count();
0063     }
0064 #ifdef SCHEDULER_DEBUG
0065     QList<KIO::SimpleJob *> runningJobs() const
0066     {
0067         return QList<KIO::SimpleJob *>(m_runningJobs.cbegin(), m_runningJobs.cend());
0068     }
0069 #endif
0070     bool isJobRunning(KIO::SimpleJob *job) const
0071     {
0072         return m_runningJobs.contains(job);
0073     }
0074 
0075     void queueJob(KIO::SimpleJob *job);
0076     KIO::SimpleJob *takeFirstInQueue();
0077     bool removeJob(KIO::SimpleJob *job);
0078 
0079     QList<KIO::Worker *> allWorkers() const;
0080 
0081 private:
0082     QMap<int, KIO::SimpleJob *> m_queuedJobs;
0083     QSet<KIO::SimpleJob *> m_runningJobs;
0084 };
0085 
0086 class SchedulerPrivate;
0087 
0088 class SerialPicker
0089 {
0090 public:
0091     // note that serial number zero is the default value from job_p.h and invalid!
0092 
0093     int next()
0094     {
0095         if (m_offset >= m_jobsPerPriority) {
0096             m_offset = 1;
0097         }
0098         return m_offset++;
0099     }
0100 
0101     int changedPrioritySerial(int oldSerial, int newPriority) const;
0102 
0103 private:
0104     static const uint m_jobsPerPriority = 100000000;
0105     uint m_offset = 1;
0106 
0107 public:
0108     static const int maxSerial = m_jobsPerPriority * 20;
0109 };
0110 
0111 class ProtoQueue : public QObject
0112 {
0113     Q_OBJECT
0114 public:
0115     ProtoQueue(int maxWorkers, int maxWorkersPerHost);
0116     ~ProtoQueue() override;
0117 
0118     void queueJob(KIO::SimpleJob *job);
0119     void changeJobPriority(KIO::SimpleJob *job, int newPriority);
0120     void removeJob(KIO::SimpleJob *job);
0121     KIO::Worker *createWorker(const QString &protocol, KIO::SimpleJob *job, const QUrl &url);
0122     bool removeWorker(KIO::Worker *worker);
0123     QList<KIO::Worker *> allWorkers() const;
0124 
0125 private Q_SLOTS:
0126     // start max one (non-connected) job and return
0127     void startAJob();
0128 
0129 private:
0130     SerialPicker m_serialPicker;
0131     QTimer m_startJobTimer;
0132     QMap<int, HostQueue *> m_queuesBySerial;
0133     QHash<QString, HostQueue> m_queuesByHostname;
0134     WorkerManager m_workerManager;
0135     int m_maxConnectionsPerHost;
0136     int m_maxConnectionsTotal;
0137     int m_runningJobsCount;
0138 };
0139 
0140 } // namespace KIO
0141 
0142 #endif // SCHEDULER_P_H