aboutsummaryrefslogtreecommitdiff
path: root/src/stable/minicron.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/stable/minicron.cpp622
1 files changed, 311 insertions, 311 deletions
diff --git a/src/stable/minicron.cpp b/src/stable/minicron.cpp
index 87296ae..c83cd44 100644
--- a/src/stable/minicron.cpp
+++ b/src/stable/minicron.cpp
@@ -11,260 +11,260 @@
11#include <time.h> 11#include <time.h>
12 12
13Bu::MiniCron::MiniCron() : 13Bu::MiniCron::MiniCron() :
14 jidNext( 1 ) 14 jidNext( 1 )
15{ 15{
16} 16}
17 17
18Bu::MiniCron::~MiniCron() 18Bu::MiniCron::~MiniCron()
19{ 19{
20 while( !hJobs.isEmpty() ) 20 while( !hJobs.isEmpty() )
21 { 21 {
22 delete hJobs.dequeue(); 22 delete hJobs.dequeue();
23 } 23 }
24} 24}
25 25
26bool Bu::MiniCron::hasJobs() 26bool Bu::MiniCron::hasJobs()
27{ 27{
28 return !hJobs.isEmpty(); 28 return !hJobs.isEmpty();
29} 29}
30 30
31time_t Bu::MiniCron::getNextRun() 31time_t Bu::MiniCron::getNextRun()
32{ 32{
33 if( hasJobs() ) 33 if( hasJobs() )
34 return hJobs.peek()->getNextRun(); 34 return hJobs.peek()->getNextRun();
35 return -1; 35 return -1;
36} 36}
37 37
38time_t Bu::MiniCron::getNextRun( Bu::MiniCron::JobId jid ) 38time_t Bu::MiniCron::getNextRun( Bu::MiniCron::JobId jid )
39{ 39{
40 for( JobHeap::iterator i = hJobs.begin(); i; i++ ) 40 for( JobHeap::iterator i = hJobs.begin(); i; i++ )
41 { 41 {
42 if( (*i)->getId() == jid ) 42 if( (*i)->getId() == jid )
43 { 43 {
44 return (*i)->getNextRunTime(); 44 return (*i)->getNextRunTime();
45 } 45 }
46 } 46 }
47 return -1; 47 return -1;
48} 48}
49 49
50void Bu::MiniCron::poll() 50void Bu::MiniCron::poll()
51{ 51{
52 time_t tNow = time( NULL ); 52 time_t tNow = time( NULL );
53 53
54 while( !hJobs.isEmpty() ) 54 while( !hJobs.isEmpty() )
55 { 55 {
56 if( hJobs.peek()->getNextRun() <= tNow ) 56 if( hJobs.peek()->getNextRun() <= tNow )
57 { 57 {
58 Job *pJob = hJobs.dequeue(); 58 Job *pJob = hJobs.dequeue();
59 pJob->run(); 59 pJob->run();
60 if( pJob->bContinue ) 60 if( pJob->bContinue )
61 { 61 {
62 hJobs.enqueue( pJob ); 62 hJobs.enqueue( pJob );
63 } 63 }
64 else 64 else
65 { 65 {
66 delete pJob; 66 delete pJob;
67 } 67 }
68 } 68 }
69 else 69 else
70 { 70 {
71 break; 71 break;
72 } 72 }
73 } 73 }
74} 74}
75 75
76Bu::MiniCron::JobId Bu::MiniCron::addJob( const Bu::String &sName, 76Bu::MiniCron::JobId Bu::MiniCron::addJob( const Bu::String &sName,
77 Bu::MiniCron::CronSignal sigJob, const Bu::MiniCron::Timer &t ) 77 Bu::MiniCron::CronSignal sigJob, const Bu::MiniCron::Timer &t )
78{ 78{
79 JobId jid = jidNext++; 79 JobId jid = jidNext++;
80 Job *pJob = new Job( sName, jid ); 80 Job *pJob = new Job( sName, jid );
81 pJob->sigJob = sigJob; 81 pJob->sigJob = sigJob;
82 pJob->pTimer = t.clone(); 82 pJob->pTimer = t.clone();
83 pJob->tNextRun = pJob->pTimer->nextTime(); 83 pJob->tNextRun = pJob->pTimer->nextTime();
84 hJobs.enqueue( pJob ); 84 hJobs.enqueue( pJob );
85 85
86 return jid; 86 return jid;
87} 87}
88 88
89Bu::MiniCron::JobId Bu::MiniCron::addJobOnce( const Bu::String &sName, 89Bu::MiniCron::JobId Bu::MiniCron::addJobOnce( const Bu::String &sName,
90 Bu::MiniCron::CronSignal sigJob, const Bu::MiniCron::Timer &t ) 90 Bu::MiniCron::CronSignal sigJob, const Bu::MiniCron::Timer &t )
91{ 91{
92 JobId jid = jidNext++; 92 JobId jid = jidNext++;
93 Job *pJob = new Job( sName, jid, false ); 93 Job *pJob = new Job( sName, jid, false );
94 pJob->sigJob = sigJob; 94 pJob->sigJob = sigJob;
95 pJob->pTimer = t.clone(); 95 pJob->pTimer = t.clone();
96 pJob->tNextRun = pJob->pTimer->nextTime(); 96 pJob->tNextRun = pJob->pTimer->nextTime();
97 hJobs.enqueue( pJob ); 97 hJobs.enqueue( pJob );
98 98
99 return jid; 99 return jid;
100} 100}
101 101
102void Bu::MiniCron::removeJob( JobId jid ) 102void Bu::MiniCron::removeJob( JobId jid )
103{ 103{
104 Bu::List<Job *> lJobs; 104 Bu::List<Job *> lJobs;
105 while( !hJobs.isEmpty() ) 105 while( !hJobs.isEmpty() )
106 { 106 {
107 Job *pJob = hJobs.dequeue(); 107 Job *pJob = hJobs.dequeue();
108 if( pJob->getId() == jid ) 108 if( pJob->getId() == jid )
109 { 109 {
110 delete pJob; 110 delete pJob;
111 } 111 }
112 else 112 else
113 lJobs.append( pJob ); 113 lJobs.append( pJob );
114 } 114 }
115 115
116 for( Bu::List<Job *>::iterator i = lJobs.begin(); i; i++ ) 116 for( Bu::List<Job *>::iterator i = lJobs.begin(); i; i++ )
117 { 117 {
118 hJobs.enqueue( *i ); 118 hJobs.enqueue( *i );
119 } 119 }
120} 120}
121 121
122void Bu::MiniCron::runJob( JobId jid, bool bReschedule ) 122void Bu::MiniCron::runJob( JobId jid, bool bReschedule )
123{ 123{
124 Bu::List<Job *> lJobs; 124 Bu::List<Job *> lJobs;
125 while( !hJobs.isEmpty() ) 125 while( !hJobs.isEmpty() )
126 { 126 {
127 Job *pJob = hJobs.dequeue(); 127 Job *pJob = hJobs.dequeue();
128 if( pJob->getId() == jid ) 128 if( pJob->getId() == jid )
129 { 129 {
130 pJob->run( bReschedule ); 130 pJob->run( bReschedule );
131 if( !pJob->bContinue ) 131 if( !pJob->bContinue )
132 { 132 {
133 delete pJob; 133 delete pJob;
134 break; 134 break;
135 } 135 }
136 lJobs.append( pJob ); 136 lJobs.append( pJob );
137 break; 137 break;
138 } 138 }
139 lJobs.append( pJob ); 139 lJobs.append( pJob );
140 } 140 }
141 141
142 for( Bu::List<Job *>::iterator i = lJobs.begin(); i; i++ ) 142 for( Bu::List<Job *>::iterator i = lJobs.begin(); i; i++ )
143 { 143 {
144 hJobs.enqueue( *i ); 144 hJobs.enqueue( *i );
145 } 145 }
146} 146}
147 147
148void Bu::MiniCron::runJob( const Bu::String &sName, bool bReschedule ) 148void Bu::MiniCron::runJob( const Bu::String &sName, bool bReschedule )
149{ 149{
150 Bu::List<Job *> lJobs; 150 Bu::List<Job *> lJobs;
151 while( !hJobs.isEmpty() ) 151 while( !hJobs.isEmpty() )
152 { 152 {
153 Job *pJob = hJobs.dequeue(); 153 Job *pJob = hJobs.dequeue();
154 if( pJob->getName() == sName ) 154 if( pJob->getName() == sName )
155 { 155 {
156 pJob->run( bReschedule ); 156 pJob->run( bReschedule );
157 if( !pJob->bContinue ) 157 if( !pJob->bContinue )
158 { 158 {
159 delete pJob; 159 delete pJob;
160 break; 160 break;
161 } 161 }
162 lJobs.append( pJob ); 162 lJobs.append( pJob );
163 break; 163 break;
164 } 164 }
165 lJobs.append( pJob ); 165 lJobs.append( pJob );
166 } 166 }
167 167
168 for( Bu::List<Job *>::iterator i = lJobs.begin(); i; i++ ) 168 for( Bu::List<Job *>::iterator i = lJobs.begin(); i; i++ )
169 { 169 {
170 hJobs.enqueue( *i ); 170 hJobs.enqueue( *i );
171 } 171 }
172} 172}
173 173
174Bu::MiniCron::JobInfoList Bu::MiniCron::getJobInfo() 174Bu::MiniCron::JobInfoList Bu::MiniCron::getJobInfo()
175{ 175{
176 JobInfoList lRet; 176 JobInfoList lRet;
177 for( JobHeap::iterator i = hJobs.begin(); i; i++ ) 177 for( JobHeap::iterator i = hJobs.begin(); i; i++ )
178 { 178 {
179 lRet.append( 179 lRet.append(
180 JobInfo( (*i)->getName(), (*i)->getId(), (*i)->getNextRun() ) 180 JobInfo( (*i)->getName(), (*i)->getId(), (*i)->getNextRun() )
181 ); 181 );
182 } 182 }
183 lRet.sort(); 183 lRet.sort();
184 return lRet; 184 return lRet;
185} 185}
186 186
187Bu::MiniCron::Job::Job( const Bu::String &sName, JobId jid, bool bRepeat ) : 187Bu::MiniCron::Job::Job( const Bu::String &sName, JobId jid, bool bRepeat ) :
188 sName( sName ), 188 sName( sName ),
189 pTimer( NULL ), 189 pTimer( NULL ),
190 bContinue( bRepeat ), 190 bContinue( bRepeat ),
191 jid( jid ), 191 jid( jid ),
192 tAdded( time( NULL ) ), 192 tAdded( time( NULL ) ),
193 iRunCount( 0 ) 193 iRunCount( 0 )
194{ 194{
195} 195}
196 196
197Bu::MiniCron::Job::~Job() 197Bu::MiniCron::Job::~Job()
198{ 198{
199 delete pTimer; 199 delete pTimer;
200 pTimer = NULL; 200 pTimer = NULL;
201} 201}
202 202
203void Bu::MiniCron::Job::run( bool bReschedule ) 203void Bu::MiniCron::Job::run( bool bReschedule )
204{ 204{
205 iRunCount++; 205 iRunCount++;
206 if( bReschedule ) 206 if( bReschedule )
207 tNextRun = pTimer->nextTime(); 207 tNextRun = pTimer->nextTime();
208 sigJob( *this ); 208 sigJob( *this );
209} 209}
210 210
211time_t Bu::MiniCron::Job::getNextRun() const 211time_t Bu::MiniCron::Job::getNextRun() const
212{ 212{
213 return tNextRun; 213 return tNextRun;
214} 214}
215 215
216void Bu::MiniCron::Job::calcNextRun() 216void Bu::MiniCron::Job::calcNextRun()
217{ 217{
218 if( pTimer ) 218 if( pTimer )
219 tNextRun = pTimer->nextTime(); 219 tNextRun = pTimer->nextTime();
220} 220}
221 221
222void Bu::MiniCron::Job::setTimer( const Timer &t ) 222void Bu::MiniCron::Job::setTimer( const Timer &t )
223{ 223{
224 delete pTimer; 224 delete pTimer;
225 pTimer = t.clone(); 225 pTimer = t.clone();
226} 226}
227 227
228void Bu::MiniCron::Job::stop() 228void Bu::MiniCron::Job::stop()
229{ 229{
230 bContinue = false; 230 bContinue = false;
231} 231}
232 232
233void Bu::MiniCron::Job::resume() 233void Bu::MiniCron::Job::resume()
234{ 234{
235 bContinue = true; 235 bContinue = true;
236} 236}
237 237
238Bu::MiniCron::JobId Bu::MiniCron::Job::getId() const 238Bu::MiniCron::JobId Bu::MiniCron::Job::getId() const
239{ 239{
240 return jid; 240 return jid;
241} 241}
242 242
243time_t Bu::MiniCron::Job::getTimeCreated() const 243time_t Bu::MiniCron::Job::getTimeCreated() const
244{ 244{
245 return tAdded; 245 return tAdded;
246} 246}
247 247
248int Bu::MiniCron::Job::getRunCount() const 248int Bu::MiniCron::Job::getRunCount() const
249{ 249{
250 return iRunCount; 250 return iRunCount;
251} 251}
252 252
253time_t Bu::MiniCron::Job::getNextRunTime() const 253time_t Bu::MiniCron::Job::getNextRunTime() const
254{ 254{
255 return tNextRun; 255 return tNextRun;
256} 256}
257 257
258Bu::String Bu::MiniCron::Job::getName() const 258Bu::String Bu::MiniCron::Job::getName() const
259{ 259{
260 return sName; 260 return sName;
261} 261}
262 262
263Bu::MiniCron::JobInfo::JobInfo( const Bu::String &sName, JobId jid, 263Bu::MiniCron::JobInfo::JobInfo( const Bu::String &sName, JobId jid,
264 time_t tNext ) : 264 time_t tNext ) :
265 sName( sName ), 265 sName( sName ),
266 jid( jid ), 266 jid( jid ),
267 tNext( tNext ) 267 tNext( tNext )
268{ 268{
269} 269}
270 270
@@ -274,7 +274,7 @@ Bu::MiniCron::JobInfo::~JobInfo()
274 274
275bool Bu::MiniCron::JobInfo::operator<( const JobInfo &rhs ) const 275bool Bu::MiniCron::JobInfo::operator<( const JobInfo &rhs ) const
276{ 276{
277 return jid < rhs.jid; 277 return jid < rhs.jid;
278} 278}
279 279
280Bu::MiniCron::Timer::Timer() 280Bu::MiniCron::Timer::Timer()
@@ -286,8 +286,8 @@ Bu::MiniCron::Timer::~Timer()
286} 286}
287 287
288Bu::MiniCron::TimerInterval::TimerInterval( time_t tFirst, time_t tInterval ) : 288Bu::MiniCron::TimerInterval::TimerInterval( time_t tFirst, time_t tInterval ) :
289 tNext( tFirst ), 289 tNext( tFirst ),
290 tInterval( tInterval ) 290 tInterval( tInterval )
291{ 291{
292} 292}
293 293
@@ -297,14 +297,14 @@ Bu::MiniCron::TimerInterval::~TimerInterval()
297 297
298time_t Bu::MiniCron::TimerInterval::nextTime() 298time_t Bu::MiniCron::TimerInterval::nextTime()
299{ 299{
300 time_t tRet = tNext; 300 time_t tRet = tNext;
301 tNext += tInterval; 301 tNext += tInterval;
302 return tRet; 302 return tRet;
303} 303}
304 304
305Bu::MiniCron::TimerBasic::TimerBasic( const Bu::String &s ) : 305Bu::MiniCron::TimerBasic::TimerBasic( const Bu::String &s ) :
306 tLast( -1 ), 306 tLast( -1 ),
307 sSpec( s ) 307 sSpec( s )
308{ 308{
309} 309}
310 310
@@ -314,164 +314,164 @@ Bu::MiniCron::TimerBasic::~TimerBasic()
314 314
315time_t Bu::MiniCron::TimerBasic::nextTime() 315time_t Bu::MiniCron::TimerBasic::nextTime()
316{ 316{
317 if( tLast == -1 ) 317 if( tLast == -1 )
318 tLast = time( NULL ); 318 tLast = time( NULL );
319 319
320 Bu::String::const_iterator i = sSpec.begin(); 320 Bu::String::const_iterator i = sSpec.begin();
321 switch( lex( i ) ) 321 switch( lex( i ) )
322 { 322 {
323 case tokDaily: 323 case tokDaily:
324 { 324 {
325 int iHour = lexInt( i ); 325 int iHour = lexInt( i );
326 int iMin = lexInt( i ); 326 int iMin = lexInt( i );
327 327
328 struct tm t; 328 struct tm t;
329 ::memcpy( &t, localtime( &tLast ), sizeof(struct tm) ); 329 ::memcpy( &t, localtime( &tLast ), sizeof(struct tm) );
330 if( iHour < t.tm_hour || 330 if( iHour < t.tm_hour ||
331 (iHour == t.tm_hour && iMin <= t.tm_min) ) 331 (iHour == t.tm_hour && iMin <= t.tm_min) )
332 { 332 {
333 t.tm_mday++; 333 t.tm_mday++;
334 } 334 }
335 t.tm_hour = iHour; 335 t.tm_hour = iHour;
336 t.tm_min = iMin; 336 t.tm_min = iMin;
337 t.tm_sec = 0; 337 t.tm_sec = 0;
338 tLast = mktime( &t ); 338 tLast = mktime( &t );
339 } 339 }
340 break; 340 break;
341 341
342 case tokHourly: 342 case tokHourly:
343 { 343 {
344 int iMin = lexInt( i ); 344 int iMin = lexInt( i );
345 345
346 struct tm t; 346 struct tm t;
347 ::memcpy( &t, localtime( &tLast ), sizeof(struct tm) ); 347 ::memcpy( &t, localtime( &tLast ), sizeof(struct tm) );
348 if( iMin <= t.tm_min ) 348 if( iMin <= t.tm_min )
349 t.tm_hour++; 349 t.tm_hour++;
350 t.tm_min = iMin; 350 t.tm_min = iMin;
351 t.tm_sec = 0; 351 t.tm_sec = 0;
352 tLast = mktime( &t ); 352 tLast = mktime( &t );
353 } 353 }
354 break; 354 break;
355 355
356 case tokWeekly: 356 case tokWeekly:
357 { 357 {
358 int iDay = lexInt( i ); 358 int iDay = lexInt( i );
359 int iHour = lexInt( i ); 359 int iHour = lexInt( i );
360 int iMin = lexInt( i ); 360 int iMin = lexInt( i );
361 361
362 struct tm t; 362 struct tm t;
363 ::memcpy( &t, localtime( &tLast ), sizeof(struct tm) ); 363 ::memcpy( &t, localtime( &tLast ), sizeof(struct tm) );
364 if( iDay < t.tm_wday || 364 if( iDay < t.tm_wday ||
365 (iDay == t.tm_wday && iHour < t.tm_hour) || 365 (iDay == t.tm_wday && iHour < t.tm_hour) ||
366 (iDay == t.tm_wday && iHour == t.tm_hour 366 (iDay == t.tm_wday && iHour == t.tm_hour
367 && iMin <= t.tm_min) ) 367 && iMin <= t.tm_min) )
368 { 368 {
369 if( iDay <= t.tm_wday ) 369 if( iDay <= t.tm_wday )
370 t.tm_mday += 7 - (t.tm_wday-iDay); 370 t.tm_mday += 7 - (t.tm_wday-iDay);
371 else 371 else
372 t.tm_mday += 7 - (iDay-t.tm_wday); 372 t.tm_mday += 7 - (iDay-t.tm_wday);
373 } 373 }
374 else 374 else
375 { 375 {
376 t.tm_mday += (iDay-t.tm_wday); 376 t.tm_mday += (iDay-t.tm_wday);
377 } 377 }
378 t.tm_hour = iHour; 378 t.tm_hour = iHour;
379 t.tm_min = iMin; 379 t.tm_min = iMin;
380 t.tm_sec = 0; 380 t.tm_sec = 0;
381 tLast = mktime( &t ); 381 tLast = mktime( &t );
382 } 382 }
383 break; 383 break;
384 384
385 case tokMonthly: 385 case tokMonthly:
386 break; 386 break;
387 387
388 case tokYearly: 388 case tokYearly:
389 break; 389 break;
390 390
391 default: 391 default:
392 break; 392 break;
393 } 393 }
394 394
395 return tLast; 395 return tLast;
396} 396}
397 397
398Bu::MiniCron::TimerBasic::Token Bu::MiniCron::TimerBasic::lex( 398Bu::MiniCron::TimerBasic::Token Bu::MiniCron::TimerBasic::lex(
399 Bu::String::const_iterator &i ) 399 Bu::String::const_iterator &i )
400{ 400{
401 if( !i ) 401 if( !i )
402 { 402 {
403 return tokEos; 403 return tokEos;
404 } 404 }
405 405
406 Bu::String::const_iterator b = i; 406 Bu::String::const_iterator b = i;
407 407
408 for(; b && (*b == ' ' || *b == '\t'); b++ ) { i = b+1; } 408 for(; b && (*b == ' ' || *b == '\t'); b++ ) { i = b+1; }
409 for(; b && *b != ' ' && *b != '\t'; b++ ) { } 409 for(; b && *b != ' ' && *b != '\t'; b++ ) { }
410 410
411 Bu::String sTok( i, b ); 411 Bu::String sTok( i, b );
412 i = b; 412 i = b;
413 413
414 if( sTok == "daily" ) 414 if( sTok == "daily" )
415 return tokDaily; 415 return tokDaily;
416 else if( sTok == "hourly" ) 416 else if( sTok == "hourly" )
417 return tokHourly; 417 return tokHourly;
418 else if( sTok == "weekly" ) 418 else if( sTok == "weekly" )
419 return tokWeekly; 419 return tokWeekly;
420 else if( sTok == "monthly" ) 420 else if( sTok == "monthly" )
421 return tokMonthly; 421 return tokMonthly;
422 else if( sTok == "yearly" ) 422 else if( sTok == "yearly" )
423 return tokYearly; 423 return tokYearly;
424 else if( sTok == "sun" ) 424 else if( sTok == "sun" )
425 { 425 {
426 iVal = 0; 426 iVal = 0;
427 return valInt; 427 return valInt;
428 } 428 }
429 else if( sTok == "mon" ) 429 else if( sTok == "mon" )
430 { 430 {
431 iVal = 1; 431 iVal = 1;
432 return valInt; 432 return valInt;
433 } 433 }
434 else if( sTok == "tue" ) 434 else if( sTok == "tue" )
435 { 435 {
436 iVal = 2; 436 iVal = 2;
437 return valInt; 437 return valInt;
438 } 438 }
439 else if( sTok == "wed" ) 439 else if( sTok == "wed" )
440 { 440 {
441 iVal = 3; 441 iVal = 3;
442 return valInt; 442 return valInt;
443 } 443 }
444 else if( sTok == "thu" ) 444 else if( sTok == "thu" )
445 { 445 {
446 iVal = 4; 446 iVal = 4;
447 return valInt; 447 return valInt;
448 } 448 }
449 else if( sTok == "fri" ) 449 else if( sTok == "fri" )
450 { 450 {
451 iVal = 5; 451 iVal = 5;
452 return valInt; 452 return valInt;
453 } 453 }
454 else if( sTok == "sat" ) 454 else if( sTok == "sat" )
455 { 455 {
456 iVal = 6; 456 iVal = 6;
457 return valInt; 457 return valInt;
458 } 458 }
459 else if( sTok[0] >= '0' && sTok[0] <= '9' ) 459 else if( sTok[0] >= '0' && sTok[0] <= '9' )
460 { 460 {
461 iVal = strtol( sTok.getStr(), NULL, 0 ); 461 iVal = strtol( sTok.getStr(), NULL, 0 );
462 return valInt; 462 return valInt;
463 } 463 }
464 464
465 return tokErr; 465 return tokErr;
466} 466}
467 467
468int Bu::MiniCron::TimerBasic::lexInt( Bu::String::const_iterator &i ) 468int Bu::MiniCron::TimerBasic::lexInt( Bu::String::const_iterator &i )
469{ 469{
470 Token t = lex( i ); 470 Token t = lex( i );
471 if( t == tokEos ) 471 if( t == tokEos )
472 return 0; 472 return 0;
473 if( t != valInt ) 473 if( t != valInt )
474 throw Bu::ExceptionBase("Expected int, got something else."); 474 throw Bu::ExceptionBase("Expected int, got something else.");
475 return iVal; 475 return iVal;
476} 476}
477 477