Ticket #2282: 2282-v5.patch
File 2282-v5.patch, 20.2 KB (added by , 18 years ago) |
---|
-
programs/mythbackend/scheduler.cpp
76 76 } 77 77 } 78 78 79 Scheduler::~Scheduler()79 static void delete_reclist(RecList &reclist) 80 80 { 81 81 while (reclist.size() > 0) 82 82 { … … 86 86 } 87 87 } 88 88 89 static void copy_reclist(RecList ©, const RecList &orig) 90 { 91 delete_reclist(copy); 92 93 RecList::const_iterator it = orig.begin(); 94 for (; it != orig.end(); it++) 95 copy.push_back(new ProgramInfo(*(*it))); 96 } 97 98 Scheduler::~Scheduler() 99 { 100 delete_reclist(reclist); 101 102 if (reclist_lock) 103 { 104 delete reclist_lock; 105 reclist_lock = NULL; 106 } 107 108 if (schedlist_lock) 109 { 110 delete schedlist_lock; 111 schedlist_lock = NULL; 112 } 113 } 114 89 115 void Scheduler::SetMainServer(MainServer *ms) 90 116 { 91 117 m_mainServer = ms; … … 263 289 264 290 bool Scheduler::FillRecordList(void) 265 291 { 266 QMutexLocker lockit(reclist_lock);267 268 292 schedMoveHigher = (bool)gContext->GetNumSetting("SchedMoveHigher"); 269 293 schedTime = QDateTime::currentDateTime(); 270 294 271 VERBOSE(VB_SCHEDULE, "PruneOldRecords..."); 272 PruneOldRecords(); 273 VERBOSE(VB_SCHEDULE, "AddNewRecords..."); 274 AddNewRecords(); 275 VERBOSE(VB_SCHEDULE, "AddNotListed..."); 276 AddNotListed(); 295 RecList newlist; 277 296 297 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locking 1"); 298 reclist_lock->lock(); 299 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locked 1"); 300 301 copy_reclist(newlist, reclist); 302 303 reclist_lock->unlock(); 304 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- unlocked 1"); 305 306 PruneOldRecords(newlist); 307 AddNewRecords(dbConn, recordTable, specsched, threadrunning, 308 *m_tvList, newlist); 309 AddNotListed(dbConn, recordTable, newlist); 310 278 311 VERBOSE(VB_SCHEDULE, "Sort by time..."); 279 reclist.sort(comp_overlap);280 VERBOSE(VB_SCHEDULE, "PruneOverlaps...");281 PruneOverlaps( );282 312 newlist.sort(comp_overlap); 313 314 PruneOverlaps(newlist); 315 283 316 VERBOSE(VB_SCHEDULE, "Sort by priority..."); 284 reclist.sort(comp_priority); 285 VERBOSE(VB_SCHEDULE, "BuildListMaps..."); 286 BuildListMaps(); 287 VERBOSE(VB_SCHEDULE, "SchedNewRecords..."); 288 SchedNewRecords(); 289 VERBOSE(VB_SCHEDULE, "ClearListMaps..."); 290 ClearListMaps(); 317 newlist.sort(comp_priority); 318 319 { 320 QMap<int, RecList> cardlistmap; 321 QMap<int, RecList> recordidlistmap; 322 QMap<QString, RecList> titlelistmap; 323 324 BuildListMaps(newlist, cardlistmap, recordidlistmap, titlelistmap); 291 325 326 RecList retrylist; 327 SchedNewRecords(schedMoveHigher, newlist, retrylist, 328 cardlistmap, recordidlistmap, titlelistmap); 329 } 330 292 331 VERBOSE(VB_SCHEDULE, "Sort by time..."); 293 reclist.sort(comp_redundant);294 VERBOSE(VB_SCHEDULE, "PruneRedundants...");295 PruneRedundants();332 newlist.sort(comp_redundant); 333 334 bool will_have_conflicts = PruneRedundants(newlist); 296 335 297 336 VERBOSE(VB_SCHEDULE, "Sort by time..."); 298 reclist.sort(comp_recstart); 337 newlist.sort(comp_recstart); 338 339 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locking"); 340 reclist_lock->lock(); 341 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locked"); 299 342 343 copy_reclist(reclist, newlist); 344 hasconflicts = will_have_conflicts; 345 346 reclist_lock->unlock(); 347 VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- unlocked"); 348 349 delete_reclist(newlist); 350 300 351 return hasconflicts; 301 352 } 302 353 … … 476 527 } 477 528 } 478 529 479 bool Scheduler::ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp) 530 bool Scheduler::ChangeRecordingEnd(const bool specsched, 531 QMap<int, EncoderLink*> &tvList, 532 ProgramInfo *oldp, 533 ProgramInfo *newp) 480 534 { 481 535 RecordingType oldrectype = oldp->rectype; 482 536 int oldrecordid = oldp->recordid; … … 497 551 else 498 552 return true; 499 553 } 500 EncoderLink *tv = (*m_tvList)[oldp->cardid];554 EncoderLink *tv = tvList[oldp->cardid]; 501 555 RecStatusType rs = tv->StartRecording(oldp); 502 556 if (rs != rsRecording) 503 557 { … … 587 641 } 588 642 } 589 643 590 void Scheduler::PruneOldRecords( void)644 void Scheduler::PruneOldRecords(RecList &reclist) 591 645 { 646 VERBOSE(VB_SCHEDULE, "PruneOldRecords..."); 592 647 RecIter dreciter = reclist.begin(); 593 648 while (dreciter != reclist.end()) 594 649 { … … 607 662 } 608 663 } 609 664 610 void Scheduler::PruneOverlaps( void)665 void Scheduler::PruneOverlaps(RecList &reclist) 611 666 { 667 VERBOSE(VB_SCHEDULE, "PruneOverlaps..."); 612 668 ProgramInfo *lastp = NULL; 613 669 614 670 RecIter dreciter = reclist.begin(); … … 648 704 } 649 705 } 650 706 651 void Scheduler::BuildListMaps(void) 707 void Scheduler::BuildListMaps(RecList &reclist, 708 QMap<int, RecList> &cardlistmap, 709 QMap<int, RecList> &recordidlistmap, 710 QMap<QString, RecList> &titlelistmap) 652 711 { 712 VERBOSE(VB_SCHEDULE, "BuildListMaps..."); 653 713 RecIter i = reclist.begin(); 654 714 for ( ; i != reclist.end(); i++) 655 715 { … … 665 725 } 666 726 } 667 727 668 void Scheduler::ClearListMaps(void)669 {670 cardlistmap.clear();671 titlelistmap.clear();672 recordidlistmap.clear();673 }674 675 728 bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j) 676 729 { 677 730 for ( ; j != cardlist.end(); j++) … … 695 748 return false; 696 749 } 697 750 698 void Scheduler::MarkOtherShowings(ProgramInfo *p) 751 void Scheduler::MarkOtherShowings(ProgramInfo *p, 752 QMap<int, RecList> &recordidlistmap, 753 QMap<QString, RecList> &titlelistmap) 699 754 { 700 755 RecList *showinglist = &titlelistmap[p->title]; 701 756 … … 743 798 } 744 799 } 745 800 746 void Scheduler::BackupRecStatus( void)801 void Scheduler::BackupRecStatus(RecList &reclist) 747 802 { 748 803 RecIter i = reclist.begin(); 749 804 for ( ; i != reclist.end(); i++) … … 753 808 } 754 809 } 755 810 756 void Scheduler::RestoreRecStatus( void)811 void Scheduler::RestoreRecStatus(RecList &reclist) 757 812 { 758 813 RecIter i = reclist.begin(); 759 814 for ( ; i != reclist.end(); i++) … … 763 818 } 764 819 } 765 820 766 bool Scheduler::TryAnotherShowing(ProgramInfo *p) 821 bool Scheduler::TryAnotherShowing(QMap<int, RecList> &cardlistmap, 822 QMap<QString, RecList> &titlelistmap, 823 QMap<int, RecList> &recordidlistmap, 824 ProgramInfo *p) 767 825 { 768 826 PrintRec(p, " >"); 769 827 … … 812 870 } 813 871 814 872 q->recstatus = rsWillRecord; 815 MarkOtherShowings(q );873 MarkOtherShowings(q, recordidlistmap, titlelistmap); 816 874 PrintRec(p, " -"); 817 875 PrintRec(q, " +"); 818 876 return true; … … 822 880 return false; 823 881 } 824 882 825 void Scheduler::SchedNewRecords(void) 883 void Scheduler::SchedNewRecords(const bool schedMoveHigher, 884 RecList &reclist, 885 RecList &retrylist, 886 QMap<int, RecList> &cardlistmap, 887 QMap<int, RecList> &recordidlistmap, 888 QMap<QString, RecList> &titlelistmap) 826 889 { 827 890 VERBOSE(VB_SCHEDULE, "Scheduling:"); 828 891 … … 831 894 { 832 895 ProgramInfo *p = *i; 833 896 if (p->recstatus == rsRecording) 834 MarkOtherShowings(p );897 MarkOtherShowings(p, recordidlistmap, titlelistmap); 835 898 else if (p->recstatus == rsUnknown) 836 899 { 837 900 RecList &cardlist = cardlistmap[p->cardid]; … … 839 902 if (!FindNextConflict(cardlist, p, k)) 840 903 { 841 904 p->recstatus = rsWillRecord; 842 MarkOtherShowings(p );905 MarkOtherShowings(p, recordidlistmap, titlelistmap); 843 906 PrintRec(p, " +"); 844 907 } 845 908 else … … 854 917 i++; 855 918 if (i == reclist.end() || lastpri != (*i)->recpriority) 856 919 { 857 MoveHigherRecords(); 920 MoveHigherRecords(schedMoveHigher, reclist, retrylist, 921 cardlistmap, recordidlistmap, titlelistmap); 858 922 retrylist.clear(); 859 923 } 860 924 } 861 925 } 862 926 863 void Scheduler::MoveHigherRecords(void) 927 void Scheduler::MoveHigherRecords(const bool schedMoveHigher, 928 RecList &reclist, 929 RecList &retrylist, 930 QMap<int, RecList> &cardlistmap, 931 QMap<int, RecList> &recordidlistmap, 932 QMap<QString, RecList> &titlelistmap) 864 933 { 865 934 RecIter i = retrylist.begin(); 866 935 for ( ; i != retrylist.end(); i++) … … 871 940 872 941 PrintRec(p, " ?"); 873 942 874 if (TryAnotherShowing( p))943 if (TryAnotherShowing(cardlistmap, titlelistmap, recordidlistmap, p)) 875 944 continue; 876 945 877 BackupRecStatus( );946 BackupRecStatus(reclist); 878 947 p->recstatus = rsWillRecord; 879 MarkOtherShowings(p );948 MarkOtherShowings(p, recordidlistmap, titlelistmap); 880 949 881 950 RecList &cardlist = cardlistmap[p->cardid]; 882 951 RecIter k = cardlist.begin(); 883 952 for ( ; FindNextConflict(cardlist, p, k); k++) 884 953 { 885 954 if ((p->recpriority < (*k)->recpriority && !schedMoveHigher) || 886 !TryAnotherShowing(*k)) 955 !TryAnotherShowing(cardlistmap, titlelistmap, 956 recordidlistmap, *k)) 887 957 { 888 RestoreRecStatus( );958 RestoreRecStatus(reclist); 889 959 break; 890 960 } 891 961 } … … 895 965 } 896 966 } 897 967 898 void Scheduler::PruneRedundants(void)968 bool Scheduler::PruneRedundants(RecList &reclist) 899 969 { 970 VERBOSE(VB_SCHEDULE, "PruneRedundants..."); 900 971 ProgramInfo *lastp = NULL; 901 hasconflicts = false;972 bool hasconflicts = false; 902 973 903 974 RecIter i = reclist.begin(); 904 975 while (i != reclist.end()) … … 948 1019 i = reclist.erase(i); 949 1020 } 950 1021 } 1022 1023 return hasconflicts; 951 1024 } 952 1025 953 void Scheduler::UpdateNextRecord(void) 1026 void Scheduler::UpdateNextRecord(MSqlQueryInfo &dbConn, 1027 RecList &reclist) 954 1028 { 955 if (specsched) 956 return; 957 1029 VERBOSE(VB_SCHEDULE, "UpdateNextRecord..."); 958 1030 QMap<int, QDateTime> nextRecMap; 959 1031 960 1032 RecIter i = reclist.begin(); … … 1041 1113 { 1042 1114 QMutexLocker lockit(reclist_lock); 1043 1115 1044 while (retList->size() > 0) 1045 { 1046 ProgramInfo *pginfo = retList->back(); 1047 delete pginfo; 1048 retList->pop_back(); 1049 } 1050 1051 RecIter i = reclist.begin(); 1052 for (; i != reclist.end(); i++) 1053 { 1054 ProgramInfo *p = *i; 1055 retList->push_back(new ProgramInfo(*p)); 1056 } 1116 copy_reclist(*retList, reclist); 1057 1117 retList->sort(comp_timechannel); 1058 1118 } 1059 1119 1060 1120 void Scheduler::getAllPending(QStringList &strList) 1061 1121 { 1062 QMutexLocker lockit(reclist_lock); 1122 RecList retList; 1123 getAllPending(&retList); 1063 1124 1064 1125 strList << QString::number(hasconflicts); 1065 strList << QString::number(re clist.size());1126 strList << QString::number(retList.size()); 1066 1127 1067 RecList *retList = new RecList; 1128 for (RecIter it = retList.begin(); it != retList.end(); ++it) 1129 (*it)->ToStringList(strList); 1068 1130 1069 RecIter i = reclist.begin(); 1070 for (; i != reclist.end(); i++) 1071 { 1072 ProgramInfo *p = *i; 1073 retList->push_back(new ProgramInfo(*p)); 1074 } 1075 retList->sort(comp_timechannel); 1076 1077 for (i = retList->begin(); i != retList->end(); i++) 1078 { 1079 ProgramInfo *p = *i; 1080 p->ToStringList(strList); 1081 delete p; 1082 } 1083 1084 delete retList; 1131 delete_reclist(retList); 1085 1132 } 1086 1133 1087 1134 RecList *Scheduler::getAllScheduled(void) 1088 1135 { 1089 while (schedlist.size() > 0) 1090 { 1091 ProgramInfo *pginfo = schedlist.back(); 1092 delete pginfo; 1093 schedlist.pop_back(); 1094 } 1136 delete_reclist(schedlist); 1095 1137 1096 1138 findAllScheduledPrograms(schedlist); 1097 1139 … … 1244 1286 gettimeofday(&fillstart, NULL); 1245 1287 FillRecordList(); 1246 1288 gettimeofday(&fillend, NULL); 1247 UpdateNextRecord(); 1289 if (!specsched) 1290 UpdateNextRecord(dbConn, reclist); 1248 1291 PrintList(); 1249 1292 1250 1293 placeTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 + … … 1452 1495 VERBOSE(VB_GENERAL, msg << ": " << details); 1453 1496 gContext->LogEntry("scheduler", LP_NOTICE, msg, details); 1454 1497 1455 if (is_rec )1456 UpdateNextRecord( );1498 if (is_rec && specsched) 1499 UpdateNextRecord(dbConn, reclist); 1457 1500 1458 1501 if (nextRecording->recstatus == rsFailed) 1459 1502 { … … 2010 2053 VERBOSE(VB_SCHEDULE, " +-- Done."); 2011 2054 } 2012 2055 2013 void Scheduler::AddNewRecords(void) 2056 void Scheduler::AddNewRecords(MSqlQueryInfo &dbConn, 2057 const QString &recordTable, 2058 const bool specsched, 2059 const bool threadrunning, 2060 QMap<int, EncoderLink*> &tvList, 2061 RecList &reclist) 2014 2062 { 2063 VERBOSE(VB_SCHEDULE, "AddNewRecords..."); 2015 2064 struct timeval dbstart, dbend; 2016 2065 2017 2066 QMap<RecordingType, int> recTypeRecPriorityMap; … … 2024 2073 int ccpriority = gContext->GetNumSetting("CCRecPriority", 0); 2025 2074 2026 2075 QMap<int, bool> cardMap; 2027 QMap<int, EncoderLink *>::Iterator enciter = m_tvList->begin();2028 for (; enciter != m_tvList->end(); ++enciter)2076 QMap<int, EncoderLink *>::Iterator enciter = tvList.begin(); 2077 for (; enciter != tvList.end(); ++enciter) 2029 2078 { 2030 2079 EncoderLink *enc = enciter.data(); 2031 2080 if (enc->IsConnected()) … … 2335 2384 r->recendts != p->recendts && 2336 2385 (r->recordid == p->recordid || 2337 2386 p->rectype == kOverrideRecord)) 2338 ChangeRecordingEnd(r, p); 2387 { 2388 ChangeRecordingEnd(specsched, tvList, r, p); 2389 } 2339 2390 delete p; 2340 2391 p = NULL; 2341 2392 break; … … 2392 2443 reclist.push_back(*tmp); 2393 2444 } 2394 2445 2395 void Scheduler::AddNotListed(void) { 2396 2446 void Scheduler::AddNotListed(MSqlQueryInfo &dbConn, 2447 const QString &recordTable, 2448 RecList &reclist) 2449 { 2450 VERBOSE(VB_SCHEDULE, "AddNotListed..."); 2397 2451 struct timeval dbstart, dbend; 2398 2452 RecList tmpList; 2399 2453 -
programs/mythbackend/scheduler.h
49 49 RecList *getConflicting(ProgramInfo *pginfo); 50 50 51 51 void PrintList(bool onlyFutureRecordings = false); 52 void PrintRec(ProgramInfo *p, const char *prefix = NULL);52 static void PrintRec(ProgramInfo *p, const char *prefix = NULL); 53 53 54 54 bool HasConflicts(void) { return hasconflicts; } 55 55 … … 66 66 static void *SchedulerThread(void *param); 67 67 68 68 private: 69 QString recordTable;70 71 69 void verifyCards(void); 72 70 73 71 bool FillRecordList(void); 74 72 void UpdateMatches(int recordid); 75 73 void UpdateManuals(int recordid); 76 void PruneOldRecords(void);77 void AddNewRecords(void);78 void AddNotListed(void);79 74 void BuildNewRecordsQueries(int recordid, QStringList &from, QStringList &where, 80 75 MSqlBindings &bindings); 81 void PruneOverlaps(void);82 void BuildListMaps(void);83 void ClearListMaps(void);84 bool FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &iter);85 void MarkOtherShowings(ProgramInfo *p);86 void MarkShowingsList(RecList &showinglist, ProgramInfo *p);87 void BackupRecStatus(void);88 void RestoreRecStatus(void);89 bool TryAnotherShowing(ProgramInfo *p);90 void SchedNewRecords(void);91 void MoveHigherRecords(void);92 void PruneRedundants(void);93 void UpdateNextRecord(void);94 76 95 bool ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp);96 97 77 void findAllScheduledPrograms(list<ProgramInfo *> &proglist); 98 78 bool CheckShutdownServer(int prerollseconds, QDateTime &idleSince, 99 79 bool &blockShutdown); 100 80 void ShutdownServer(int prerollseconds); 101 81 82 // statics 83 static void PruneOldRecords(RecList &reclist); 84 static void AddNewRecords(MSqlQueryInfo &dbConn, 85 const QString &recordTable, 86 bool specsched, 87 bool threadrunning, 88 QMap<int, EncoderLink*> &tvList, 89 RecList &reclist); 90 static void AddNotListed(MSqlQueryInfo &dbConn, 91 const QString &recordTable, 92 RecList &reclist); 93 static void PruneOverlaps(RecList &reclist); 94 static void BuildListMaps(RecList &reclist, 95 QMap<int, RecList> &cardlistmap, 96 QMap<int, RecList> &recordidlistmap, 97 QMap<QString, RecList> &titlelistmap); 98 static bool FindNextConflict(RecList &cardlist, 99 ProgramInfo *p, 100 RecIter &iter); 101 static void MarkOtherShowings(ProgramInfo *p, 102 QMap<int, RecList> &recordidlistmap, 103 QMap<QString, RecList> &titlelistmap); 104 static void MarkShowingsList(RecList &showinglist, 105 ProgramInfo *p); 106 static void BackupRecStatus(RecList &reclist); 107 static void RestoreRecStatus(RecList &reclist); 108 static bool TryAnotherShowing(QMap<int, RecList> &cardlistmap, 109 QMap<QString, RecList> &titlelistmap, 110 QMap<int, RecList> &recordidlistmap, 111 ProgramInfo *p); 112 static void SchedNewRecords(bool schedMoveHigher, 113 RecList &reclist, 114 RecList &retrylist, 115 QMap<int, RecList> &cardlistmap, 116 QMap<int, RecList> &recordidlistmap, 117 QMap<QString, RecList> &titlelistmap); 118 static void MoveHigherRecords(bool schedMoveHigher, 119 RecList &reclist, 120 RecList &retrylist, 121 QMap<int, RecList> &cardlistmap, 122 QMap<int, RecList> &recordidlistmap, 123 QMap<QString, RecList> &titlelistmap); 124 static bool PruneRedundants(RecList &reclist); 125 static void UpdateNextRecord(MSqlQueryInfo &dbConn, 126 RecList &reclist); 127 static bool ChangeRecordingEnd(bool specsched, 128 QMap<int, EncoderLink*> &tvList, 129 ProgramInfo *oldp, 130 ProgramInfo *newp); 102 131 132 private: 133 QString recordTable; 103 134 QValueList<int> reschedQueue; 104 135 QMutex reschedLock; 105 136 QMutex recordmatchLock; 106 137 QWaitCondition reschedWait; 107 138 RecList reclist; 108 RecList retrylist;109 139 RecList schedlist; 110 QMap<int, RecList> cardlistmap;111 QMap<int, RecList> recordidlistmap;112 QMap<QString, RecList> titlelistmap;113 140 114 141 QMutex *reclist_lock; 115 142 QMutex *schedlist_lock;