• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

mailcommon

  • sources
  • kde-4.12
  • kdepim
  • mailcommon
  • job
jobscheduler.cpp
Go to the documentation of this file.
1 
30 #include "jobscheduler.h"
31 #include <kdebug.h>
32 
33 namespace MailCommon {
34 
35 ScheduledTask::ScheduledTask( const Akonadi::Collection& folder, bool immediate )
36  : mCurrentFolder( folder ), mImmediate( immediate )
37 {
38 }
39 
40 ScheduledTask::~ScheduledTask()
41 {
42 }
43 
44 JobScheduler::JobScheduler( QObject* parent )
45  : QObject( parent ), mTimer( this ),
46  mPendingImmediateTasks( 0 ),
47  mCurrentTask( 0 ), mCurrentJob( 0 )
48 {
49  connect( &mTimer, SIGNAL(timeout()), SLOT(slotRunNextJob()) );
50  // No need to start the internal timer yet, we wait for a task to be scheduled
51 }
52 
53 
54 JobScheduler::~JobScheduler()
55 {
56  qDeleteAll( mTaskList );
57  mTaskList.clear();
58  delete mCurrentTask;
59  mCurrentTask = 0;
60  delete mCurrentJob;
61 }
62 
63 void JobScheduler::registerTask( ScheduledTask* task )
64 {
65  bool immediate = task->isImmediate();
66  int typeId = task->taskTypeId();
67  if ( typeId ) {
68  const Akonadi::Collection folder = task->folder();
69  // Search for an identical task already scheduled
70  TaskList::Iterator end( mTaskList.end() );
71  for ( TaskList::Iterator it = mTaskList.begin(); it != end; ++it ) {
72  if ( (*it)->taskTypeId() == typeId && (*it)->folder() == folder ) {
73 #ifdef DEBUG_SCHEDULER
74  kDebug() << "JobScheduler: already having task type" << typeId << "for folder" << folder->label();
75 #endif
76  delete task;
77  if ( !mCurrentTask && immediate ) {
78  ScheduledTask* task = *it;
79  removeTask( it );
80  runTaskNow( task );
81  }
82  return;
83  }
84  }
85  // Note that scheduling an identical task as the one currently running is allowed.
86  }
87  if ( !mCurrentTask && immediate )
88  runTaskNow( task );
89  else {
90 #ifdef DEBUG_SCHEDULER
91  kDebug() << "JobScheduler: adding task" << task << "(type" << task->taskTypeId()
92  << ") for folder" << task->folder() << task->folder().name();
93 #endif
94  mTaskList.append( task );
95  if ( immediate )
96  ++mPendingImmediateTasks;
97  if ( !mCurrentTask && !mTimer.isActive() )
98  restartTimer();
99  }
100 }
101 
102 void JobScheduler::removeTask( TaskList::Iterator& it )
103 {
104  if ( (*it)->isImmediate() )
105  --mPendingImmediateTasks;
106  mTaskList.erase( it );
107 }
108 
109 void JobScheduler::interruptCurrentTask()
110 {
111  Q_ASSERT( mCurrentTask );
112 #ifdef DEBUG_SCHEDULER
113  kDebug() << "JobScheduler: interrupting job" << mCurrentJob << "for folder" << mCurrentTask->folder()->label();
114 #endif
115  // File it again. This will either delete it or put it in mTaskList.
116  registerTask( mCurrentTask );
117  mCurrentTask = 0;
118  mCurrentJob->kill(); // This deletes the job and calls slotJobFinished!
119 }
120 
121 void JobScheduler::slotRunNextJob()
122 {
123  while ( !mCurrentJob ) {
124 #ifdef DEBUG_SCHEDULER
125  kDebug() << "JobScheduler: slotRunNextJob";
126 #endif
127  Q_ASSERT( mCurrentTask == 0 );
128  ScheduledTask* task = 0;
129  // Find a task suitable for being run
130  TaskList::Iterator end( mTaskList.end() );
131  for ( TaskList::Iterator it = mTaskList.begin(); it != end; ++it ) {
132  // Remove if folder died
133  const Akonadi::Collection folder = (*it)->folder();
134  if ( !folder.isValid() ) {
135 #ifdef DEBUG_SCHEDULER
136  kDebug() << " folder for task" << (*it) << "was deleted";
137 #endif
138  removeTask( it );
139  if ( !mTaskList.isEmpty() )
140  slotRunNextJob(); // to avoid the mess with invalid iterators :)
141  else
142  mTimer.stop();
143  return;
144  }
145 #ifdef DEBUG_SCHEDULER
146  kDebug() << " looking at folder" << folder.name();
147 #endif
148  task = *it;
149  removeTask( it );
150  break;
151  }
152 
153  if ( !task ) // found nothing to run, i.e. folder was opened
154  return; // Timer keeps running, i.e. try again in 1 minute
155 
156  runTaskNow( task );
157  } // If nothing to do for that task, loop and find another one to run
158 }
159 
160 void JobScheduler::restartTimer()
161 {
162  if ( mPendingImmediateTasks > 0 )
163  slotRunNextJob();
164  else
165  {
166 #ifdef DEBUG_SCHEDULER
167  mTimer.start( 10000 ); // 10 seconds
168 #else
169  mTimer.start( 1 * 60000 ); // 1 minute
170 #endif
171  }
172 }
173 
174 void JobScheduler::runTaskNow( ScheduledTask* task )
175 {
176  Q_ASSERT( mCurrentTask == 0 );
177  if ( mCurrentTask ) {
178  interruptCurrentTask();
179  }
180  mCurrentTask = task;
181  mTimer.stop();
182  mCurrentJob = mCurrentTask->run();
183 #ifdef DEBUG_SCHEDULER
184  kDebug() << "JobScheduler: task" << mCurrentTask
185  << "(type" << mCurrentTask->taskTypeId() << ")"
186  << "for folder" << mCurrentTask->folder()->label()
187  << "returned job" << mCurrentJob
188  << ( mCurrentJob?mCurrentJob->className():0 );
189 #endif
190  if ( !mCurrentJob ) { // nothing to do, e.g. folder deleted
191  delete mCurrentTask;
192  mCurrentTask = 0;
193  if ( !mTaskList.isEmpty() )
194  restartTimer();
195  return;
196  }
197  // Register the job in the folder. This makes it autodeleted if the folder is deleted.
198 #if 0
199  mCurrentTask->folder()->storage()->addJob( mCurrentJob );
200 #endif
201  connect( mCurrentJob, SIGNAL(finished()), this, SLOT(slotJobFinished()) );
202  mCurrentJob->start();
203 }
204 
205 void JobScheduler::slotJobFinished()
206 {
207  // Do we need to test for mCurrentJob->error()? What do we do then?
208 #ifdef DEBUG_SCHEDULER
209  kDebug() << "JobScheduler: slotJobFinished";
210 #endif
211  delete mCurrentTask;
212  mCurrentTask = 0;
213  mCurrentJob = 0;
214  if ( !mTaskList.isEmpty() )
215  restartTimer();
216 }
217 
218 // D-Bus call to pause any background jobs
219 void JobScheduler::pause()
220 {
221  mPendingImmediateTasks = 0;
222  if ( mCurrentJob && mCurrentJob->isCancellable() )
223  interruptCurrentTask();
224  mTimer.stop();
225 }
226 
227 void JobScheduler::resume()
228 {
229  restartTimer();
230 }
231 
233 
234 ScheduledJob::ScheduledJob( const Akonadi::Collection& folder, bool immediate )
235  : mImmediate( immediate )
236 {
237  mCancellable = true;
238  mSrcFolder = folder;
239 }
240 
241 ScheduledJob::~ScheduledJob()
242 {
243 }
244 
245 }
246 
247 #include "jobscheduler.moc"
MailCommon::ScheduledTask::ScheduledTask
ScheduledTask(const Akonadi::Collection &folder, bool immediate)
Create a scheduled task for a given folder If immediate is true, the scheduler will run this task as ...
Definition: jobscheduler.cpp:35
MailCommon::JobScheduler::pause
void pause()
Definition: jobscheduler.cpp:219
MailCommon::ScheduledTask
A scheduled task is some information about a folder job that should be run later. ...
Definition: jobscheduler.h:54
MailCommon::ScheduledJob::ScheduledJob
ScheduledJob(const Akonadi::Collection &folder, bool immediate)
Definition: jobscheduler.cpp:234
MailCommon::FolderJob::kill
virtual void kill()
Interrupt the job.
Definition: folderjob.cpp:60
QObject
MailCommon::FolderJob::mCancellable
bool mCancellable
Definition: folderjob.h:112
MailCommon::JobScheduler::JobScheduler
JobScheduler(QObject *parent)
Definition: jobscheduler.cpp:44
MailCommon::JobScheduler::~JobScheduler
~JobScheduler()
Definition: jobscheduler.cpp:54
MailCommon::JobScheduler::registerTask
void registerTask(ScheduledTask *task)
Register a task to be done for a given folder The ownership of the task is transferred to the JobSche...
Definition: jobscheduler.cpp:63
MailCommon::ScheduledTask::folder
Akonadi::Collection folder() const
The folder which this task is about, 0 if it was deleted meanwhile.
Definition: jobscheduler.h:78
MailCommon::ScheduledJob::~ScheduledJob
~ScheduledJob()
Definition: jobscheduler.cpp:241
MailCommon::ScheduledTask::taskTypeId
virtual int taskTypeId() const =0
An identifier for the type of task (a bit like QListViewItem::rtti) This allows to automatically prev...
MailCommon::JobScheduler::resume
void resume()
Definition: jobscheduler.cpp:227
jobscheduler.h
MailCommon::FolderJob::start
void start()
Start the job.
Definition: folderjob.cpp:51
MailCommon::ScheduledTask::isImmediate
bool isImmediate() const
Definition: jobscheduler.h:80
MailCommon::ScheduledTask::~ScheduledTask
virtual ~ScheduledTask()
Definition: jobscheduler.cpp:40
MailCommon::FolderJob::mSrcFolder
Akonadi::Collection mSrcFolder
Definition: folderjob.h:108
MailCommon::ScheduledTask::run
virtual ScheduledJob * run()=0
Run this task, i.e.
MailCommon::FolderJob::isCancellable
bool isCancellable() const
Definition: folderjob.h:71
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:55:14 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

mailcommon

Skip menu "mailcommon"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal