Ticket #2282: 2282-v4.patch

File 2282-v4.patch, 19.8 KB (added by danielk, 14 years ago)

Updated version of original patch (with static functions)

  • programs/mythbackend/scheduler.cpp

     
    7676    }
    7777}
    7878
    79 Scheduler::~Scheduler()
     79static void delete_reclist(RecList &reclist)
    8080{
    8181    while (reclist.size() > 0)
    8282    {
     
    8686    }
    8787}
    8888
     89static void copy_reclist(RecList &copy, 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
     98Scheduler::~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
    89115void Scheduler::SetMainServer(MainServer *ms)
    90116{
    91117    m_mainServer = ms;
     
    263289
    264290bool Scheduler::FillRecordList(void)
    265291{
    266     QMutexLocker lockit(reclist_lock);
    267 
    268292    schedMoveHigher = (bool)gContext->GetNumSetting("SchedMoveHigher");
    269293    schedTime = QDateTime::currentDateTime();
    270294
    271     VERBOSE(VB_SCHEDULE, "PruneOldRecords...");
    272     PruneOldRecords();
    273     VERBOSE(VB_SCHEDULE, "AddNewRecords...");
    274     AddNewRecords();
    275     VERBOSE(VB_SCHEDULE, "AddNotListed...");
    276     AddNotListed();
     295    RecList newlist;
    277296
     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 
    278311    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 
    283316    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);
    291325
     326        RecList retrylist;
     327        SchedNewRecords(schedMoveHigher, newlist, retrylist,
     328                        cardlistmap, recordidlistmap, titlelistmap);
     329    }
     330
    292331    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);
    296335
    297336    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");
    299342
     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
    300351    return hasconflicts;
    301352}
    302353
     
    476527    }
    477528}
    478529
    479 bool Scheduler::ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp)
     530bool Scheduler::ChangeRecordingEnd(const bool specsched,
     531                                   QMap<int, EncoderLink*> &tvList,
     532                                   ProgramInfo *oldp,
     533                                   ProgramInfo *newp)
    480534{
    481535    RecordingType oldrectype = oldp->rectype;
    482536    int oldrecordid = oldp->recordid;
     
    497551        else
    498552            return true;
    499553    }
    500     EncoderLink *tv = (*m_tvList)[oldp->cardid];
     554    EncoderLink *tv = tvList[oldp->cardid];
    501555    RecStatusType rs = tv->StartRecording(oldp);
    502556    if (rs != rsRecording)
    503557    {
     
    587641    }
    588642}
    589643
    590 void Scheduler::PruneOldRecords(void)
     644void Scheduler::PruneOldRecords(RecList &reclist)
    591645{
     646    VERBOSE(VB_SCHEDULE, "PruneOldRecords...");
    592647    RecIter dreciter = reclist.begin();
    593648    while (dreciter != reclist.end())
    594649    {
     
    607662    }
    608663}
    609664
    610 void Scheduler::PruneOverlaps(void)
     665void Scheduler::PruneOverlaps(RecList &reclist)
    611666{
     667    VERBOSE(VB_SCHEDULE, "PruneOverlaps...");
    612668    ProgramInfo *lastp = NULL;
    613669
    614670    RecIter dreciter = reclist.begin();
     
    648704    }
    649705}
    650706
    651 void Scheduler::BuildListMaps(void)
     707void Scheduler::BuildListMaps(RecList                &reclist,
     708                              QMap<int, RecList>     &cardlistmap,
     709                              QMap<int, RecList>     &recordidlistmap,
     710                              QMap<QString, RecList> &titlelistmap)
    652711{
     712    VERBOSE(VB_SCHEDULE, "BuildListMaps...");
    653713    RecIter i = reclist.begin();
    654714    for ( ; i != reclist.end(); i++)
    655715    {
     
    665725    }
    666726}
    667727
    668 void Scheduler::ClearListMaps(void)
    669 {
    670     cardlistmap.clear();
    671     titlelistmap.clear();
    672     recordidlistmap.clear();
    673 }
    674 
    675728bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j)
    676729{
    677730    for ( ; j != cardlist.end(); j++)
     
    695748    return false;
    696749}
    697750
    698 void Scheduler::MarkOtherShowings(ProgramInfo *p)
     751void Scheduler::MarkOtherShowings(ProgramInfo *p,
     752                                  QMap<int, RecList>     &recordidlistmap,
     753                                  QMap<QString, RecList> &titlelistmap)
    699754{
    700755    RecList *showinglist = &titlelistmap[p->title];
    701756
     
    743798    }
    744799}
    745800
    746 void Scheduler::BackupRecStatus(void)
     801void Scheduler::BackupRecStatus(RecList &reclist)
    747802{
    748803    RecIter i = reclist.begin();
    749804    for ( ; i != reclist.end(); i++)
     
    753808    }
    754809}
    755810
    756 void Scheduler::RestoreRecStatus(void)
     811void Scheduler::RestoreRecStatus(RecList &reclist)
    757812{
    758813    RecIter i = reclist.begin();
    759814    for ( ; i != reclist.end(); i++)
     
    763818    }
    764819}
    765820
    766 bool Scheduler::TryAnotherShowing(ProgramInfo *p)
     821bool Scheduler::TryAnotherShowing(QMap<int, RecList>     &cardlistmap,
     822                                  QMap<QString, RecList> &titlelistmap,
     823                                  QMap<int, RecList>     &recordidlistmap,
     824                                  ProgramInfo *p)
    767825{
    768826    PrintRec(p, "     >");
    769827
     
    812870        }
    813871
    814872        q->recstatus = rsWillRecord;
    815         MarkOtherShowings(q);
     873        MarkOtherShowings(q, recordidlistmap, titlelistmap);
    816874        PrintRec(p, "     -");
    817875        PrintRec(q, "     +");
    818876        return true;
     
    822880    return false;
    823881}
    824882
    825 void Scheduler::SchedNewRecords(void)
     883void 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)
    826889{
    827890    VERBOSE(VB_SCHEDULE, "Scheduling:");
    828891
     
    831894    {
    832895        ProgramInfo *p = *i;
    833896        if (p->recstatus == rsRecording)
    834             MarkOtherShowings(p);
     897            MarkOtherShowings(p, recordidlistmap, titlelistmap);
    835898        else if (p->recstatus == rsUnknown)
    836899        {
    837900            RecList &cardlist = cardlistmap[p->cardid];
     
    839902            if (!FindNextConflict(cardlist, p, k))
    840903            {
    841904                p->recstatus = rsWillRecord;
    842                 MarkOtherShowings(p);
     905                MarkOtherShowings(p, recordidlistmap, titlelistmap);
    843906                PrintRec(p, "  +");
    844907            }
    845908            else
     
    854917        i++;
    855918        if (i == reclist.end() || lastpri != (*i)->recpriority)
    856919        {
    857             MoveHigherRecords();
     920            MoveHigherRecords(schedMoveHigher, reclist, retrylist,
     921                              cardlistmap, recordidlistmap, titlelistmap);
    858922            retrylist.clear();
    859923        }
    860924    }
    861925}
    862926
    863 void Scheduler::MoveHigherRecords(void)
     927void 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)
    864933{
    865934    RecIter i = retrylist.begin();
    866935    for ( ; i != retrylist.end(); i++)
     
    871940
    872941        PrintRec(p, "  ?");
    873942
    874         if (TryAnotherShowing(p))
     943        if (TryAnotherShowing(cardlistmap, titlelistmap, recordidlistmap, p))
    875944            continue;
    876945
    877         BackupRecStatus();
     946        BackupRecStatus(reclist);
    878947        p->recstatus = rsWillRecord;
    879         MarkOtherShowings(p);
     948        MarkOtherShowings(p, recordidlistmap, titlelistmap);
    880949
    881950        RecList &cardlist = cardlistmap[p->cardid];
    882951        RecIter k = cardlist.begin();
    883952        for ( ; FindNextConflict(cardlist, p, k); k++)
    884953        {
    885954            if ((p->recpriority < (*k)->recpriority && !schedMoveHigher) ||
    886                 !TryAnotherShowing(*k))
     955                !TryAnotherShowing(cardlistmap, titlelistmap,
     956                                   recordidlistmap, *k))
    887957            {
    888                 RestoreRecStatus();
     958                RestoreRecStatus(reclist);
    889959                break;
    890960            }
    891961        }
     
    895965    }
    896966}
    897967
    898 void Scheduler::PruneRedundants(void)
     968bool Scheduler::PruneRedundants(RecList &reclist)
    899969{
     970    VERBOSE(VB_SCHEDULE, "PruneRedundants...");
    900971    ProgramInfo *lastp = NULL;
    901     hasconflicts = false;
     972    bool hasconflicts = false;
    902973
    903974    RecIter i = reclist.begin();
    904975    while (i != reclist.end())
     
    9481019            i = reclist.erase(i);
    9491020        }
    9501021    }
     1022
     1023    return hasconflicts;
    9511024}
    9521025
    953 void Scheduler::UpdateNextRecord(void)
     1026void Scheduler::UpdateNextRecord(MSqlQueryInfo &dbConn,
     1027                                 RecList       &reclist)
    9541028{
     1029    VERBOSE(VB_SCHEDULE, "UpdateNextRecord...");
    9551030    QMap<int, QDateTime> nextRecMap;
    9561031    QDateTime now = QDateTime::currentDateTime();
    9571032
     
    10401115{
    10411116    QMutexLocker lockit(reclist_lock);
    10421117
    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     }
     1118    copy_reclist(*retList, reclist);
    10561119    retList->sort(comp_timechannel);
    10571120}
    10581121
    10591122void Scheduler::getAllPending(QStringList &strList)
    10601123{
    1061     QMutexLocker lockit(reclist_lock);
     1124    RecList retList;
     1125    getAllPending(&retList);
    10621126
    10631127    strList << QString::number(hasconflicts);
    1064     strList << QString::number(reclist.size());
     1128    strList << QString::number(retList.size());
    10651129
    1066     RecList *retList = new RecList;
     1130    for (RecIter it = retList.begin(); it != retList.end(); ++it)
     1131        (*it)->ToStringList(strList);
    10671132
    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;
     1133    delete_reclist(retList);
    10841134}
    10851135
    10861136RecList *Scheduler::getAllScheduled(void)
    10871137{
    1088     while (schedlist.size() > 0)
    1089     {
    1090         ProgramInfo *pginfo = schedlist.back();
    1091         delete pginfo;
    1092         schedlist.pop_back();
    1093     }
     1138    delete_reclist(schedlist);
    10941139
    10951140    findAllScheduledPrograms(schedlist);
    10961141
     
    12431288            gettimeofday(&fillstart, NULL);
    12441289            FillRecordList();
    12451290            gettimeofday(&fillend, NULL);
    1246             UpdateNextRecord();
     1291            UpdateNextRecord(dbConn, reclist);
    12471292            PrintList();
    12481293
    12491294            placeTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 +
     
    20062051    VERBOSE(VB_SCHEDULE, " +-- Done.");
    20072052}
    20082053
    2009 void Scheduler::AddNewRecords(void)
     2054void Scheduler::AddNewRecords(MSqlQueryInfo           &dbConn,
     2055                              const QString           &recordTable,
     2056                              const bool               specsched,
     2057                              const bool               threadrunning,
     2058                              QMap<int, EncoderLink*> &tvList,
     2059                              RecList                 &reclist)
    20102060{
     2061    VERBOSE(VB_SCHEDULE, "AddNewRecords...");
    20112062    struct timeval dbstart, dbend;
    20122063
    20132064    QMap<RecordingType, int> recTypeRecPriorityMap;
     
    20202071    int ccpriority      = gContext->GetNumSetting("CCRecPriority", 0);
    20212072
    20222073    QMap<int, bool> cardMap;
    2023     QMap<int, EncoderLink *>::Iterator enciter = m_tvList->begin();
    2024     for (; enciter != m_tvList->end(); ++enciter)
     2074    QMap<int, EncoderLink *>::Iterator enciter = tvList.begin();
     2075    for (; enciter != tvList.end(); ++enciter)
    20252076    {
    20262077        EncoderLink *enc = enciter.data();
    20272078        if (enc->IsConnected())
     
    23312382                    r->recendts != p->recendts &&
    23322383                    (r->recordid == p->recordid ||
    23332384                     p->rectype == kOverrideRecord))
    2334                     ChangeRecordingEnd(r, p);
     2385                {
     2386                    ChangeRecordingEnd(specsched, tvList, r, p);
     2387                }
    23352388                delete p;
    23362389                p = NULL;
    23372390                break;
     
    23882441        reclist.push_back(*tmp);
    23892442}
    23902443
    2391 void Scheduler::AddNotListed(void) {
    2392 
     2444void Scheduler::AddNotListed(MSqlQueryInfo &dbConn,
     2445                             const QString &recordTable,
     2446                             RecList       &reclist)
     2447{
     2448    VERBOSE(VB_SCHEDULE, "AddNotListed...");
    23932449    struct timeval dbstart, dbend;
    23942450    RecList tmpList;
    23952451
  • programs/mythbackend/scheduler.h

     
    4949    RecList *getConflicting(ProgramInfo *pginfo);
    5050
    5151    void PrintList(bool onlyFutureRecordings = false);
    52     void PrintRec(ProgramInfo *p, const char *prefix = NULL);
     52    static void PrintRec(ProgramInfo *p, const char *prefix = NULL);
    5353
    5454    bool HasConflicts(void) { return hasconflicts; }
    5555
     
    6666    static void *SchedulerThread(void *param);
    6767
    6868  private:
    69     QString recordTable;
    70 
    7169    void verifyCards(void);
    7270
    7371    bool FillRecordList(void);
    7472    void UpdateMatches(int recordid);
    7573    void UpdateManuals(int recordid);
    76     void PruneOldRecords(void);
    77     void AddNewRecords(void);
    78     void AddNotListed(void);
    7974    void BuildNewRecordsQueries(int recordid, QStringList &from, QStringList &where,
    8075                                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);
    9476
    95     bool ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp);
    96 
    9777    void findAllScheduledPrograms(list<ProgramInfo *> &proglist);
    9878    bool CheckShutdownServer(int prerollseconds, QDateTime &idleSince,
    9979                             bool &blockShutdown);
    10080    void ShutdownServer(int prerollseconds);
    10181
     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);
    102131
     132  private:
     133    QString recordTable;
    103134    QValueList<int> reschedQueue;
    104135    QMutex reschedLock;
    105136    QMutex recordmatchLock;
    106137    QWaitCondition reschedWait;
    107138    RecList reclist;
    108     RecList retrylist;
    109139    RecList schedlist;
    110     QMap<int, RecList> cardlistmap;
    111     QMap<int, RecList> recordidlistmap;
    112     QMap<QString, RecList> titlelistmap;
    113140
    114141    QMutex *reclist_lock;
    115142    QMutex *schedlist_lock;