Index: programs/mythbackend/scheduler.cpp
===================================================================
--- programs/mythbackend/scheduler.cpp	(revision 11413)
+++ programs/mythbackend/scheduler.cpp	(working copy)
@@ -36,6 +36,9 @@
 #define LOC QString("Scheduler: ")
 #define LOC_ERR QString("Scheduler, Error: ")
 
+static void delete_reclist(RecList &reclist);
+static void copy_reclist(RecList &copy, const RecList &orig);
+
 Scheduler::Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
                      QString recordTbl, Scheduler *master_sched)
 {
@@ -47,7 +50,7 @@
     if (master_sched)
     {
         specsched = true;
-        master_sched->getAllPending(&reclist);
+        master_sched->getAllPending(&cached_reclist);
     }
 
     // Only the master scheduler should use SchedCon()
@@ -66,7 +69,7 @@
 
     threadrunning = runthread;
 
-    reclist_lock = new QMutex(true);
+    cached_reclist_lock = new QMutex(true);
     schedlist_lock = new QMutex(true);
 
     if (runthread)
@@ -78,12 +81,19 @@
 
 Scheduler::~Scheduler()
 {
-    while (reclist.size() > 0)
+    delete_reclist(cached_reclist);
+
+    if (cached_reclist_lock)
     {
-        ProgramInfo *pginfo = reclist.back();
-        delete pginfo;
-        reclist.pop_back();
+        delete cached_reclist_lock;
+        cached_reclist_lock = NULL;
     }
+
+    if (schedlist_lock)
+    {
+        delete schedlist_lock;
+        schedlist_lock = NULL;
+    }
 }
 
 void Scheduler::SetMainServer(MainServer *ms)
@@ -263,11 +273,18 @@
 
 bool Scheduler::FillRecordList(void)
 {
-    QMutexLocker lockit(reclist_lock);
-
     schedMoveHigher = (bool)gContext->GetNumSetting("SchedMoveHigher");
     schedTime = QDateTime::currentDateTime();
 
+    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locking  1");
+    cached_reclist_lock->lock();
+    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locked   1");
+
+    copy_reclist(reclist, cached_reclist);
+
+    cached_reclist_lock->unlock();
+    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- unlocked 1");
+
     VERBOSE(VB_SCHEDULE, "PruneOldRecords...");
     PruneOldRecords();
     VERBOSE(VB_SCHEDULE, "AddNewRecords...");
@@ -292,11 +309,23 @@
     VERBOSE(VB_SCHEDULE, "Sort by time...");
     reclist.sort(comp_redundant);
     VERBOSE(VB_SCHEDULE, "PruneRedundants...");
-    PruneRedundants();
+    bool will_have_conflicts = PruneRedundants();
 
     VERBOSE(VB_SCHEDULE, "Sort by time...");
     reclist.sort(comp_recstart);
 
+    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locking  2");
+    cached_reclist_lock->lock();
+    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locked   2");
+
+    copy_reclist(cached_reclist, reclist);
+    hasconflicts = will_have_conflicts;
+
+    cached_reclist_lock->unlock();
+    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- unlocked 2");
+
+    delete_reclist(reclist);
+
     return hasconflicts;
 }
 
@@ -358,7 +387,7 @@
                          (fillend.tv_usec - fillstart.tv_usec) / 1000000.0;
     QString msg;
     msg.sprintf("Speculative scheduled %d items in "
-                "%.2f", (int)reclist.size(),
+                "%.2f", (int)cached_reclist.size(),
                 schedTime);
     VERBOSE(VB_GENERAL, msg);
 }
@@ -368,11 +397,11 @@
     ProgramList schedList(false);
     schedList.FromScheduler();
 
-    QMutexLocker lockit(reclist_lock);
+    QMutexLocker lockit(cached_reclist_lock);
 
     ProgramInfo *p;
     for (p = schedList.first(); p; p = schedList.next())
-        reclist.push_back(p);
+        cached_reclist.push_back(p);
 }
 
 void Scheduler::PrintList(bool onlyFutureRecordings)
@@ -386,8 +415,8 @@
     cout << "Title - Subtitle                    Chan ChID Day Start  End   "
         "C I  T N   Pri" << endl;
 
-    RecIter i = reclist.begin();
-    for ( ; i != reclist.end(); i++)
+    RecIter i = cached_reclist.begin();
+    for ( ; i != cached_reclist.end(); i++)
     {
         ProgramInfo *first = (*i);
 
@@ -431,10 +460,10 @@
 
 void Scheduler::UpdateRecStatus(ProgramInfo *pginfo)
 {
-    QMutexLocker lockit(reclist_lock);
+    QMutexLocker lockit(cached_reclist_lock);
 
-    RecIter dreciter = reclist.begin();
-    for (; dreciter != reclist.end(); ++dreciter)
+    RecIter dreciter = cached_reclist.begin();
+    for (; dreciter != cached_reclist.end(); ++dreciter)
     {
         ProgramInfo *p = *dreciter;
         if (p->IsSameProgramTimeslot(*pginfo))
@@ -454,10 +483,10 @@
                                 RecStatusType recstatus, 
                                 const QDateTime &recendts)
 {
-    QMutexLocker lockit(reclist_lock);
+    QMutexLocker lockit(cached_reclist_lock);
 
-    RecIter dreciter = reclist.begin();
-    for (; dreciter != reclist.end(); ++dreciter)
+    RecIter dreciter = cached_reclist.begin();
+    for (; dreciter != cached_reclist.end(); ++dreciter)
     {
         ProgramInfo *p = *dreciter;
         if (p->cardid == cardid &&
@@ -513,15 +542,15 @@
 
 void Scheduler::SlaveConnected(ProgramList &slavelist)
 {
-    QMutexLocker lockit(reclist_lock);
+    QMutexLocker lockit(cached_reclist_lock);
 
     ProgramInfo *sp;
     for (sp = slavelist.first(); sp; sp = slavelist.next())
     {
         bool found = false;
 
-        RecIter ri = reclist.begin();
-        for ( ; ri != reclist.end(); ri++)
+        RecIter ri = cached_reclist.begin();
+        for ( ; ri != cached_reclist.end(); ri++)
         {
             ProgramInfo *rp = *ri;
 
@@ -559,7 +588,7 @@
 
         if (sp->inputid && !found)
         {
-            reclist.push_back(new ProgramInfo(*sp));
+            cached_reclist.push_back(new ProgramInfo(*sp));
             sp->AddHistory(false);
             VERBOSE(VB_IMPORTANT, QString("adding %1/%2/\"%3\" as recording")
                     .arg(sp->cardid).arg(sp->chansign).arg(sp->title));
@@ -569,10 +598,10 @@
 
 void Scheduler::SlaveDisconnected(int cardid)
 {
-    QMutexLocker lockit(reclist_lock);
+    QMutexLocker lockit(cached_reclist_lock);
 
-    RecIter ri = reclist.begin();
-    for ( ; ri != reclist.end(); ri++)
+    RecIter ri = cached_reclist.begin();
+    for ( ; ri != cached_reclist.end(); ri++)
     {
         ProgramInfo *rp = *ri;
 
@@ -895,10 +924,10 @@
     }
 }
 
-void Scheduler::PruneRedundants(void)
+bool Scheduler::PruneRedundants(void)
 {
     ProgramInfo *lastp = NULL;
-    hasconflicts = false;
+    bool hasconflicts = false;
 
     RecIter i = reclist.begin();
     while (i != reclist.end())
@@ -948,6 +977,8 @@
             i = reclist.erase(i);
         }
     }
+
+    return hasconflicts;
 }
 
 void Scheduler::UpdateNextRecord(void)
@@ -955,8 +986,8 @@
     QMap<int, QDateTime> nextRecMap;
     QDateTime now = QDateTime::currentDateTime();
 
-    RecIter i = reclist.begin();
-    while (i != reclist.end())
+    RecIter i = cached_reclist.begin();
+    while (i != cached_reclist.end())
     {
         ProgramInfo *p = *i;
         if (p->recstartts > now && p->recstatus == rsWillRecord && 
@@ -1007,7 +1038,7 @@
 
 void Scheduler::getConflicting(ProgramInfo *pginfo, QStringList &strlist)
 {
-    QMutexLocker lockit(reclist_lock);
+    QMutexLocker lockit(cached_reclist_lock);
 
     RecList *curList = getConflicting(pginfo);
 
@@ -1022,12 +1053,12 @@
  
 RecList *Scheduler::getConflicting(ProgramInfo *pginfo)
 {
-    QMutexLocker lockit(reclist_lock);
+    QMutexLocker lockit(cached_reclist_lock);
 
     RecList *retlist = new RecList;
 
-    RecIter i = reclist.begin();
-    for (; FindNextConflict(reclist, pginfo, i); i++)
+    RecIter i = cached_reclist.begin();
+    for (; FindNextConflict(cached_reclist, pginfo, i); i++)
     {
         ProgramInfo *p = *i;
         retlist->push_back(p);
@@ -1038,59 +1069,29 @@
 
 void Scheduler::getAllPending(RecList *retList)
 {
-    QMutexLocker lockit(reclist_lock);
+    QMutexLocker lockit(cached_reclist_lock);
 
-    while (retList->size() > 0)
-    {
-        ProgramInfo *pginfo = retList->back();
-        delete pginfo;
-        retList->pop_back();
-    }
-
-    RecIter i = reclist.begin();
-    for (; i != reclist.end(); i++)
-    {
-        ProgramInfo *p = *i;
-        retList->push_back(new ProgramInfo(*p));
-    }
+    copy_reclist(*retList, cached_reclist);
     retList->sort(comp_timechannel);
 }
 
 void Scheduler::getAllPending(QStringList &strList)
 {
-    QMutexLocker lockit(reclist_lock);
+    RecList retList;
+    getAllPending(&retList);
 
     strList << QString::number(hasconflicts);
-    strList << QString::number(reclist.size());
+    strList << QString::number(retList.size());
 
-    RecList *retList = new RecList;
+    for (RecIter it = retList.begin(); it != retList.end(); ++it)
+        (*it)->ToStringList(strList);
 
-    RecIter i = reclist.begin();
-    for (; i != reclist.end(); i++)
-    {
-        ProgramInfo *p = *i;
-        retList->push_back(new ProgramInfo(*p));
-    }
-    retList->sort(comp_timechannel);
-
-    for (i = retList->begin(); i != retList->end(); i++)
-    {
-        ProgramInfo *p = *i;
-        p->ToStringList(strList);
-        delete p;
-    }
-
-    delete retList;
+    delete_reclist(retList);
 }
 
 RecList *Scheduler::getAllScheduled(void)
 {
-    while (schedlist.size() > 0)
-    {
-        ProgramInfo *pginfo = schedlist.back();
-        delete pginfo;
-        schedlist.pop_back();
-    }
+    delete_reclist(schedlist);
 
     findAllScheduledPrograms(schedlist);
 
@@ -1122,11 +1123,11 @@
 
 void Scheduler::AddRecording(const ProgramInfo &pi)
 {
-    QMutexLocker lockit(reclist_lock);
+    QMutexLocker lockit(cached_reclist_lock);
 
     VERBOSE(VB_GENERAL, LOC + "AddRecording() recid: " << pi.recordid);
 
-    for (RecIter it = reclist.begin(); it != reclist.end(); ++it)
+    for (RecIter it = cached_reclist.begin(); it != cached_reclist.end(); ++it)
     {
         ProgramInfo *p = *it;
         if (p->recstatus == rsRecording && p->IsSameProgramTimeslot(pi))
@@ -1141,7 +1142,7 @@
             QString("Adding '%1' to reclist.").arg(pi.title));
 
     ProgramInfo * new_pi = new ProgramInfo(pi);
-    reclist.push_back(new_pi);
+    cached_reclist.push_back(new_pi);
 
     // Save rsRecording recstatus to DB
     // This allows recordings to resume on backend restart
@@ -1169,7 +1170,7 @@
 
     QString recordfileprefix = gContext->GetFilePrefix();
 
-    RecIter startIter = reclist.begin();
+    RecIter startIter = cached_reclist.begin();
 
     bool blockShutdown = gContext->GetNumSetting("blockSDWUwithoutClient", 1);
     QDateTime idleSince = QDateTime();
@@ -1201,7 +1202,7 @@
         curtime = QDateTime::currentDateTime();
         bool statuschanged = false;
 
-      if ((startIter != reclist.end() &&
+      if ((startIter != cached_reclist.end() &&
            curtime.secsTo((*startIter)->recstartts) < 30))
           sleep(1);
       else
@@ -1250,14 +1251,15 @@
                          (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
 
             msg.sprintf("Scheduled %d items in "
-                        "%.1f = %.2f match + %.2f place", (int)reclist.size(),
+                        "%.1f = %.2f match + %.2f place",
+                        (int)cached_reclist.size(),
                         matchTime + placeTime, matchTime, placeTime);
                          
             VERBOSE(VB_GENERAL, msg);
             gContext->LogEntry("scheduler", LP_INFO, "Scheduled items", msg);
 
             lastupdate = curtime;
-            startIter = reclist.begin();
+            startIter = cached_reclist.begin();
             statuschanged = true;
 
             // Determine if the user wants us to start recording early
@@ -1275,7 +1277,7 @@
                 QString startupParam = "user";
                 
                 // have we been started automatically?
-                if ((startIter != reclist.end()) &&
+                if ((startIter != cached_reclist.end()) &&
                     ((curtime.secsTo((*startIter)->startts) - prerollseconds)
                         < (idleWaitForRecordingTime * 60)))
                 {
@@ -1304,14 +1306,14 @@
         }
       }
 
-        for ( ; startIter != reclist.end(); startIter++)
+        for ( ; startIter != cached_reclist.end(); startIter++)
             if ((*startIter)->recstatus != (*startIter)->oldrecstatus)
                 break;
 
         curtime = QDateTime::currentDateTime();
 
         RecIter recIter = startIter;
-        for ( ; recIter != reclist.end(); recIter++)
+        for ( ; recIter != cached_reclist.end(); recIter++)
         {
             QString msg, details;
 
@@ -1338,7 +1340,7 @@
                     .arg(nextRecording->title);
                 VERBOSE(VB_GENERAL, msg);
 
-                QMutexLocker lockit(reclist_lock);
+                QMutexLocker lockit(cached_reclist_lock);
                 nextRecording->recstatus = rsTunerBusy;
                 nextRecording->AddHistory(true);
                 statuschanged = true;
@@ -1360,7 +1362,7 @@
                     .arg(nextRecording->sourceid)
                     .arg((long)nexttv->GetFreeDiskSpace(true)/1024);
                 VERBOSE(VB_GENERAL, msg);
-                QMutexLocker lockit(reclist_lock);
+                QMutexLocker lockit(cached_reclist_lock);
                 nextRecording->recstatus = rsLowDiskSpace;
                 nextRecording->AddHistory(true);
                 statuschanged = true;
@@ -1378,7 +1380,7 @@
                     .arg(nextRecording->sourceid);
                 VERBOSE(VB_GENERAL, msg);
 
-                QMutexLocker lockit(reclist_lock);
+                QMutexLocker lockit(cached_reclist_lock);
                 nextRecording->recstatus = rsTunerBusy;
                 nextRecording->AddHistory(true);
                 statuschanged = true;
@@ -1418,7 +1420,7 @@
                 nextRecording->recstartts.time().hour(),
                 nextRecording->recstartts.time().minute()));
 
-            QMutexLocker lockit(reclist_lock);
+            QMutexLocker lockit(cached_reclist_lock);
 
             QString subtitle = nextRecording->subtitle.isEmpty() ? "" :
                 QString(" \"%1\"").arg(nextRecording->subtitle);
@@ -1489,7 +1491,7 @@
                 {
                     if (!idleSince.isValid())
                     {
-                        if (startIter != reclist.end())
+                        if (startIter != cached_reclist.end())
                         {
                             if (curtime.secsTo((*startIter)->startts) - 
                                 prerollseconds > idleWaitForRecordingTime * 60)
@@ -1609,13 +1611,13 @@
 {    
     m_isShuttingDown = true;
   
-    RecIter recIter = reclist.begin();
-    for ( ; recIter != reclist.end(); recIter++)
+    RecIter recIter = cached_reclist.begin();
+    for ( ; recIter != cached_reclist.end(); recIter++)
         if ((*recIter)->recstatus == rsWillRecord)
             break;
 
     // set the wakeuptime if needed
-    if (recIter != reclist.end())
+    if (recIter != cached_reclist.end())
     {
         ProgramInfo *nextRecording = (*recIter);
         QDateTime restarttime = nextRecording->startts.addSecs((-1) * 
@@ -2617,4 +2619,23 @@
     }
 }
 
+static void delete_reclist(RecList &reclist)
+{
+    while (reclist.size() > 0)
+    {
+        ProgramInfo *pginfo = reclist.back();
+        delete pginfo;
+        reclist.pop_back();
+    }
+}
+
+static void copy_reclist(RecList &copy, const RecList &orig)
+{
+    delete_reclist(copy);
+
+    RecList::const_iterator it = orig.begin();
+    for (; it != orig.end(); it++)
+        copy.push_back(new ProgramInfo(*(*it)));
+}
+
 /* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: programs/mythbackend/scheduler.h
===================================================================
--- programs/mythbackend/scheduler.h	(revision 11413)
+++ programs/mythbackend/scheduler.h	(working copy)
@@ -38,7 +38,7 @@
                          const QDateTime &startts, RecStatusType recstatus, 
                          const QDateTime &recendts);
 
-    RecList *getAllPending(void) { return &reclist; }
+    RecList *getAllPending(void) { return &cached_reclist; }
     void getAllPending(RecList *retList);
     void getAllPending(QStringList &strList);
 
@@ -89,7 +89,7 @@
     bool TryAnotherShowing(ProgramInfo *p);
     void SchedNewRecords(void);
     void MoveHigherRecords(void);
-    void PruneRedundants(void);
+    bool PruneRedundants(void);
     void UpdateNextRecord(void);
 
     bool ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp);
@@ -104,16 +104,20 @@
     QMutex reschedLock;
     QMutex recordmatchLock;
     QWaitCondition reschedWait;
+
+    RecList cached_reclist;
+    RecList schedlist;
+
+    QMutex *cached_reclist_lock;
+    QMutex *schedlist_lock;
+
+    // temporaries used in scheduler
     RecList reclist;
     RecList retrylist;
-    RecList schedlist;
     QMap<int, RecList> cardlistmap;
     QMap<int, RecList> recordidlistmap;
     QMap<QString, RecList> titlelistmap;
 
-    QMutex *reclist_lock;
-    QMutex *schedlist_lock;
-
     bool specsched;
     bool hasconflicts;
     bool schedMoveHigher;
