File indexing completed on 2023-09-24 04:08:42
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 slave keeper manages the list of idle slaves that can be reused 0020 class SlaveKeeper : public QObject 0021 { 0022 Q_OBJECT 0023 public: 0024 SlaveKeeper(); 0025 ~SlaveKeeper() override; 0026 void returnSlave(KIO::Slave *slave); 0027 // pick suitable slave for job and return it, return null if no slave found. 0028 // the slave is removed from the keeper. 0029 KIO::Slave *takeSlaveForJob(KIO::SimpleJob *job); 0030 // remove slave from keeper 0031 bool removeSlave(KIO::Slave *slave); 0032 // remove all slaves from keeper 0033 void clear(); 0034 QList<KIO::Slave *> allSlaves() const; 0035 0036 private: 0037 void scheduleGrimReaper(); 0038 0039 private Q_SLOTS: 0040 void grimReaper(); 0041 0042 private: 0043 QMultiHash<QString, KIO::Slave *> m_idleSlaves; 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::Slave *> allSlaves() const; 0080 0081 private: 0082 QMap<int, KIO::SimpleJob *> m_queuedJobs; 0083 QSet<KIO::SimpleJob *> m_runningJobs; 0084 }; 0085 0086 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 91) 0087 struct PerSlaveQueue { 0088 PerSlaveQueue() 0089 : runningJob(nullptr) 0090 { 0091 } 0092 QList<SimpleJob *> waitingList; 0093 SimpleJob *runningJob; 0094 }; 0095 0096 class ConnectedSlaveQueue : public QObject 0097 { 0098 Q_OBJECT 0099 public: 0100 ConnectedSlaveQueue(); 0101 0102 bool queueJob(KIO::SimpleJob *job, KIO::Slave *slave); 0103 bool removeJob(KIO::SimpleJob *job); 0104 0105 void addSlave(KIO::Slave *slave); 0106 bool removeSlave(KIO::Slave *slave); 0107 0108 // KDE5: only one caller, for doubtful reasons. remove this if possible. 0109 bool isIdle(KIO::Slave *slave); 0110 bool isEmpty() const 0111 { 0112 return m_connectedSlaves.isEmpty(); 0113 } 0114 QList<KIO::Slave *> allSlaves() const 0115 { 0116 return m_connectedSlaves.keys(); 0117 } 0118 0119 private Q_SLOTS: 0120 void startRunnableJobs(); 0121 0122 private: 0123 // note that connected slaves stay here when idle, they are not returned to SlaveKeeper 0124 QHash<KIO::Slave *, PerSlaveQueue> m_connectedSlaves; 0125 QSet<KIO::Slave *> m_runnableSlaves; 0126 QTimer m_startJobsTimer; 0127 }; 0128 #endif 0129 0130 class SchedulerPrivate; 0131 0132 class SerialPicker 0133 { 0134 public: 0135 // note that serial number zero is the default value from job_p.h and invalid! 0136 0137 int next() 0138 { 0139 if (m_offset >= m_jobsPerPriority) { 0140 m_offset = 1; 0141 } 0142 return m_offset++; 0143 } 0144 0145 int changedPrioritySerial(int oldSerial, int newPriority) const; 0146 0147 private: 0148 static const uint m_jobsPerPriority = 100000000; 0149 uint m_offset = 1; 0150 0151 public: 0152 static const int maxSerial = m_jobsPerPriority * 20; 0153 }; 0154 0155 class ProtoQueue : public QObject 0156 { 0157 Q_OBJECT 0158 public: 0159 ProtoQueue(int maxWorkers, int maxWorkersPerHost); 0160 ~ProtoQueue() override; 0161 0162 void queueJob(KIO::SimpleJob *job); 0163 void changeJobPriority(KIO::SimpleJob *job, int newPriority); 0164 void removeJob(KIO::SimpleJob *job); 0165 KIO::Slave *createSlave(const QString &protocol, KIO::SimpleJob *job, const QUrl &url); 0166 bool removeSlave(KIO::Slave *slave); 0167 QList<KIO::Slave *> allSlaves() const; 0168 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 91) 0169 ConnectedSlaveQueue m_connectedSlaveQueue; // KF6 TODO: remove 0170 #endif 0171 0172 private Q_SLOTS: 0173 // start max one (non-connected) job and return 0174 void startAJob(); 0175 0176 private: 0177 SerialPicker m_serialPicker; 0178 QTimer m_startJobTimer; 0179 QMap<int, HostQueue *> m_queuesBySerial; 0180 QHash<QString, HostQueue> m_queuesByHostname; 0181 SlaveKeeper m_slaveKeeper; 0182 int m_maxConnectionsPerHost; 0183 int m_maxConnectionsTotal; 0184 int m_runningJobsCount; 0185 }; 0186 0187 } // namespace KIO 0188 0189 #endif // SCHEDULER_P_H