Ticket #2282: 2282-alt-v4.patch
File 2282-alt-v4.patch, 16.7 KB (added by , 17 years ago) |
---|
-
programs/mythbackend/scheduler.cpp
36 36 #define LOC QString("Scheduler: ") 37 37 #define LOC_ERR QString("Scheduler, Error: ") 38 38 39 static void delete_reclist(RecList &reclist); 40 static void copy_reclist(RecList ©, const RecList &orig); 41 39 42 Scheduler::Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList, 40 43 QString recordTbl, Scheduler *master_sched) 41 44 { … … 47 50 if (master_sched) 48 51 { 49 52 specsched = true; 50 master_sched->getAllPending(& reclist);53 master_sched->getAllPending(&cached_reclist); 51 54 } 52 55 53 56 // Only the master scheduler should use SchedCon() … … 66 69 67 70 threadrunning = runthread; 68 71 69 reclist_lock = new QMutex(true);72 cached_reclist_lock = new QMutex(true); 70 73 schedlist_lock = new QMutex(true); 71 74 72 75 if (runthread) … … 78 81 79 82 Scheduler::~Scheduler() 80 83 { 81 while (reclist.size() > 0) 84 delete_reclist(cached_reclist); 85 86 if (cached_reclist_lock) 82 87 { 83 ProgramInfo *pginfo = reclist.back(); 84 delete pginfo; 85 reclist.pop_back(); 88 delete cached_reclist_lock; 89 cached_reclist_lock = NULL; 86 90 } 91 92 if (schedlist_lock) 93 { 94 delete schedlist_lock; 95 schedlist_lock = NULL; 96 } 87 97 } 88 98 89 99 void Scheduler::SetMainServer(MainServer *ms) … … 263 273 264 274 bool Scheduler::FillRecordList(void) 265 275 { 266 QMutexLocker lockit(reclist_lock);267 268 276 schedMoveHigher = (bool)gContext->GetNumSetting("SchedMoveHigher"); 269 277 schedTime = QDateTime::currentDateTime(); 270 278 279 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locking 1"); 280 cached_reclist_lock->lock(); 281 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locked 1"); 282 283 copy_reclist(reclist, cached_reclist); 284 285 cached_reclist_lock->unlock(); 286 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- unlocked 1"); 287 271 288 VERBOSE(VB_SCHEDULE, "PruneOldRecords..."); 272 289 PruneOldRecords(); 273 290 VERBOSE(VB_SCHEDULE, "AddNewRecords..."); … … 292 309 VERBOSE(VB_SCHEDULE, "Sort by time..."); 293 310 reclist.sort(comp_redundant); 294 311 VERBOSE(VB_SCHEDULE, "PruneRedundants..."); 295 PruneRedundants();312 bool will_have_conflicts = PruneRedundants(); 296 313 297 314 VERBOSE(VB_SCHEDULE, "Sort by time..."); 298 315 reclist.sort(comp_recstart); 299 316 317 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locking 2"); 318 cached_reclist_lock->lock(); 319 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locked 2"); 320 321 copy_reclist(cached_reclist, reclist); 322 hasconflicts = will_have_conflicts; 323 324 cached_reclist_lock->unlock(); 325 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- unlocked 2"); 326 327 delete_reclist(reclist); 328 300 329 return hasconflicts; 301 330 } 302 331 … … 358 387 (fillend.tv_usec - fillstart.tv_usec) / 1000000.0; 359 388 QString msg; 360 389 msg.sprintf("Speculative scheduled %d items in " 361 "%.2f", (int) reclist.size(),390 "%.2f", (int)cached_reclist.size(), 362 391 schedTime); 363 392 VERBOSE(VB_GENERAL, msg); 364 393 } … … 368 397 ProgramList schedList(false); 369 398 schedList.FromScheduler(); 370 399 371 QMutexLocker lockit( reclist_lock);400 QMutexLocker lockit(cached_reclist_lock); 372 401 373 402 ProgramInfo *p; 374 403 for (p = schedList.first(); p; p = schedList.next()) 375 reclist.push_back(p);404 cached_reclist.push_back(p); 376 405 } 377 406 378 407 void Scheduler::PrintList(bool onlyFutureRecordings) … … 386 415 cout << "Title - Subtitle Chan ChID Day Start End " 387 416 "C I T N Pri" << endl; 388 417 389 RecIter i = reclist.begin();390 for ( ; i != reclist.end(); i++)418 RecIter i = cached_reclist.begin(); 419 for ( ; i != cached_reclist.end(); i++) 391 420 { 392 421 ProgramInfo *first = (*i); 393 422 … … 431 460 432 461 void Scheduler::UpdateRecStatus(ProgramInfo *pginfo) 433 462 { 434 QMutexLocker lockit( reclist_lock);463 QMutexLocker lockit(cached_reclist_lock); 435 464 436 RecIter dreciter = reclist.begin();437 for (; dreciter != reclist.end(); ++dreciter)465 RecIter dreciter = cached_reclist.begin(); 466 for (; dreciter != cached_reclist.end(); ++dreciter) 438 467 { 439 468 ProgramInfo *p = *dreciter; 440 469 if (p->IsSameProgramTimeslot(*pginfo)) … … 454 483 RecStatusType recstatus, 455 484 const QDateTime &recendts) 456 485 { 457 QMutexLocker lockit( reclist_lock);486 QMutexLocker lockit(cached_reclist_lock); 458 487 459 RecIter dreciter = reclist.begin();460 for (; dreciter != reclist.end(); ++dreciter)488 RecIter dreciter = cached_reclist.begin(); 489 for (; dreciter != cached_reclist.end(); ++dreciter) 461 490 { 462 491 ProgramInfo *p = *dreciter; 463 492 if (p->cardid == cardid && … … 513 542 514 543 void Scheduler::SlaveConnected(ProgramList &slavelist) 515 544 { 516 QMutexLocker lockit( reclist_lock);545 QMutexLocker lockit(cached_reclist_lock); 517 546 518 547 ProgramInfo *sp; 519 548 for (sp = slavelist.first(); sp; sp = slavelist.next()) 520 549 { 521 550 bool found = false; 522 551 523 RecIter ri = reclist.begin();524 for ( ; ri != reclist.end(); ri++)552 RecIter ri = cached_reclist.begin(); 553 for ( ; ri != cached_reclist.end(); ri++) 525 554 { 526 555 ProgramInfo *rp = *ri; 527 556 … … 559 588 560 589 if (sp->inputid && !found) 561 590 { 562 reclist.push_back(new ProgramInfo(*sp));591 cached_reclist.push_back(new ProgramInfo(*sp)); 563 592 sp->AddHistory(false); 564 593 VERBOSE(VB_IMPORTANT, QString("adding %1/%2/\"%3\" as recording") 565 594 .arg(sp->cardid).arg(sp->chansign).arg(sp->title)); … … 569 598 570 599 void Scheduler::SlaveDisconnected(int cardid) 571 600 { 572 QMutexLocker lockit( reclist_lock);601 QMutexLocker lockit(cached_reclist_lock); 573 602 574 RecIter ri = reclist.begin();575 for ( ; ri != reclist.end(); ri++)603 RecIter ri = cached_reclist.begin(); 604 for ( ; ri != cached_reclist.end(); ri++) 576 605 { 577 606 ProgramInfo *rp = *ri; 578 607 … … 895 924 } 896 925 } 897 926 898 voidScheduler::PruneRedundants(void)927 bool Scheduler::PruneRedundants(void) 899 928 { 900 929 ProgramInfo *lastp = NULL; 901 hasconflicts = false;930 bool hasconflicts = false; 902 931 903 932 RecIter i = reclist.begin(); 904 933 while (i != reclist.end()) … … 948 977 i = reclist.erase(i); 949 978 } 950 979 } 980 981 return hasconflicts; 951 982 } 952 983 953 984 void Scheduler::UpdateNextRecord(void) … … 955 986 QMap<int, QDateTime> nextRecMap; 956 987 QDateTime now = QDateTime::currentDateTime(); 957 988 958 RecIter i = reclist.begin();959 while (i != reclist.end())989 RecIter i = cached_reclist.begin(); 990 while (i != cached_reclist.end()) 960 991 { 961 992 ProgramInfo *p = *i; 962 993 if (p->recstartts > now && p->recstatus == rsWillRecord && … … 1007 1038 1008 1039 void Scheduler::getConflicting(ProgramInfo *pginfo, QStringList &strlist) 1009 1040 { 1010 QMutexLocker lockit( reclist_lock);1041 QMutexLocker lockit(cached_reclist_lock); 1011 1042 1012 1043 RecList *curList = getConflicting(pginfo); 1013 1044 … … 1022 1053 1023 1054 RecList *Scheduler::getConflicting(ProgramInfo *pginfo) 1024 1055 { 1025 QMutexLocker lockit( reclist_lock);1056 QMutexLocker lockit(cached_reclist_lock); 1026 1057 1027 1058 RecList *retlist = new RecList; 1028 1059 1029 RecIter i = reclist.begin();1030 for (; FindNextConflict( reclist, pginfo, i); i++)1060 RecIter i = cached_reclist.begin(); 1061 for (; FindNextConflict(cached_reclist, pginfo, i); i++) 1031 1062 { 1032 1063 ProgramInfo *p = *i; 1033 1064 retlist->push_back(p); … … 1038 1069 1039 1070 void Scheduler::getAllPending(RecList *retList) 1040 1071 { 1041 QMutexLocker lockit( reclist_lock);1072 QMutexLocker lockit(cached_reclist_lock); 1042 1073 1043 while (retList->size() > 0) 1044 { 1045 ProgramInfo *pginfo = retList->back(); 1046 delete pginfo; 1047 retList->pop_back(); 1048 } 1049 1050 RecIter i = reclist.begin(); 1051 for (; i != reclist.end(); i++) 1052 { 1053 ProgramInfo *p = *i; 1054 retList->push_back(new ProgramInfo(*p)); 1055 } 1074 copy_reclist(*retList, cached_reclist); 1056 1075 retList->sort(comp_timechannel); 1057 1076 } 1058 1077 1059 1078 void Scheduler::getAllPending(QStringList &strList) 1060 1079 { 1061 QMutexLocker lockit(reclist_lock); 1080 RecList retList; 1081 getAllPending(&retList); 1062 1082 1063 1083 strList << QString::number(hasconflicts); 1064 strList << QString::number(re clist.size());1084 strList << QString::number(retList.size()); 1065 1085 1066 RecList *retList = new RecList; 1086 for (RecIter it = retList.begin(); it != retList.end(); ++it) 1087 (*it)->ToStringList(strList); 1067 1088 1068 RecIter i = reclist.begin(); 1069 for (; i != reclist.end(); i++) 1070 { 1071 ProgramInfo *p = *i; 1072 retList->push_back(new ProgramInfo(*p)); 1073 } 1074 retList->sort(comp_timechannel); 1075 1076 for (i = retList->begin(); i != retList->end(); i++) 1077 { 1078 ProgramInfo *p = *i; 1079 p->ToStringList(strList); 1080 delete p; 1081 } 1082 1083 delete retList; 1089 delete_reclist(retList); 1084 1090 } 1085 1091 1086 1092 RecList *Scheduler::getAllScheduled(void) 1087 1093 { 1088 while (schedlist.size() > 0) 1089 { 1090 ProgramInfo *pginfo = schedlist.back(); 1091 delete pginfo; 1092 schedlist.pop_back(); 1093 } 1094 delete_reclist(schedlist); 1094 1095 1095 1096 findAllScheduledPrograms(schedlist); 1096 1097 … … 1122 1123 1123 1124 void Scheduler::AddRecording(const ProgramInfo &pi) 1124 1125 { 1125 QMutexLocker lockit( reclist_lock);1126 QMutexLocker lockit(cached_reclist_lock); 1126 1127 1127 1128 VERBOSE(VB_GENERAL, LOC + "AddRecording() recid: " << pi.recordid); 1128 1129 1129 for (RecIter it = reclist.begin(); it !=reclist.end(); ++it)1130 for (RecIter it = cached_reclist.begin(); it != cached_reclist.end(); ++it) 1130 1131 { 1131 1132 ProgramInfo *p = *it; 1132 1133 if (p->recstatus == rsRecording && p->IsSameProgramTimeslot(pi)) … … 1141 1142 QString("Adding '%1' to reclist.").arg(pi.title)); 1142 1143 1143 1144 ProgramInfo * new_pi = new ProgramInfo(pi); 1144 reclist.push_back(new_pi);1145 cached_reclist.push_back(new_pi); 1145 1146 1146 1147 // Save rsRecording recstatus to DB 1147 1148 // This allows recordings to resume on backend restart … … 1169 1170 1170 1171 QString recordfileprefix = gContext->GetFilePrefix(); 1171 1172 1172 RecIter startIter = reclist.begin();1173 RecIter startIter = cached_reclist.begin(); 1173 1174 1174 1175 bool blockShutdown = gContext->GetNumSetting("blockSDWUwithoutClient", 1); 1175 1176 QDateTime idleSince = QDateTime(); … … 1201 1202 curtime = QDateTime::currentDateTime(); 1202 1203 bool statuschanged = false; 1203 1204 1204 if ((startIter != reclist.end() &&1205 if ((startIter != cached_reclist.end() && 1205 1206 curtime.secsTo((*startIter)->recstartts) < 30)) 1206 1207 sleep(1); 1207 1208 else … … 1250 1251 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0; 1251 1252 1252 1253 msg.sprintf("Scheduled %d items in " 1253 "%.1f = %.2f match + %.2f place", (int)reclist.size(), 1254 "%.1f = %.2f match + %.2f place", 1255 (int)cached_reclist.size(), 1254 1256 matchTime + placeTime, matchTime, placeTime); 1255 1257 1256 1258 VERBOSE(VB_GENERAL, msg); 1257 1259 gContext->LogEntry("scheduler", LP_INFO, "Scheduled items", msg); 1258 1260 1259 1261 lastupdate = curtime; 1260 startIter = reclist.begin();1262 startIter = cached_reclist.begin(); 1261 1263 statuschanged = true; 1262 1264 1263 1265 // Determine if the user wants us to start recording early … … 1275 1277 QString startupParam = "user"; 1276 1278 1277 1279 // have we been started automatically? 1278 if ((startIter != reclist.end()) &&1280 if ((startIter != cached_reclist.end()) && 1279 1281 ((curtime.secsTo((*startIter)->startts) - prerollseconds) 1280 1282 < (idleWaitForRecordingTime * 60))) 1281 1283 { … … 1304 1306 } 1305 1307 } 1306 1308 1307 for ( ; startIter != reclist.end(); startIter++)1309 for ( ; startIter != cached_reclist.end(); startIter++) 1308 1310 if ((*startIter)->recstatus != (*startIter)->oldrecstatus) 1309 1311 break; 1310 1312 1311 1313 curtime = QDateTime::currentDateTime(); 1312 1314 1313 1315 RecIter recIter = startIter; 1314 for ( ; recIter != reclist.end(); recIter++)1316 for ( ; recIter != cached_reclist.end(); recIter++) 1315 1317 { 1316 1318 QString msg, details; 1317 1319 … … 1338 1340 .arg(nextRecording->title); 1339 1341 VERBOSE(VB_GENERAL, msg); 1340 1342 1341 QMutexLocker lockit( reclist_lock);1343 QMutexLocker lockit(cached_reclist_lock); 1342 1344 nextRecording->recstatus = rsTunerBusy; 1343 1345 nextRecording->AddHistory(true); 1344 1346 statuschanged = true; … … 1360 1362 .arg(nextRecording->sourceid) 1361 1363 .arg((long)nexttv->GetFreeDiskSpace(true)/1024); 1362 1364 VERBOSE(VB_GENERAL, msg); 1363 QMutexLocker lockit( reclist_lock);1365 QMutexLocker lockit(cached_reclist_lock); 1364 1366 nextRecording->recstatus = rsLowDiskSpace; 1365 1367 nextRecording->AddHistory(true); 1366 1368 statuschanged = true; … … 1378 1380 .arg(nextRecording->sourceid); 1379 1381 VERBOSE(VB_GENERAL, msg); 1380 1382 1381 QMutexLocker lockit( reclist_lock);1383 QMutexLocker lockit(cached_reclist_lock); 1382 1384 nextRecording->recstatus = rsTunerBusy; 1383 1385 nextRecording->AddHistory(true); 1384 1386 statuschanged = true; … … 1418 1420 nextRecording->recstartts.time().hour(), 1419 1421 nextRecording->recstartts.time().minute())); 1420 1422 1421 QMutexLocker lockit( reclist_lock);1423 QMutexLocker lockit(cached_reclist_lock); 1422 1424 1423 1425 QString subtitle = nextRecording->subtitle.isEmpty() ? "" : 1424 1426 QString(" \"%1\"").arg(nextRecording->subtitle); … … 1489 1491 { 1490 1492 if (!idleSince.isValid()) 1491 1493 { 1492 if (startIter != reclist.end())1494 if (startIter != cached_reclist.end()) 1493 1495 { 1494 1496 if (curtime.secsTo((*startIter)->startts) - 1495 1497 prerollseconds > idleWaitForRecordingTime * 60) … … 1609 1611 { 1610 1612 m_isShuttingDown = true; 1611 1613 1612 RecIter recIter = reclist.begin();1613 for ( ; recIter != reclist.end(); recIter++)1614 RecIter recIter = cached_reclist.begin(); 1615 for ( ; recIter != cached_reclist.end(); recIter++) 1614 1616 if ((*recIter)->recstatus == rsWillRecord) 1615 1617 break; 1616 1618 1617 1619 // set the wakeuptime if needed 1618 if (recIter != reclist.end())1620 if (recIter != cached_reclist.end()) 1619 1621 { 1620 1622 ProgramInfo *nextRecording = (*recIter); 1621 1623 QDateTime restarttime = nextRecording->startts.addSecs((-1) * … … 2617 2619 } 2618 2620 } 2619 2621 2622 static void delete_reclist(RecList &reclist) 2623 { 2624 while (reclist.size() > 0) 2625 { 2626 ProgramInfo *pginfo = reclist.back(); 2627 delete pginfo; 2628 reclist.pop_back(); 2629 } 2630 } 2631 2632 static void copy_reclist(RecList ©, const RecList &orig) 2633 { 2634 delete_reclist(copy); 2635 2636 RecList::const_iterator it = orig.begin(); 2637 for (; it != orig.end(); it++) 2638 copy.push_back(new ProgramInfo(*(*it))); 2639 } 2640 2620 2641 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
programs/mythbackend/scheduler.h
38 38 const QDateTime &startts, RecStatusType recstatus, 39 39 const QDateTime &recendts); 40 40 41 RecList *getAllPending(void) { return & reclist; }41 RecList *getAllPending(void) { return &cached_reclist; } 42 42 void getAllPending(RecList *retList); 43 43 void getAllPending(QStringList &strList); 44 44 … … 89 89 bool TryAnotherShowing(ProgramInfo *p); 90 90 void SchedNewRecords(void); 91 91 void MoveHigherRecords(void); 92 voidPruneRedundants(void);92 bool PruneRedundants(void); 93 93 void UpdateNextRecord(void); 94 94 95 95 bool ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp); … … 104 104 QMutex reschedLock; 105 105 QMutex recordmatchLock; 106 106 QWaitCondition reschedWait; 107 108 RecList cached_reclist; 109 RecList schedlist; 110 111 QMutex *cached_reclist_lock; 112 QMutex *schedlist_lock; 113 114 // temporaries used in scheduler 107 115 RecList reclist; 108 116 RecList retrylist; 109 RecList schedlist;110 117 QMap<int, RecList> cardlistmap; 111 118 QMap<int, RecList> recordidlistmap; 112 119 QMap<QString, RecList> titlelistmap; 113 120 114 QMutex *reclist_lock;115 QMutex *schedlist_lock;116 117 121 bool specsched; 118 122 bool hasconflicts; 119 123 bool schedMoveHigher;