File indexing completed on 2024-10-13 03:38:12
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