Ticket #2282: 2282-v3.patch

File 2282-v3.patch, 19.2 KB (added by danielk, 14 years ago)

Updated version of patch without extra debugging

  • 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    PruneOldRecords(newlist);
     298    AddNewRecords(dbConn, recordTable, specsched, threadrunning,
     299                  *m_tvList, newlist);
     300    AddNotListed(dbConn, recordTable, newlist);
     301 
    278302    VERBOSE(VB_SCHEDULE, "Sort by time...");
    279     reclist.sort(comp_overlap);
    280     VERBOSE(VB_SCHEDULE, "PruneOverlaps...");
    281     PruneOverlaps();
     303    newlist.sort(comp_overlap);
    282304
     305    PruneOverlaps(newlist);
     306 
    283307    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();
     308    newlist.sort(comp_priority);
    291309
     310    {
     311        QMap<int, RecList>     cardlistmap;
     312        QMap<int, RecList>     recordidlistmap;
     313        QMap<QString, RecList> titlelistmap;
     314 
     315        BuildListMaps(newlist, cardlistmap, recordidlistmap, titlelistmap);
     316
     317        RecList retrylist;
     318        SchedNewRecords(schedMoveHigher, newlist, retrylist,
     319                        cardlistmap, recordidlistmap, titlelistmap);
     320    }
     321
    292322    VERBOSE(VB_SCHEDULE, "Sort by time...");
    293     reclist.sort(comp_redundant);
    294     VERBOSE(VB_SCHEDULE, "PruneRedundants...");
    295     PruneRedundants();
     323    newlist.sort(comp_redundant);
    296324
     325    bool will_have_conflicts = PruneRedundants(newlist);
     326
    297327    VERBOSE(VB_SCHEDULE, "Sort by time...");
    298     reclist.sort(comp_recstart);
     328    newlist.sort(comp_recstart);
    299329
    300     VERBOSE(VB_SCHEDULE, "UpdateNextRecord...");
    301     UpdateNextRecord();
     330    UpdateNextRecord(dbConn, newlist);
    302331
     332    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locking");
     333    reclist_lock->lock();
     334    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locked");
     335
     336    copy_reclist(reclist, newlist);
     337    hasconflicts = will_have_conflicts;
     338
     339    reclist_lock->unlock();
     340    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- unlocked");
     341
     342    delete_reclist(newlist);
     343
    303344    return hasconflicts;
    304345}
    305346
     
    479520    }
    480521}
    481522
    482 bool Scheduler::ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp)
     523bool Scheduler::ChangeRecordingEnd(const bool specsched,
     524                                   QMap<int, EncoderLink*> &tvList,
     525                                   ProgramInfo *oldp,
     526                                   ProgramInfo *newp)
    483527{
    484528    RecordingType oldrectype = oldp->rectype;
    485529    int oldrecordid = oldp->recordid;
     
    500544        else
    501545            return true;
    502546    }
    503     EncoderLink *tv = (*m_tvList)[oldp->cardid];
     547    EncoderLink *tv = tvList[oldp->cardid];
    504548    RecStatusType rs = tv->StartRecording(oldp);
    505549    if (rs != rsRecording)
    506550    {
     
    590634    }
    591635}
    592636
    593 void Scheduler::PruneOldRecords(void)
     637void Scheduler::PruneOldRecords(RecList &reclist)
    594638{
     639    VERBOSE(VB_SCHEDULE, "PruneOldRecords...");
    595640    RecIter dreciter = reclist.begin();
    596641    while (dreciter != reclist.end())
    597642    {
     
    610655    }
    611656}
    612657
    613 void Scheduler::PruneOverlaps(void)
     658void Scheduler::PruneOverlaps(RecList &reclist)
    614659{
     660    VERBOSE(VB_SCHEDULE, "PruneOverlaps...");
    615661    ProgramInfo *lastp = NULL;
    616662
    617663    RecIter dreciter = reclist.begin();
     
    651697    }
    652698}
    653699
    654 void Scheduler::BuildListMaps(void)
     700void Scheduler::BuildListMaps(RecList                &reclist,
     701                              QMap<int, RecList>     &cardlistmap,
     702                              QMap<int, RecList>     &recordidlistmap,
     703                              QMap<QString, RecList> &titlelistmap)
    655704{
     705    VERBOSE(VB_SCHEDULE, "BuildListMaps...");
    656706    RecIter i = reclist.begin();
    657707    for ( ; i != reclist.end(); i++)
    658708    {
     
    668718    }
    669719}
    670720
    671 void Scheduler::ClearListMaps(void)
    672 {
    673     cardlistmap.clear();
    674     titlelistmap.clear();
    675     recordidlistmap.clear();
    676 }
    677 
    678721bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j)
    679722{
    680723    for ( ; j != cardlist.end(); j++)
     
    698741    return false;
    699742}
    700743
    701 void Scheduler::MarkOtherShowings(ProgramInfo *p)
     744void Scheduler::MarkOtherShowings(ProgramInfo *p,
     745                                  QMap<int, RecList>     &recordidlistmap,
     746                                  QMap<QString, RecList> &titlelistmap)
    702747{
    703748    RecList *showinglist = &titlelistmap[p->title];
    704749
     
    746791    }
    747792}
    748793
    749 void Scheduler::BackupRecStatus(void)
     794void Scheduler::BackupRecStatus(RecList &reclist)
    750795{
    751796    RecIter i = reclist.begin();
    752797    for ( ; i != reclist.end(); i++)
     
    756801    }
    757802}
    758803
    759 void Scheduler::RestoreRecStatus(void)
     804void Scheduler::RestoreRecStatus(RecList &reclist)
    760805{
    761806    RecIter i = reclist.begin();
    762807    for ( ; i != reclist.end(); i++)
     
    766811    }
    767812}
    768813
    769 bool Scheduler::TryAnotherShowing(ProgramInfo *p)
     814bool Scheduler::TryAnotherShowing(QMap<int, RecList>     &cardlistmap,
     815                                  QMap<QString, RecList> &titlelistmap,
     816                                  QMap<int, RecList>     &recordidlistmap,
     817                                  ProgramInfo *p)
    770818{
    771819    PrintRec(p, "     >");
    772820
     
    815863        }
    816864
    817865        q->recstatus = rsWillRecord;
    818         MarkOtherShowings(q);
     866        MarkOtherShowings(q, recordidlistmap, titlelistmap);
    819867        PrintRec(p, "     -");
    820868        PrintRec(q, "     +");
    821869        return true;
     
    825873    return false;
    826874}
    827875
    828 void Scheduler::SchedNewRecords(void)
     876void Scheduler::SchedNewRecords(const bool              schedMoveHigher,
     877                                RecList                &reclist,
     878                                RecList                &retrylist,
     879                                QMap<int, RecList>     &cardlistmap,
     880                                QMap<int, RecList>     &recordidlistmap,
     881                                QMap<QString, RecList> &titlelistmap)
    829882{
    830883    VERBOSE(VB_SCHEDULE, "Scheduling:");
    831884
     
    834887    {
    835888        ProgramInfo *p = *i;
    836889        if (p->recstatus == rsRecording)
    837             MarkOtherShowings(p);
     890            MarkOtherShowings(p, recordidlistmap, titlelistmap);
    838891        else if (p->recstatus == rsUnknown)
    839892        {
    840893            RecList &cardlist = cardlistmap[p->cardid];
     
    842895            if (!FindNextConflict(cardlist, p, k))
    843896            {
    844897                p->recstatus = rsWillRecord;
    845                 MarkOtherShowings(p);
     898                MarkOtherShowings(p, recordidlistmap, titlelistmap);
    846899                PrintRec(p, "  +");
    847900            }
    848901            else
     
    857910        i++;
    858911        if (i == reclist.end() || lastpri != (*i)->recpriority)
    859912        {
    860             MoveHigherRecords();
     913            MoveHigherRecords(schedMoveHigher, reclist, retrylist,
     914                              cardlistmap, recordidlistmap, titlelistmap);
    861915            retrylist.clear();
    862916        }
    863917    }
    864918}
    865919
    866 void Scheduler::MoveHigherRecords(void)
     920void Scheduler::MoveHigherRecords(const bool              schedMoveHigher,
     921                                  RecList                &reclist,
     922                                  RecList                &retrylist,
     923                                  QMap<int, RecList>     &cardlistmap,
     924                                  QMap<int, RecList>     &recordidlistmap,
     925                                  QMap<QString, RecList> &titlelistmap)
    867926{
    868927    RecIter i = retrylist.begin();
    869928    for ( ; i != retrylist.end(); i++)
     
    874933
    875934        PrintRec(p, "  ?");
    876935
    877         if (TryAnotherShowing(p))
     936        if (TryAnotherShowing(cardlistmap, titlelistmap, recordidlistmap, p))
    878937            continue;
    879938
    880         BackupRecStatus();
     939        BackupRecStatus(reclist);
    881940        p->recstatus = rsWillRecord;
    882         MarkOtherShowings(p);
     941        MarkOtherShowings(p, recordidlistmap, titlelistmap);
    883942
    884943        RecList &cardlist = cardlistmap[p->cardid];
    885944        RecIter k = cardlist.begin();
    886945        for ( ; FindNextConflict(cardlist, p, k); k++)
    887946        {
    888947            if ((p->recpriority < (*k)->recpriority && !schedMoveHigher) ||
    889                 !TryAnotherShowing(*k))
     948                !TryAnotherShowing(cardlistmap, titlelistmap,
     949                                   recordidlistmap, *k))
    890950            {
    891                 RestoreRecStatus();
     951                RestoreRecStatus(reclist);
    892952                break;
    893953            }
    894954        }
     
    898958    }
    899959}
    900960
    901 void Scheduler::PruneRedundants(void)
     961bool Scheduler::PruneRedundants(RecList &reclist)
    902962{
     963    VERBOSE(VB_SCHEDULE, "PruneRedundants...");
    903964    ProgramInfo *lastp = NULL;
    904     hasconflicts = false;
     965    bool hasconflicts = false;
    905966
    906967    RecIter i = reclist.begin();
    907968    while (i != reclist.end())
     
    9511012            i = reclist.erase(i);
    9521013        }
    9531014    }
     1015
     1016    return hasconflicts;
    9541017}
    9551018
    956 void Scheduler::UpdateNextRecord(void)
     1019void Scheduler::UpdateNextRecord(MSqlQueryInfo &dbConn,
     1020                                 RecList       &reclist)
    9571021{
     1022    VERBOSE(VB_SCHEDULE, "UpdateNextRecord...");
    9581023    QMap<int, QDateTime> nextRecMap;
    9591024    QDateTime now = QDateTime::currentDateTime();
    9601025
     
    10431108{
    10441109    QMutexLocker lockit(reclist_lock);
    10451110
    1046     while (retList->size() > 0)
    1047     {
    1048         ProgramInfo *pginfo = retList->back();
    1049         delete pginfo;
    1050         retList->pop_back();
    1051     }
    1052 
    1053     RecIter i = reclist.begin();
    1054     for (; i != reclist.end(); i++)
    1055     {
    1056         ProgramInfo *p = *i;
    1057         retList->push_back(new ProgramInfo(*p));
    1058     }
     1111    copy_reclist(*retList, reclist);
    10591112    retList->sort(comp_timechannel);
    10601113}
    10611114
    10621115void Scheduler::getAllPending(QStringList &strList)
    10631116{
    1064     QMutexLocker lockit(reclist_lock);
     1117    RecList retList;
     1118    getAllPending(&retList);
    10651119
    10661120    strList << QString::number(hasconflicts);
    1067     strList << QString::number(reclist.size());
     1121    strList << QString::number(retList.size());
    10681122
    1069     RecList *retList = new RecList;
     1123    for (RecIter it = retList.begin(); it != retList.end(); ++it)
     1124        (*it)->ToStringList(strList);
    10701125
    1071     RecIter i = reclist.begin();
    1072     for (; i != reclist.end(); i++)
    1073     {
    1074         ProgramInfo *p = *i;
    1075         retList->push_back(new ProgramInfo(*p));
    1076     }
    1077     retList->sort(comp_timechannel);
    1078 
    1079     for (i = retList->begin(); i != retList->end(); i++)
    1080     {
    1081         ProgramInfo *p = *i;
    1082         p->ToStringList(strList);
    1083         delete p;
    1084     }
    1085 
    1086     delete retList;
     1126    delete_reclist(retList);
    10871127}
    10881128
    10891129RecList *Scheduler::getAllScheduled(void)
    10901130{
    1091     while (schedlist.size() > 0)
    1092     {
    1093         ProgramInfo *pginfo = schedlist.back();
    1094         delete pginfo;
    1095         schedlist.pop_back();
    1096     }
     1131    delete_reclist(schedlist);
    10971132
    10981133    findAllScheduledPrograms(schedlist);
    10991134
     
    20082043    VERBOSE(VB_SCHEDULE, " +-- Done.");
    20092044}
    20102045
    2011 void Scheduler::AddNewRecords(void)
     2046void Scheduler::AddNewRecords(MSqlQueryInfo           &dbConn,
     2047                              const QString           &recordTable,
     2048                              const bool               specsched,
     2049                              const bool               threadrunning,
     2050                              QMap<int, EncoderLink*> &tvList,
     2051                              RecList                 &reclist)
    20122052{
     2053    VERBOSE(VB_SCHEDULE, "AddNewRecords...");
    20132054    struct timeval dbstart, dbend;
    20142055
    20152056    QMap<RecordingType, int> recTypeRecPriorityMap;
     
    20222063    int ccpriority      = gContext->GetNumSetting("CCRecPriority", 0);
    20232064
    20242065    QMap<int, bool> cardMap;
    2025     QMap<int, EncoderLink *>::Iterator enciter = m_tvList->begin();
    2026     for (; enciter != m_tvList->end(); ++enciter)
     2066    QMap<int, EncoderLink *>::Iterator enciter = tvList.begin();
     2067    for (; enciter != tvList.end(); ++enciter)
    20272068    {
    20282069        EncoderLink *enc = enciter.data();
    20292070        if (enc->IsConnected())
     
    23332374                    r->recendts != p->recendts &&
    23342375                    (r->recordid == p->recordid ||
    23352376                     p->rectype == kOverrideRecord))
    2336                     ChangeRecordingEnd(r, p);
     2377                {
     2378                    ChangeRecordingEnd(specsched, tvList, r, p);
     2379                }
    23372380                delete p;
    23382381                p = NULL;
    23392382                break;
     
    23902433        reclist.push_back(*tmp);
    23912434}
    23922435
    2393 void Scheduler::AddNotListed(void) {
    2394 
     2436void Scheduler::AddNotListed(MSqlQueryInfo &dbConn,
     2437                             const QString &recordTable,
     2438                             RecList       &reclist)
     2439{
     2440    VERBOSE(VB_SCHEDULE, "AddNotListed...");
    23952441    struct timeval dbstart, dbend;
    23962442    RecList tmpList;
    23972443
  • 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;