Index: programs/mythbackend/scheduler.cpp
===================================================================
--- programs/mythbackend/scheduler.cpp	(revision 11388)
+++ programs/mythbackend/scheduler.cpp	(working copy)
@@ -76,7 +76,7 @@
     }
 }
 
-Scheduler::~Scheduler()
+static void delete_reclist(RecList &reclist)
 {
     while (reclist.size() > 0)
     {
@@ -86,6 +86,32 @@
     }
 }
 
+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)));
+}
+
+Scheduler::~Scheduler()
+{
+    delete_reclist(reclist);
+
+    if (reclist_lock)
+    {
+        delete reclist_lock;
+        reclist_lock = NULL;
+    }
+
+    if (schedlist_lock)
+    {
+        delete schedlist_lock;
+        schedlist_lock = NULL;
+    }
+}
+
 void Scheduler::SetMainServer(MainServer *ms)
 {
     m_mainServer = ms;
@@ -263,43 +289,58 @@
 
 bool Scheduler::FillRecordList(void)
 {
-    QMutexLocker lockit(reclist_lock);
-
     schedMoveHigher = (bool)gContext->GetNumSetting("SchedMoveHigher");
     schedTime = QDateTime::currentDateTime();
 
-    VERBOSE(VB_SCHEDULE, "PruneOldRecords...");
-    PruneOldRecords();
-    VERBOSE(VB_SCHEDULE, "AddNewRecords...");
-    AddNewRecords();
-    VERBOSE(VB_SCHEDULE, "AddNotListed...");
-    AddNotListed();
+    RecList newlist;
 
+    PruneOldRecords(newlist);
+    AddNewRecords(dbConn, recordTable, specsched, threadrunning,
+                  *m_tvList, newlist);
+    AddNotListed(dbConn, recordTable, newlist);
+  
     VERBOSE(VB_SCHEDULE, "Sort by time...");
-    reclist.sort(comp_overlap);
-    VERBOSE(VB_SCHEDULE, "PruneOverlaps...");
-    PruneOverlaps();
+    newlist.sort(comp_overlap);
 
+    PruneOverlaps(newlist);
+  
     VERBOSE(VB_SCHEDULE, "Sort by priority...");
-    reclist.sort(comp_priority);
-    VERBOSE(VB_SCHEDULE, "BuildListMaps...");
-    BuildListMaps();
-    VERBOSE(VB_SCHEDULE, "SchedNewRecords...");
-    SchedNewRecords();
-    VERBOSE(VB_SCHEDULE, "ClearListMaps...");
-    ClearListMaps();
+    newlist.sort(comp_priority);
 
+    {
+        QMap<int, RecList>     cardlistmap;
+        QMap<int, RecList>     recordidlistmap;
+        QMap<QString, RecList> titlelistmap;
+  
+        BuildListMaps(newlist, cardlistmap, recordidlistmap, titlelistmap);
+
+        RecList retrylist;
+        SchedNewRecords(schedMoveHigher, newlist, retrylist,
+                        cardlistmap, recordidlistmap, titlelistmap);
+    }
+
     VERBOSE(VB_SCHEDULE, "Sort by time...");
-    reclist.sort(comp_redundant);
-    VERBOSE(VB_SCHEDULE, "PruneRedundants...");
-    PruneRedundants();
+    newlist.sort(comp_redundant);
 
+    bool will_have_conflicts = PruneRedundants(newlist);
+
     VERBOSE(VB_SCHEDULE, "Sort by time...");
-    reclist.sort(comp_recstart);
+    newlist.sort(comp_recstart);
 
-    VERBOSE(VB_SCHEDULE, "UpdateNextRecord...");
-    UpdateNextRecord();
+    UpdateNextRecord(dbConn, newlist);
 
+    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locking");
+    reclist_lock->lock();
+    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- locked");
+
+    copy_reclist(reclist, newlist);
+    hasconflicts = will_have_conflicts;
+
+    reclist_lock->unlock();
+    VERBOSE(VB_SCHEDULE, "Scheduler::FillRecordList() -- unlocked");
+
+    delete_reclist(newlist);
+
     return hasconflicts;
 }
 
@@ -479,7 +520,10 @@
     }
 }
 
-bool Scheduler::ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp)
+bool Scheduler::ChangeRecordingEnd(const bool specsched,
+                                   QMap<int, EncoderLink*> &tvList,
+                                   ProgramInfo *oldp,
+                                   ProgramInfo *newp)
 {
     RecordingType oldrectype = oldp->rectype;
     int oldrecordid = oldp->recordid;
@@ -500,7 +544,7 @@
         else
             return true;
     }
-    EncoderLink *tv = (*m_tvList)[oldp->cardid];
+    EncoderLink *tv = tvList[oldp->cardid];
     RecStatusType rs = tv->StartRecording(oldp);
     if (rs != rsRecording)
     {
@@ -590,8 +634,9 @@
     }
 }
 
-void Scheduler::PruneOldRecords(void)
+void Scheduler::PruneOldRecords(RecList &reclist)
 {
+    VERBOSE(VB_SCHEDULE, "PruneOldRecords...");
     RecIter dreciter = reclist.begin();
     while (dreciter != reclist.end())
     {
@@ -610,8 +655,9 @@
     }
 }
 
-void Scheduler::PruneOverlaps(void)
+void Scheduler::PruneOverlaps(RecList &reclist)
 {
+    VERBOSE(VB_SCHEDULE, "PruneOverlaps...");
     ProgramInfo *lastp = NULL;
 
     RecIter dreciter = reclist.begin();
@@ -651,8 +697,12 @@
     }
 }
 
-void Scheduler::BuildListMaps(void)
+void Scheduler::BuildListMaps(RecList                &reclist,
+                              QMap<int, RecList>     &cardlistmap,
+                              QMap<int, RecList>     &recordidlistmap,
+                              QMap<QString, RecList> &titlelistmap)
 {
+    VERBOSE(VB_SCHEDULE, "BuildListMaps...");
     RecIter i = reclist.begin();
     for ( ; i != reclist.end(); i++)
     {
@@ -668,13 +718,6 @@
     }
 }
 
-void Scheduler::ClearListMaps(void)
-{
-    cardlistmap.clear();
-    titlelistmap.clear();
-    recordidlistmap.clear();
-}
-
 bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j)
 {
     for ( ; j != cardlist.end(); j++)
@@ -698,7 +741,9 @@
     return false;
 }
 
-void Scheduler::MarkOtherShowings(ProgramInfo *p)
+void Scheduler::MarkOtherShowings(ProgramInfo *p,
+                                  QMap<int, RecList>     &recordidlistmap,
+                                  QMap<QString, RecList> &titlelistmap)
 {
     RecList *showinglist = &titlelistmap[p->title];
 
@@ -746,7 +791,7 @@
     }
 }
 
-void Scheduler::BackupRecStatus(void)
+void Scheduler::BackupRecStatus(RecList &reclist)
 {
     RecIter i = reclist.begin();
     for ( ; i != reclist.end(); i++)
@@ -756,7 +801,7 @@
     }
 }
 
-void Scheduler::RestoreRecStatus(void)
+void Scheduler::RestoreRecStatus(RecList &reclist)
 {
     RecIter i = reclist.begin();
     for ( ; i != reclist.end(); i++)
@@ -766,7 +811,10 @@
     }
 }
 
-bool Scheduler::TryAnotherShowing(ProgramInfo *p)
+bool Scheduler::TryAnotherShowing(QMap<int, RecList>     &cardlistmap,
+                                  QMap<QString, RecList> &titlelistmap,
+                                  QMap<int, RecList>     &recordidlistmap,
+                                  ProgramInfo *p)
 {
     PrintRec(p, "     >");
 
@@ -815,7 +863,7 @@
         }
 
         q->recstatus = rsWillRecord;
-        MarkOtherShowings(q);
+        MarkOtherShowings(q, recordidlistmap, titlelistmap);
         PrintRec(p, "     -");
         PrintRec(q, "     +");
         return true;
@@ -825,7 +873,12 @@
     return false;
 }
 
-void Scheduler::SchedNewRecords(void)
+void Scheduler::SchedNewRecords(const bool              schedMoveHigher,
+                                RecList                &reclist,
+                                RecList                &retrylist,
+                                QMap<int, RecList>     &cardlistmap,
+                                QMap<int, RecList>     &recordidlistmap,
+                                QMap<QString, RecList> &titlelistmap)
 {
     VERBOSE(VB_SCHEDULE, "Scheduling:");
 
@@ -834,7 +887,7 @@
     {
         ProgramInfo *p = *i;
         if (p->recstatus == rsRecording)
-            MarkOtherShowings(p);
+            MarkOtherShowings(p, recordidlistmap, titlelistmap);
         else if (p->recstatus == rsUnknown)
         {
             RecList &cardlist = cardlistmap[p->cardid];
@@ -842,7 +895,7 @@
             if (!FindNextConflict(cardlist, p, k))
             {
                 p->recstatus = rsWillRecord;
-                MarkOtherShowings(p);
+                MarkOtherShowings(p, recordidlistmap, titlelistmap);
                 PrintRec(p, "  +");
             }
             else
@@ -857,13 +910,19 @@
         i++;
         if (i == reclist.end() || lastpri != (*i)->recpriority)
         {
-            MoveHigherRecords();
+            MoveHigherRecords(schedMoveHigher, reclist, retrylist,
+                              cardlistmap, recordidlistmap, titlelistmap);
             retrylist.clear();
         }
     }
 }
 
-void Scheduler::MoveHigherRecords(void)
+void Scheduler::MoveHigherRecords(const bool              schedMoveHigher,
+                                  RecList                &reclist,
+                                  RecList                &retrylist,
+                                  QMap<int, RecList>     &cardlistmap,
+                                  QMap<int, RecList>     &recordidlistmap,
+                                  QMap<QString, RecList> &titlelistmap)
 {
     RecIter i = retrylist.begin();
     for ( ; i != retrylist.end(); i++)
@@ -874,21 +933,22 @@
 
         PrintRec(p, "  ?");
 
-        if (TryAnotherShowing(p))
+        if (TryAnotherShowing(cardlistmap, titlelistmap, recordidlistmap, p))
             continue;
 
-        BackupRecStatus();
+        BackupRecStatus(reclist);
         p->recstatus = rsWillRecord;
-        MarkOtherShowings(p);
+        MarkOtherShowings(p, recordidlistmap, titlelistmap);
 
         RecList &cardlist = cardlistmap[p->cardid];
         RecIter k = cardlist.begin();
         for ( ; FindNextConflict(cardlist, p, k); k++)
         {
             if ((p->recpriority < (*k)->recpriority && !schedMoveHigher) ||
-                !TryAnotherShowing(*k))
+                !TryAnotherShowing(cardlistmap, titlelistmap,
+                                   recordidlistmap, *k))
             {
-                RestoreRecStatus();
+                RestoreRecStatus(reclist);
                 break;
             }
         }
@@ -898,10 +958,11 @@
     }
 }
 
-void Scheduler::PruneRedundants(void)
+bool Scheduler::PruneRedundants(RecList &reclist)
 {
+    VERBOSE(VB_SCHEDULE, "PruneRedundants...");
     ProgramInfo *lastp = NULL;
-    hasconflicts = false;
+    bool hasconflicts = false;
 
     RecIter i = reclist.begin();
     while (i != reclist.end())
@@ -951,10 +1012,14 @@
             i = reclist.erase(i);
         }
     }
+
+    return hasconflicts;
 }
 
-void Scheduler::UpdateNextRecord(void)
+void Scheduler::UpdateNextRecord(MSqlQueryInfo &dbConn,
+                                 RecList       &reclist)
 {
+    VERBOSE(VB_SCHEDULE, "UpdateNextRecord...");
     QMap<int, QDateTime> nextRecMap;
     QDateTime now = QDateTime::currentDateTime();
 
@@ -1043,57 +1108,27 @@
 {
     QMutexLocker lockit(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, 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);
 
@@ -2008,8 +2043,14 @@
     VERBOSE(VB_SCHEDULE, " +-- Done.");
 }
 
-void Scheduler::AddNewRecords(void) 
+void Scheduler::AddNewRecords(MSqlQueryInfo           &dbConn,
+                              const QString           &recordTable,
+                              const bool               specsched,
+                              const bool               threadrunning,
+                              QMap<int, EncoderLink*> &tvList,
+                              RecList                 &reclist) 
 {
+    VERBOSE(VB_SCHEDULE, "AddNewRecords...");
     struct timeval dbstart, dbend;
 
     QMap<RecordingType, int> recTypeRecPriorityMap;
@@ -2022,8 +2063,8 @@
     int ccpriority      = gContext->GetNumSetting("CCRecPriority", 0);
 
     QMap<int, bool> cardMap;
-    QMap<int, EncoderLink *>::Iterator enciter = m_tvList->begin();
-    for (; enciter != m_tvList->end(); ++enciter)
+    QMap<int, EncoderLink *>::Iterator enciter = tvList.begin();
+    for (; enciter != tvList.end(); ++enciter)
     {
         EncoderLink *enc = enciter.data();
         if (enc->IsConnected())
@@ -2333,7 +2374,9 @@
                     r->recendts != p->recendts &&
                     (r->recordid == p->recordid ||
                      p->rectype == kOverrideRecord))
-                    ChangeRecordingEnd(r, p);
+                {
+                    ChangeRecordingEnd(specsched, tvList, r, p);
+                }
                 delete p;
                 p = NULL;
                 break;
@@ -2390,8 +2433,11 @@
         reclist.push_back(*tmp);
 }
 
-void Scheduler::AddNotListed(void) {
-
+void Scheduler::AddNotListed(MSqlQueryInfo &dbConn,
+                             const QString &recordTable,
+                             RecList       &reclist)
+{
+    VERBOSE(VB_SCHEDULE, "AddNotListed...");
     struct timeval dbstart, dbend;
     RecList tmpList;
 
Index: programs/mythbackend/scheduler.h
===================================================================
--- programs/mythbackend/scheduler.h	(revision 11388)
+++ programs/mythbackend/scheduler.h	(working copy)
@@ -49,7 +49,7 @@
     RecList *getConflicting(ProgramInfo *pginfo);
 
     void PrintList(bool onlyFutureRecordings = false);
-    void PrintRec(ProgramInfo *p, const char *prefix = NULL);
+    static void PrintRec(ProgramInfo *p, const char *prefix = NULL);
 
     bool HasConflicts(void) { return hasconflicts; }
 
@@ -66,50 +66,77 @@
     static void *SchedulerThread(void *param);
 
   private:
-    QString recordTable;
-
     void verifyCards(void);
 
     bool FillRecordList(void);
     void UpdateMatches(int recordid);
     void UpdateManuals(int recordid);
-    void PruneOldRecords(void);
-    void AddNewRecords(void);
-    void AddNotListed(void);
     void BuildNewRecordsQueries(int recordid, QStringList &from, QStringList &where,
                                 MSqlBindings &bindings);
-    void PruneOverlaps(void);
-    void BuildListMaps(void);
-    void ClearListMaps(void);
-    bool FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &iter);
-    void MarkOtherShowings(ProgramInfo *p);
-    void MarkShowingsList(RecList &showinglist, ProgramInfo *p);
-    void BackupRecStatus(void);
-    void RestoreRecStatus(void);
-    bool TryAnotherShowing(ProgramInfo *p);
-    void SchedNewRecords(void);
-    void MoveHigherRecords(void);
-    void PruneRedundants(void);
-    void UpdateNextRecord(void);
 
-    bool ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp);
-
     void findAllScheduledPrograms(list<ProgramInfo *> &proglist);
     bool CheckShutdownServer(int prerollseconds, QDateTime &idleSince,
                              bool &blockShutdown);
     void ShutdownServer(int prerollseconds);
 
+    // statics
+    static void PruneOldRecords(RecList               &reclist);
+    static void AddNewRecords(MSqlQueryInfo           &dbConn,
+                              const QString           &recordTable,
+                              bool                     specsched,
+                              bool                     threadrunning,
+                              QMap<int, EncoderLink*> &tvList,
+                              RecList                 &reclist);
+    static void AddNotListed(MSqlQueryInfo            &dbConn,
+                             const QString            &recordTable,
+                             RecList                  &reclist);
+    static void PruneOverlaps(RecList                 &reclist);
+    static void BuildListMaps(RecList                 &reclist,
+                              QMap<int, RecList>      &cardlistmap,
+                              QMap<int, RecList>      &recordidlistmap,
+                              QMap<QString, RecList>  &titlelistmap);
+    static bool FindNextConflict(RecList                   &cardlist,
+                                 ProgramInfo               *p,
+                                 RecIter                   &iter);
+    static void MarkOtherShowings(ProgramInfo              *p,
+                                  QMap<int, RecList>       &recordidlistmap,
+                                  QMap<QString, RecList>   &titlelistmap);
+    static void MarkShowingsList(RecList                   &showinglist,
+                                 ProgramInfo               *p);
+    static void BackupRecStatus(RecList                    &reclist);
+    static void RestoreRecStatus(RecList                   &reclist);
+    static bool TryAnotherShowing(QMap<int, RecList>       &cardlistmap,
+                                  QMap<QString, RecList>   &titlelistmap,
+                                  QMap<int, RecList>       &recordidlistmap,
+                                  ProgramInfo              *p);
+    static void SchedNewRecords(bool                        schedMoveHigher,
+                                RecList                    &reclist,
+                                RecList                    &retrylist,
+                                QMap<int, RecList>         &cardlistmap,
+                                QMap<int, RecList>         &recordidlistmap,
+                                QMap<QString, RecList>     &titlelistmap);
+    static void MoveHigherRecords(bool                      schedMoveHigher,
+                                  RecList                  &reclist,
+                                  RecList                  &retrylist,
+                                  QMap<int, RecList>       &cardlistmap,
+                                  QMap<int, RecList>       &recordidlistmap,
+                                  QMap<QString, RecList>   &titlelistmap);
+    static bool PruneRedundants(RecList                    &reclist);
+    static void UpdateNextRecord(MSqlQueryInfo             &dbConn,
+                                 RecList                   &reclist);
+    static bool ChangeRecordingEnd(bool                     specsched,
+                                   QMap<int, EncoderLink*> &tvList,
+                                   ProgramInfo             *oldp,
+                                   ProgramInfo             *newp);
 
+  private:
+    QString recordTable;
     QValueList<int> reschedQueue;
     QMutex reschedLock;
     QMutex recordmatchLock;
     QWaitCondition reschedWait;
     RecList reclist;
-    RecList retrylist;
     RecList schedlist;
-    QMap<int, RecList> cardlistmap;
-    QMap<int, RecList> recordidlistmap;
-    QMap<QString, RecList> titlelistmap;
 
     QMutex *reclist_lock;
     QMutex *schedlist_lock;
