00001 #ifndef SCHEDULER_H_
00002 #define SCHEDULER_H_
00003
00004
00005 #include <deque>
00006 #include <vector>
00007 using namespace std;
00008
00009
00010 #include <qmutex.h>
00011 #include <qwaitcondition.h>
00012 #include <qmap.h>
00013 #include <qobject.h>
00014
00015
00016 #include "scheduledrecording.h"
00017 #include "programinfo.h"
00018 #include "remoteutil.h"
00019 #include "inputgroupmap.h"
00020
00021 class EncoderLink;
00022 class MainServer;
00023 class AutoExpire;
00024
00025 #define USE_DEQUE_RECLIST 1
00026 typedef deque<ProgramInfo*> RecList;
00027 #define SORT_RECLIST(LIST, ORDER) \
00028 do { stable_sort((LIST).begin(), (LIST).end(), ORDER); } while (0)
00029
00030 typedef RecList::const_iterator RecConstIter;
00031 typedef RecList::iterator RecIter;
00032 typedef RecList::const_iterator RecConstIter;
00033
00034 class Scheduler : public QObject
00035 {
00036 public:
00037 Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
00038 QString recordTbl = "record", Scheduler *master_sched = NULL);
00039 ~Scheduler();
00040
00041 void SetExpirer(AutoExpire *autoExpirer) { expirer = autoExpirer; }
00042
00043 void Reschedule(int recordid);
00044 void AddRecording(const ProgramInfo&);
00045 void FillRecordListFromDB(int recordid = -1);
00046 void FillRecordListFromMaster(void);
00047
00048 void UpdateRecStatus(ProgramInfo *pginfo);
00049 void UpdateRecStatus(int cardid, const QString &chanid,
00050 const QDateTime &startts, RecStatusType recstatus,
00051 const QDateTime &recendts);
00052
00053 bool getAllPending(RecList *retList);
00054 void getAllPending(QStringList &strList);
00055
00056 void getAllScheduled(QStringList &strList);
00057
00058 void getConflicting(ProgramInfo *pginfo, QStringList &strlist);
00059 void getConflicting(ProgramInfo *pginfo, RecList *retlist);
00060
00061 void PrintList(bool onlyFutureRecordings = false)
00062 { PrintList(reclist, onlyFutureRecordings); };
00063 void PrintList(RecList &list, bool onlyFutureRecordings = false);
00064 void PrintRec(const ProgramInfo *p, const char *prefix = NULL);
00065
00066 void SetMainServer(MainServer *ms);
00067
00068 void SlaveConnected(ProgramList &slavelist);
00069 void SlaveDisconnected(int cardid);
00070
00071 void DisableScheduling(void) { schedulingEnabled = false; }
00072 void EnableScheduling(void) { schedulingEnabled = true; }
00073 void GetNextLiveTVDir(int cardid);
00074 void ResetIdleTime(void);
00075
00076 protected:
00077 void RunScheduler(void);
00078 static void *SchedulerThread(void *param);
00079
00080 private:
00081 QString recordTable;
00082 QString priorityTable;
00083
00084 void verifyCards(void);
00085
00086 bool FillRecordList(void);
00087 void UpdateMatches(int recordid);
00088 void UpdateManuals(int recordid);
00089 void BuildWorkList(void);
00090 bool ClearWorkList(void);
00091 void AddNewRecords(void);
00092 void AddNotListed(void);
00093 void BuildNewRecordsQueries(int recordid, QStringList &from, QStringList &where,
00094 MSqlBindings &bindings);
00095 void PruneOverlaps(void);
00096 void BuildListMaps(void);
00097 void ClearListMaps(void);
00098
00099 bool IsBusyRecording(const ProgramInfo *rcinfo);
00100
00101 bool IsSameProgram(const ProgramInfo *a, const ProgramInfo *b) const;
00102
00103 bool FindNextConflict(const RecList &cardlist,
00104 const ProgramInfo *p, RecConstIter &iter,
00105 bool openEnd = false) const;
00106 const ProgramInfo *FindConflict(const QMap<int, RecList> &reclists,
00107 const ProgramInfo *p, bool openEnd = false) const;
00108 void MarkOtherShowings(ProgramInfo *p);
00109 void MarkShowingsList(RecList &showinglist, ProgramInfo *p);
00110 void BackupRecStatus(void);
00111 void RestoreRecStatus(void);
00112 bool TryAnotherShowing(ProgramInfo *p, bool samePriority,
00113 bool preserveLive = false);
00114 void SchedNewRecords(void);
00115 void MoveHigherRecords(bool move_this = true);
00116 void SchedPreserveLiveTV(void);
00117 void PruneRedundants(void);
00118 void UpdateNextRecord(void);
00119
00120 bool ChangeRecordingEnd(ProgramInfo *oldp, ProgramInfo *newp);
00121
00122 void findAllScheduledPrograms(RecList &proglist);
00123 bool CheckShutdownServer(int prerollseconds, QDateTime &idleSince,
00124 bool &blockShutdown);
00125 void ShutdownServer(int prerollseconds, QDateTime &idleSince);
00126
00127 bool WasStartedAutomatically();
00128
00129 int FillRecordingDir(ProgramInfo *pginfo, RecList& reclist);
00130 void FillDirectoryInfoCache(bool force = false);
00131
00132 QValueList<int> reschedQueue;
00133 QMutex reschedLock;
00134 QMutex recordmatchLock;
00135 QWaitCondition reschedWait;
00136 RecList reclist;
00137 RecList worklist;
00138 RecList retrylist;
00139 QMap<int, RecList> cardlistmap;
00140 QMap<int, RecList> recordidlistmap;
00141 QMap<QString, RecList> titlelistmap;
00142 InputGroupMap igrp;
00143
00144 QMutex *reclist_lock;
00145 bool reclist_changed;
00146
00147 bool specsched;
00148 bool schedMoveHigher;
00149 bool schedulingEnabled;
00150 QMap<int, bool> schedAfterStartMap;
00151
00152 QMap<int, EncoderLink *> *m_tvList;
00153 AutoExpire *expirer;
00154
00155 QMap<QString, bool> recPendingList;
00156
00157 pthread_t schedThread;
00158 bool threadrunning;
00159
00160 MainServer *m_mainServer;
00161
00162 QMutex resetIdleTime_lock;
00163 bool resetIdleTime;
00164
00165 bool m_isShuttingDown;
00166 MSqlQueryInfo dbConn;
00167
00168 QDateTime fsInfoCacheFillTime;
00169 QMap<QString, FileSystemInfo> fsInfoCache;
00170
00171
00172 QDateTime livetvTime;
00173 int livetvpriority;
00174 int prefinputpri;
00175 QMap<QString, bool> hasLaterList;
00176
00177
00178 typedef pair<const ProgramInfo*,const ProgramInfo*> IsSameKey;
00179 typedef QMap<IsSameKey,bool> IsSameCacheType;
00180 mutable IsSameCacheType cache_is_same_program;
00181 };
00182
00183 #endif