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.
11 #include "core/scheduler.h"
13 #include "core/kget.h"
15 #include "core/jobqueue.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()
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
)
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
)
76 void Scheduler::jobQueueMovedJobEvent(JobQueue
* queue
, Job
* job
)
83 void Scheduler::jobQueueAddedJobEvent(JobQueue
* queue
, Job
* job
)
90 void Scheduler::jobQueueRemovedJobEvent(JobQueue
* queue
, Job
* job
)
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
112 if (status
!= Job::Running
)
113 updateQueue( job
->jobQueue() );
116 void Scheduler::jobChangedEvent(Job
* job
, Job::Policy policy
)
120 updateQueue( job
->jobQueue() );
123 void Scheduler::startDelayTimer(Job
* job
, int seconds
)
127 int index
= startTimer(seconds
* 1000);
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
;
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
)
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";
194 else // != Job::Running
196 if( shouldBeRunning(*it
) )
198 kDebug(5001) << "Scheduler: starting job";
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.
216 //Stop all the other running downloads
217 kDebug(5001) << "Scheduler: stopping job over maxSimJobs limit";
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"