Ticket #2282: 2282-alt-v4.patch

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

Alternate version of patch (does not make scheduling functions static)

  • programs/mythbackend/scheduler.cpp

     
    3636#define LOC QString("Scheduler: ")
    3737#define LOC_ERR QString("Scheduler, Error: ")
    3838
     39static void delete_reclist(RecList &reclist);
     40static void copy_reclist(RecList &copy, const RecList &orig);
     41
    3942Scheduler::Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
    4043                     QString recordTbl, Scheduler *master_sched)
    4144{
     
    4750    if (master_sched)
    4851    {
    4952        specsched = true;
    50         master_sched->getAllPending(&reclist);
     53        master_sched->getAllPending(&cached_reclist);
    5154    }
    5255
    5356    // Only the master scheduler should use SchedCon()
     
    6669
    6770    threadrunning = runthread;
    6871
    69     reclist_lock = new QMutex(true);
     72    cached_reclist_lock = new QMutex(true);
    7073    schedlist_lock = new QMutex(true);
    7174
    7275    if (runthread)
     
    7881
    7982Scheduler::~Scheduler()
    8083{
    81     while (reclist.size() > 0)
     84    delete_reclist(cached_reclist);
     85
     86    if (cached_reclist_lock)
    8287    {
    83         ProgramInfo *pginfo = reclist.back();
    84         delete pginfo;
    85         reclist.pop_back();
     88        delete cached_reclist_lock;
     89        cached_reclist_lock = NULL;
    8690    }
     91
     92    if (schedlist_lock)
     93    {
     94        delete schedlist_lock;
     95        schedlist_lock = NULL;
     96    }
    8797}
    8898
    8999void Scheduler::SetMainServer(MainServer *ms)
     
    263273
    264274bool Scheduler::FillRecordList(void)
    265275{
    266     QMutexLocker lockit(reclist_lock);
    267 
    268276    schedMoveHigher = (bool)gContext->GetNumSetting("SchedMoveHigher");
    269277    schedTime = QDateTime::currentDateTime();
    270278
     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
    271288    VERBOSE(VB_SCHEDULE, "PruneOldRecords...");
    272289    PruneOldRecords();
    273290    VERBOSE(VB_SCHEDULE, "AddNewRecords...");
     
    292309    VERBOSE(VB_SCHEDULE, "Sort by time...");
    293310    reclist.sort(comp_redundant);
    294311    VERBOSE(VB_SCHEDULE, "PruneRedundants...");
    295     PruneRedundants();
     312    bool will_have_conflicts = PruneRedundants();
    296313
    297314    VERBOSE(VB_SCHEDULE, "Sort by time...");
    298315    reclist.sort(comp_recstart);
    299316
     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
    300329    return hasconflicts;
    301330}
    302331
     
    358387                         (fillend.tv_usec - fillstart.tv_usec) / 1000000.0;
    359388    QString msg;
    360389    msg.sprintf("Speculative scheduled %d items in "
    361                 "%.2f", (int)reclist.size(),
     390                "%.2f", (int)cached_reclist.size(),
    362391                schedTime);
    363392    VERBOSE(VB_GENERAL, msg);
    364393}
     
    368397    ProgramList schedList(false);
    369398    schedList.FromScheduler();
    370399
    371     QMutexLocker lockit(reclist_lock);
     400    QMutexLocker lockit(cached_reclist_lock);
    372401
    373402    ProgramInfo *p;
    374403    for (p = schedList.first(); p; p = schedList.next())
    375         reclist.push_back(p);
     404        cached_reclist.push_back(p);
    376405}
    377406
    378407void Scheduler::PrintList(bool onlyFutureRecordings)
     
    386415    cout << "Title - Subtitle                    Chan ChID Day Start  End   "
    387416        "C I  T N   Pri" << endl;
    388417
    389     RecIter i = reclist.begin();
    390     for ( ; i != reclist.end(); i++)
     418    RecIter i = cached_reclist.begin();
     419    for ( ; i != cached_reclist.end(); i++)
    391420    {
    392421        ProgramInfo *first = (*i);
    393422
     
    431460
    432461void Scheduler::UpdateRecStatus(ProgramInfo *pginfo)
    433462{
    434     QMutexLocker lockit(reclist_lock);
     463    QMutexLocker lockit(cached_reclist_lock);
    435464
    436     RecIter dreciter = reclist.begin();
    437     for (; dreciter != reclist.end(); ++dreciter)
     465    RecIter dreciter = cached_reclist.begin();
     466    for (; dreciter != cached_reclist.end(); ++dreciter)
    438467    {
    439468        ProgramInfo *p = *dreciter;
    440469        if (p->IsSameProgramTimeslot(*pginfo))
     
    454483                                RecStatusType recstatus,
    455484                                const QDateTime &recendts)
    456485{
    457     QMutexLocker lockit(reclist_lock);
     486    QMutexLocker lockit(cached_reclist_lock);
    458487
    459     RecIter dreciter = reclist.begin();
    460     for (; dreciter != reclist.end(); ++dreciter)
     488    RecIter dreciter = cached_reclist.begin();
     489    for (; dreciter != cached_reclist.end(); ++dreciter)
    461490    {
    462491        ProgramInfo *p = *dreciter;
    463492        if (p->cardid == cardid &&
     
    513542
    514543void Scheduler::SlaveConnected(ProgramList &slavelist)
    515544{
    516     QMutexLocker lockit(reclist_lock);
     545    QMutexLocker lockit(cached_reclist_lock);
    517546
    518547    ProgramInfo *sp;
    519548    for (sp = slavelist.first(); sp; sp = slavelist.next())
    520549    {
    521550        bool found = false;
    522551
    523         RecIter ri = reclist.begin();
    524         for ( ; ri != reclist.end(); ri++)
     552        RecIter ri = cached_reclist.begin();
     553        for ( ; ri != cached_reclist.end(); ri++)
    525554        {
    526555            ProgramInfo *rp = *ri;
    527556
     
    559588
    560589        if (sp->inputid && !found)
    561590        {
    562             reclist.push_back(new ProgramInfo(*sp));
     591            cached_reclist.push_back(new ProgramInfo(*sp));
    563592            sp->AddHistory(false);
    564593            VERBOSE(VB_IMPORTANT, QString("adding %1/%2/\"%3\" as recording")
    565594                    .arg(sp->cardid).arg(sp->chansign).arg(sp->title));
     
    569598
    570599void Scheduler::SlaveDisconnected(int cardid)
    571600{
    572     QMutexLocker lockit(reclist_lock);
     601    QMutexLocker lockit(cached_reclist_lock);
    573602
    574     RecIter ri = reclist.begin();
    575     for ( ; ri != reclist.end(); ri++)
     603    RecIter ri = cached_reclist.begin();
     604    for ( ; ri != cached_reclist.end(); ri++)
    576605    {
    577606        ProgramInfo *rp = *ri;
    578607
     
    895924    }
    896925}
    897926
    898 void Scheduler::PruneRedundants(void)
     927bool Scheduler::PruneRedundants(void)
    899928{
    900929    ProgramInfo *lastp = NULL;
    901     hasconflicts = false;
     930    bool hasconflicts = false;
    902931
    903932    RecIter i = reclist.begin();
    904933    while (i != reclist.end())
     
    948977            i = reclist.erase(i);
    949978        }
    950979    }
     980
     981    return hasconflicts;
    951982}
    952983
    953984void Scheduler::UpdateNextRecord(void)
     
    955986    QMap<int, QDateTime> nextRecMap;
    956987    QDateTime now = QDateTime::currentDateTime();
    957988
    958     RecIter i = reclist.begin();
    959     while (i != reclist.end())
     989    RecIter i = cached_reclist.begin();
     990    while (i != cached_reclist.end())
    960991    {
    961992        ProgramInfo *p = *i;
    962993        if (p->recstartts > now && p->recstatus == rsWillRecord &&
     
    10071038
    10081039void Scheduler::getConflicting(ProgramInfo *pginfo, QStringList &strlist)
    10091040{
    1010     QMutexLocker lockit(reclist_lock);
     1041    QMutexLocker lockit(cached_reclist_lock);
    10111042
    10121043    RecList *curList = getConflicting(pginfo);
    10131044
     
    10221053 
    10231054RecList *Scheduler::getConflicting(ProgramInfo *pginfo)
    10241055{
    1025     QMutexLocker lockit(reclist_lock);
     1056    QMutexLocker lockit(cached_reclist_lock);
    10261057
    10271058    RecList *retlist = new RecList;
    10281059
    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++)
    10311062    {
    10321063        ProgramInfo *p = *i;
    10331064        retlist->push_back(p);
     
    10381069
    10391070void Scheduler::getAllPending(RecList *retList)
    10401071{
    1041     QMutexLocker lockit(reclist_lock);
     1072    QMutexLocker lockit(cached_reclist_lock);
    10421073
    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);
    10561075    retList->sort(comp_timechannel);
    10571076}
    10581077
    10591078void Scheduler::getAllPending(QStringList &strList)
    10601079{
    1061     QMutexLocker lockit(reclist_lock);
     1080    RecList retList;
     1081    getAllPending(&retList);
    10621082
    10631083    strList << QString::number(hasconflicts);
    1064     strList << QString::number(reclist.size());
     1084    strList << QString::number(retList.size());
    10651085
    1066     RecList *retList = new RecList;
     1086    for (RecIter it = retList.begin(); it != retList.end(); ++it)
     1087        (*it)->ToStringList(strList);
    10671088
    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);
    10841090}
    10851091
    10861092RecList *Scheduler::getAllScheduled(void)
    10871093{
    1088     while (schedlist.size() > 0)
    1089     {
    1090         ProgramInfo *pginfo = schedlist.back();
    1091         delete pginfo;
    1092         schedlist.pop_back();
    1093     }
     1094    delete_reclist(schedlist);
    10941095
    10951096    findAllScheduledPrograms(schedlist);
    10961097
     
    11221123
    11231124void Scheduler::AddRecording(const ProgramInfo &pi)
    11241125{
    1125     QMutexLocker lockit(reclist_lock);
     1126    QMutexLocker lockit(cached_reclist_lock);
    11261127
    11271128    VERBOSE(VB_GENERAL, LOC + "AddRecording() recid: " << pi.recordid);
    11281129
    1129     for (RecIter it = reclist.begin(); it != reclist.end(); ++it)
     1130    for (RecIter it = cached_reclist.begin(); it != cached_reclist.end(); ++it)
    11301131    {
    11311132        ProgramInfo *p = *it;
    11321133        if (p->recstatus == rsRecording && p->IsSameProgramTimeslot(pi))
     
    11411142            QString("Adding '%1' to reclist.").arg(pi.title));
    11421143
    11431144    ProgramInfo * new_pi = new ProgramInfo(pi);
    1144     reclist.push_back(new_pi);
     1145    cached_reclist.push_back(new_pi);
    11451146
    11461147    // Save rsRecording recstatus to DB
    11471148    // This allows recordings to resume on backend restart
     
    11691170
    11701171    QString recordfileprefix = gContext->GetFilePrefix();
    11711172
    1172     RecIter startIter = reclist.begin();
     1173    RecIter startIter = cached_reclist.begin();
    11731174
    11741175    bool blockShutdown = gContext->GetNumSetting("blockSDWUwithoutClient", 1);
    11751176    QDateTime idleSince = QDateTime();
     
    12011202        curtime = QDateTime::currentDateTime();
    12021203        bool statuschanged = false;
    12031204
    1204       if ((startIter != reclist.end() &&
     1205      if ((startIter != cached_reclist.end() &&
    12051206           curtime.secsTo((*startIter)->recstartts) < 30))
    12061207          sleep(1);
    12071208      else
     
    12501251                         (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
    12511252
    12521253            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(),
    12541256                        matchTime + placeTime, matchTime, placeTime);
    12551257                         
    12561258            VERBOSE(VB_GENERAL, msg);
    12571259            gContext->LogEntry("scheduler", LP_INFO, "Scheduled items", msg);
    12581260
    12591261            lastupdate = curtime;
    1260             startIter = reclist.begin();
     1262            startIter = cached_reclist.begin();
    12611263            statuschanged = true;
    12621264
    12631265            // Determine if the user wants us to start recording early
     
    12751277                QString startupParam = "user";
    12761278               
    12771279                // have we been started automatically?
    1278                 if ((startIter != reclist.end()) &&
     1280                if ((startIter != cached_reclist.end()) &&
    12791281                    ((curtime.secsTo((*startIter)->startts) - prerollseconds)
    12801282                        < (idleWaitForRecordingTime * 60)))
    12811283                {
     
    13041306        }
    13051307      }
    13061308
    1307         for ( ; startIter != reclist.end(); startIter++)
     1309        for ( ; startIter != cached_reclist.end(); startIter++)
    13081310            if ((*startIter)->recstatus != (*startIter)->oldrecstatus)
    13091311                break;
    13101312
    13111313        curtime = QDateTime::currentDateTime();
    13121314
    13131315        RecIter recIter = startIter;
    1314         for ( ; recIter != reclist.end(); recIter++)
     1316        for ( ; recIter != cached_reclist.end(); recIter++)
    13151317        {
    13161318            QString msg, details;
    13171319
     
    13381340                    .arg(nextRecording->title);
    13391341                VERBOSE(VB_GENERAL, msg);
    13401342
    1341                 QMutexLocker lockit(reclist_lock);
     1343                QMutexLocker lockit(cached_reclist_lock);
    13421344                nextRecording->recstatus = rsTunerBusy;
    13431345                nextRecording->AddHistory(true);
    13441346                statuschanged = true;
     
    13601362                    .arg(nextRecording->sourceid)
    13611363                    .arg((long)nexttv->GetFreeDiskSpace(true)/1024);
    13621364                VERBOSE(VB_GENERAL, msg);
    1363                 QMutexLocker lockit(reclist_lock);
     1365                QMutexLocker lockit(cached_reclist_lock);
    13641366                nextRecording->recstatus = rsLowDiskSpace;
    13651367                nextRecording->AddHistory(true);
    13661368                statuschanged = true;
     
    13781380                    .arg(nextRecording->sourceid);
    13791381                VERBOSE(VB_GENERAL, msg);
    13801382
    1381                 QMutexLocker lockit(reclist_lock);
     1383                QMutexLocker lockit(cached_reclist_lock);
    13821384                nextRecording->recstatus = rsTunerBusy;
    13831385                nextRecording->AddHistory(true);
    13841386                statuschanged = true;
     
    14181420                nextRecording->recstartts.time().hour(),
    14191421                nextRecording->recstartts.time().minute()));
    14201422
    1421             QMutexLocker lockit(reclist_lock);
     1423            QMutexLocker lockit(cached_reclist_lock);
    14221424
    14231425            QString subtitle = nextRecording->subtitle.isEmpty() ? "" :
    14241426                QString(" \"%1\"").arg(nextRecording->subtitle);
     
    14891491                {
    14901492                    if (!idleSince.isValid())
    14911493                    {
    1492                         if (startIter != reclist.end())
     1494                        if (startIter != cached_reclist.end())
    14931495                        {
    14941496                            if (curtime.secsTo((*startIter)->startts) -
    14951497                                prerollseconds > idleWaitForRecordingTime * 60)
     
    16091611{   
    16101612    m_isShuttingDown = true;
    16111613 
    1612     RecIter recIter = reclist.begin();
    1613     for ( ; recIter != reclist.end(); recIter++)
     1614    RecIter recIter = cached_reclist.begin();
     1615    for ( ; recIter != cached_reclist.end(); recIter++)
    16141616        if ((*recIter)->recstatus == rsWillRecord)
    16151617            break;
    16161618
    16171619    // set the wakeuptime if needed
    1618     if (recIter != reclist.end())
     1620    if (recIter != cached_reclist.end())
    16191621    {
    16201622        ProgramInfo *nextRecording = (*recIter);
    16211623        QDateTime restarttime = nextRecording->startts.addSecs((-1) *
     
    26172619    }
    26182620}
    26192621
     2622static 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
     2632static void copy_reclist(RecList &copy, 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
    26202641/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • programs/mythbackend/scheduler.h

     
    3838                         const QDateTime &startts, RecStatusType recstatus,
    3939                         const QDateTime &recendts);
    4040
    41     RecList *getAllPending(void) { return &reclist; }
     41    RecList *getAllPending(void) { return &cached_reclist; }
    4242    void getAllPending(RecList *retList);
    4343    void getAllPending(QStringList &strList);
    4444
     
    8989    bool TryAnotherShowing(ProgramInfo *p);
    9090    void SchedNewRecords(void);
    9191    void MoveHigherRecords(void);
    92     void PruneRedundants(void);
     92    bool PruneRedundants(void);
    9393    void UpdateNextRecord(void);
    9494
    9595    bool ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp);
     
    104104    QMutex reschedLock;
    105105    QMutex recordmatchLock;
    106106    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
    107115    RecList reclist;
    108116    RecList retrylist;
    109     RecList schedlist;
    110117    QMap<int, RecList> cardlistmap;
    111118    QMap<int, RecList> recordidlistmap;
    112119    QMap<QString, RecList> titlelistmap;
    113120
    114     QMutex *reclist_lock;
    115     QMutex *schedlist_lock;
    116 
    117121    bool specsched;
    118122    bool hasconflicts;
    119123    bool schedMoveHigher;