Relicense all GPLv2 only code to GPLv2+.
[kdenetwork.git] / kget / core / scheduler.cpp
blob06c7bba5eb583c9c8acedbeeb83da775a0ce899d
1 /* This file is part of the KDE project
3 Copyright (C) 2004 Dario Massarin <nekkar@libero.it>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9 */
11 #include "core/scheduler.h"
13 #include "core/kget.h"
14 #include "core/job.h"
15 #include "core/jobqueue.h"
16 #include "settings.h"
18 #include <kdebug.h>
20 Scheduler::Scheduler()
24 Scheduler::~Scheduler()
29 void Scheduler::addQueue(JobQueue * queue)
31 if(!m_queues.contains(queue))
32 m_queues.append(queue);
35 void Scheduler::delQueue(JobQueue * queue)
37 m_queues.removeAll(queue);
40 int Scheduler::countRunningJobs()
42 int count = 0;
44 foreach(JobQueue * queue, m_queues)
46 JobQueue::iterator it = queue->begin();
47 JobQueue::iterator itEnd = queue->end();
49 for( ; it!=itEnd ; ++it )
51 if((*it)->status() == Job::Running)
52 count++;
56 return count;
59 void Scheduler::jobQueueChangedEvent(JobQueue * queue, JobQueue::Status status)
61 if( status == JobQueue::Stopped )
63 JobQueue::iterator it = queue->begin();
64 JobQueue::iterator itEnd = queue->end();
66 for( ; it!=itEnd ; ++it)
68 if((*it)->status() != Job::Stopped)
69 (*it)->stop();
72 else
73 updateQueue(queue);
76 void Scheduler::jobQueueMovedJobEvent(JobQueue * queue, Job * job)
78 Q_UNUSED(job);
80 updateQueue(queue);
83 void Scheduler::jobQueueAddedJobEvent(JobQueue * queue, Job * job)
85 Q_UNUSED(job);
87 updateQueue(queue);
90 void Scheduler::jobQueueRemovedJobEvent(JobQueue * queue, Job * job)
92 Q_UNUSED(job);
94 updateQueue(queue);
97 void Scheduler::jobChangedEvent(Job * job, Job::Status status)
99 kDebug(5001) << "Scheduler::jobChangedEvent (" << status << ")";
101 //If the Job changed its status to Aborted, set a delay.
102 if (status == Job::Aborted)
104 if(Settings::reconnectOnBroken())
105 job->setDelay(Settings::reconnectDelay());
106 //Here it's not necessary to call updateQueue since the setDelay()
107 //function will generate another jobChangedEvent. We will call
108 //updateQueue then.
109 return;
112 if (status != Job::Running)
113 updateQueue( job->jobQueue() );
116 void Scheduler::jobChangedEvent(Job * job, Job::Policy policy)
118 Q_UNUSED(policy);
120 updateQueue( job->jobQueue() );
123 void Scheduler::startDelayTimer(Job * job, int seconds)
125 stopDelayTimer(job);
127 int index = startTimer(seconds * 1000);
128 if(index == 0)
129 return;
130 m_activeTimers[index] = job;
133 void Scheduler::stopDelayTimer(Job * job)
135 QMap<int, Job *>::iterator it = m_activeTimers.begin();
136 while (it != m_activeTimers.end())
138 QMap<int, Job *>::iterator prev = it;
139 ++it;
140 if(prev.value() == job)
142 //A timer for this job has been found. Let's stop it.
143 killTimer(prev.key());
144 m_activeTimers.erase(prev);
149 void Scheduler::start()
151 QList<JobQueue *>::iterator it = m_queues.begin();
152 QList<JobQueue *>::iterator itEnd = m_queues.end();
154 for( ; it!=itEnd ; ++it )
156 (*it)->setStatus(JobQueue::Running);
160 void Scheduler::stop()
162 QList<JobQueue *>::iterator it = m_queues.begin();
163 QList<JobQueue *>::iterator itEnd = m_queues.end();
165 for( ; it!=itEnd ; ++it )
167 (*it)->setStatus(JobQueue::Stopped);
171 void Scheduler::updateQueue( JobQueue * queue )
173 int runningJobs = 0;
175 JobQueue::iterator it = queue->begin();
176 JobQueue::iterator itEnd = queue->end();
178 for( int job=0 ; it!=itEnd ; ++it, ++job)
180 //kDebug(5001) << "MaxSimJobs " << queue->maxSimultaneousJobs();
181 kDebug(5001) << "Scheduler: Evaluating job " << job;
182 if( runningJobs < queue->maxSimultaneousJobs() )
184 if( (*it)->status() == Job::Running )
186 if( !shouldBeRunning(*it) )
188 kDebug(5001) << "Scheduler: stopping job";
189 (*it)->stop();
191 else
192 runningJobs++;
194 else // != Job::Running
196 if( shouldBeRunning(*it) )
198 kDebug(5001) << "Scheduler: starting job";
199 (*it)->start();
200 runningJobs++;
202 else if( ((*it)->status() == Job::Delayed )
203 && ((*it)->policy() == Job::Stop ) )
205 kDebug(5001) << "Scheduler: Delayed transfer that should be stopped";
206 //This is a special case that we have to handle separately:
207 //if the download status is Delayed, but the current policy
208 //is Stopped, we must stop immediately the transfer.
209 stopDelayTimer(*it);
210 (*it)->stop();
214 else
216 //Stop all the other running downloads
217 kDebug(5001) << "Scheduler: stopping job over maxSimJobs limit";
218 (*it)->stop();
223 bool Scheduler::shouldBeRunning( Job * job )
225 Job::Policy policy = job->policy();
226 Job::Status status = job->status();
228 if( job->jobQueue()->status() == JobQueue::Stopped )
230 return ( (policy == Job::Start) &&
231 (status != Job::Delayed) &&
232 (status != Job::Finished) );
234 else //JobQueue::Running
236 return ( (policy != Job::Stop) &&
237 (status != Job::Delayed) &&
238 (status != Job::Finished) );
242 void Scheduler::timerEvent( QTimerEvent * event )
244 Job * job = m_activeTimers[event->timerId()];
245 stopDelayTimer( job );
247 job->delayTimerEvent();
250 #include "scheduler.moc"