MythTV  master
scheduler.h
Go to the documentation of this file.
1 #ifndef SCHEDULER_H_
2 #define SCHEDULER_H_
3 
4 // C++ headers
5 #include <deque>
6 #include <vector>
7 using namespace std;
8 
9 // Qt headers
10 #include <QWaitCondition>
11 #include <QObject>
12 #include <QString>
13 #include <QMutex>
14 #include <QMap>
15 #include <QSet>
16 
17 // MythTV headers
18 #include "filesysteminfo.h"
19 #include "recordinginfo.h"
20 #include "remoteutil.h"
21 #include "mythdeque.h"
22 #include "mythscheduler.h"
23 #include "mthread.h"
24 #include "scheduledrecording.h"
25 
26 class EncoderLink;
27 class MainServer;
28 class AutoExpire;
29 
30 class Scheduler;
31 
33 {
34  public:
35  SchedInputInfo(void) = default;;
36  ~SchedInputInfo(void) = default;
37 
38  uint m_inputId {0};
39  uint m_sgroupId {0};
40  bool m_schedGroup {false};
41  vector<uint> m_groupInputs;
42  vector<uint> m_conflictingInputs;
43  RecList *m_conflictList {nullptr};
44 };
45 
46 class Scheduler : public MThread, public MythScheduler
47 {
48  public:
49  Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
50  const QString& tmptable = "record", Scheduler *master_sched = nullptr);
51  ~Scheduler() override;
52 
53  void Stop(void);
54  void Wait(void) { MThread::wait(); }
55 
56  void SetExpirer(AutoExpire *autoExpirer) { m_expirer = autoExpirer; }
57 
58  void Reschedule(const QStringList &request);
59  void RescheduleMatch(uint recordid, uint sourceid, uint mplexid,
60  const QDateTime &maxstarttime, const QString &why)
62  mplexid, maxstarttime, why)); };
63  void RescheduleCheck(const RecordingInfo &recinfo, const QString &why)
65  void ReschedulePlace(const QString &why)
67 
68  void AddRecording(const RecordingInfo &pi);
69  void AddRecording(const ProgramInfo& prog)
70  { AddRecording(RecordingInfo(prog)); };
71  void FillRecordListFromDB(uint recordid = 0);
72  void FillRecordListFromMaster(void);
73 
74  void UpdateRecStatus(RecordingInfo *pginfo);
75  void UpdateRecStatus(uint cardid, uint chanid,
76  const QDateTime &startts, RecStatus::Type recstatus,
77  const QDateTime &recendts);
78  // Returns a list of all pending recordings and returns
79  // true iff there are conflicts
80  bool GetAllPending(RecList &retList, int recRuleId = 0) const;
81  bool GetAllPending(ProgramList &retList, int recRuleId = 0) const;
82  void GetAllPending(QStringList &strList) const override; // MythScheduler
83  QMap<QString,ProgramInfo*> GetRecording(void) const override; // MythScheduler
84 
85  enum SchedSortColumn { kSortTitle, kSortLastRecorded, kSortNextRecording,
86  kSortPriority, kSortType };
87  static void GetAllScheduled(QStringList &strList,
88  SchedSortColumn sortBy = kSortTitle,
89  bool ascending = true);
90  static void GetAllScheduled(RecList &proglist,
91  SchedSortColumn sortBy = kSortTitle,
92  bool ascending = true);
93 
94  void getConflicting(RecordingInfo *pginfo, QStringList &strlist);
95  void getConflicting(RecordingInfo *pginfo, RecList *retlist);
96 
97  void PrintList(bool onlyFutureRecordings = false)
98  { PrintList(m_recList, onlyFutureRecordings); };
99  static void PrintList(RecList &list, bool onlyFutureRecordings = false);
100  static void PrintRec(const RecordingInfo *p, const QString &prefix = "");
101 
102  void SetMainServer(MainServer *ms);
103 
104  void SlaveConnected(RecordingList &slavelist);
105  void SlaveDisconnected(uint cardid);
106 
107  void DisableScheduling(void) { m_schedulingEnabled = false; }
108  void EnableScheduling(void) { m_schedulingEnabled = true; }
109  void GetNextLiveTVDir(uint cardid);
110  void ResetIdleTime(void);
111 
112  static bool WasStartedAutomatically();
113 
114  RecStatus::Type GetRecStatus(const ProgramInfo &pginfo);
115 
116  int GetError(void) const { return m_error; }
117 
118  void AddChildInput(uint parentid, uint inputid);
119  void DelayShutdown();
120 
121  protected:
122  void run(void) override; // MThread
123 
124  private:
125  enum OpenEndType {
126  openEndNever = 0,
127  openEndDiffChannel = 1,
128  openEndAlways = 2
129  };
130 
131  QString m_recordTable;
133 
134  static bool VerifyCards(void);
135 
136  bool InitInputInfoMap(void);
137  void CreateTempTables(void);
138  void DeleteTempTables(void);
139  void UpdateDuplicates(void);
140  bool FillRecordList(void);
141  void UpdateMatches(uint recordid, uint sourceid, uint mplexid,
142  const QDateTime &maxstarttime);
143  void UpdateManuals(uint recordid);
144  void BuildWorkList(void);
145  bool ClearWorkList(void);
146  void AddNewRecords(void);
147  void AddNotListed(void);
148  void BuildNewRecordsQueries(uint recordid, QStringList &from,
149  QStringList &where, MSqlBindings &bindings);
150  void PruneOverlaps(void);
151  void BuildListMaps(void);
152  void ClearListMaps(void);
153 
154  bool IsBusyRecording(const RecordingInfo *rcinfo);
155 
156  bool IsSameProgram(const RecordingInfo *a, const RecordingInfo *b) const;
157 
158  bool FindNextConflict(const RecList &cardlist,
159  const RecordingInfo *p, RecConstIter &iter,
160  OpenEndType openEnd = openEndNever,
161  uint *paffinity = nullptr) const;
162  const RecordingInfo *FindConflict(const RecordingInfo *p,
163  OpenEndType openEnd = openEndNever,
164  uint *affinity = nullptr,
165  bool checkAll = false)
166  const;
167  void MarkOtherShowings(RecordingInfo *p);
168  void MarkShowingsList(RecList &showinglist, RecordingInfo *p);
169  void BackupRecStatus(void);
170  void RestoreRecStatus(void);
171  bool TryAnotherShowing(RecordingInfo *p, bool samePriority,
172  bool livetv = false);
173  void SchedNewRecords(void);
174  void SchedNewFirstPass(RecIter &start, const RecIter& end,
175  int recpriority, int recpriority2);
176  void SchedNewRetryPass(const RecIter& start, const RecIter& end,
177  bool samePriority, bool livetv = false);
178  void SchedLiveTV(void);
179  void PruneRedundants(void);
180  void UpdateNextRecord(void);
181 
182  bool ChangeRecordingEnd(RecordingInfo *oldp, RecordingInfo *newp);
183 
184  static bool CheckShutdownServer(int prerollseconds, QDateTime &idleSince,
185  bool &blockShutdown, uint logmask);
186  void ShutdownServer(int prerollseconds, QDateTime &idleSince);
187  void PutInactiveSlavesToSleep(void);
188  bool WakeUpSlave(const QString& slaveHostname, bool setWakingStatus = true);
189  void WakeUpSlaves(void);
190 
191  int FillRecordingDir(const QString &title,
192  const QString &hostname,
193  const QString &storagegroup,
194  const QDateTime &recstartts,
195  const QDateTime &recendts,
196  uint cardid,
197  QString &recording_dir,
198  const RecList &reclist);
199  void FillDirectoryInfoCache(void);
200 
201  void OldRecordedFixups(void);
202  void ResetDuplicates(uint recordid, uint findid, const QString &title,
203  const QString &subtitle, const QString &descrip,
204  const QString &programid);
205  bool HandleReschedule(void);
206  bool HandleRunSchedulerStartup(
207  int prerollseconds, int idleWaitForRecordingTime);
208  void HandleWakeSlave(RecordingInfo &ri, int prerollseconds);
209  bool HandleRecording(RecordingInfo &ri, bool &statuschanged,
210  QDateTime &nextStartTime, QDateTime &nextWakeTime,
211  int prerollseconds);
212  void HandleRecordingStatusChange(
213  RecordingInfo &ri, RecStatus::Type recStatus, const QString &details);
214  bool AssignGroupInput(RecordingInfo &ri, int prerollseconds);
215  void HandleIdleShutdown(
216  bool &blockShutdown, QDateTime &idleSince, int prerollseconds,
218  bool &statuschanged);
219 
220  void EnqueueMatch(uint recordid, uint sourceid, uint mplexid,
221  const QDateTime &maxstarttime, const QString &why)
222  { m_reschedQueue.enqueue(ScheduledRecording::BuildMatchRequest(recordid,
223  sourceid, mplexid, maxstarttime, why)); };
224  void EnqueueCheck(const RecordingInfo &recinfo, const QString &why)
225  { m_reschedQueue.enqueue(ScheduledRecording::BuildCheckRequest(recinfo,
226  why)); };
227  void EnqueuePlace(const QString &why)
228  { m_reschedQueue.enqueue(ScheduledRecording::BuildPlaceRequest(why)); };
229 
231  { return !m_reschedQueue.empty(); };
232  void ClearRequestQueue(void)
233  { m_reschedQueue.clear(); };
234 
235  bool CreateConflictLists(void);
236 
238  mutable QMutex m_schedLock;
240  QWaitCondition m_reschedWait;
244  QMap<uint, SchedInputInfo> m_sinputInfoMap;
245  vector<RecList *> m_conflictLists;
246  QMap<uint, RecList> m_recordIdListMap;
247  QMap<QString, RecList> m_titleListMap;
248 
249  QDateTime m_schedTime;
250  bool m_recListChanged {false};
251 
253  bool m_schedulingEnabled {true};
254  QMap<int, bool> m_schedAfterStartMap;
255 
256  QMap<int, EncoderLink *> *m_tvList {nullptr};
257  AutoExpire *m_expirer {nullptr};
258 
259  QSet<uint> m_schedOrderWarned;
260 
261  bool m_doRun;
262 
263  MainServer *m_mainServer {nullptr};
264 
266  bool m_resetIdleTime {false};
267 
268  bool m_isShuttingDown {false};
270 
271  QMap<QString, FileSystemInfo> m_fsInfoCache;
272 
273  int m_error {0};
274 
275  QSet<QString> m_sysEvents[4];
276 
277  // Try to avoid LiveTV sessions until this time
278  QDateTime m_livetvTime;
279 
280  QDateTime m_lastPrepareTime;
281  // Delay shutdown util this time (ms since epoch);
282  int64_t m_delayShutdownTime {0};
283 
285 
286  // cache IsSameProgram()
287  using IsSameKey = pair<const RecordingInfo*,const RecordingInfo*>;
288  using IsSameCacheType = QMap<IsSameKey,bool>;
290  int m_tmLastLog {0};
291 };
292 
293 #endif
QMap< QString, FileSystemInfo > m_fsInfoCache
Definition: scheduler.h:271
This is an generic interface to a program scheduler.
Definition: mythscheduler.h:20
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:46
void ClearRequestQueue(void)
Definition: scheduler.h:232
SchedSortColumn
Definition: scheduler.h:85
vector< RecList * > m_conflictLists
Definition: scheduler.h:245
RecList::const_iterator RecConstIter
Definition: mythscheduler.h:16
QMap< QString, RecList > m_titleListMap
Definition: scheduler.h:247
void AddRecording(const ProgramInfo &prog)
Definition: scheduler.h:69
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:311
void EnqueuePlace(const QString &why)
Definition: scheduler.h:227
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:34
MSqlQueryInfo m_dbConn
Definition: scheduler.h:269
QSet< uint > m_schedOrderWarned
Definition: scheduler.h:259
void DisableScheduling(void)
Definition: scheduler.h:107
vector< uint > m_conflictingInputs
Definition: scheduler.h:42
QMap< IsSameKey, bool > IsSameCacheType
Definition: scheduler.h:288
QMap< uint, SchedInputInfo > m_sinputInfoMap
Definition: scheduler.h:244
void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
Definition: scheduler.h:59
static QStringList BuildCheckRequest(const RecordingInfo &recinfo, const QString &why)
Holds information on recordings and videos.
Definition: programinfo.h:67
void EnableScheduling(void)
Definition: scheduler.h:108
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:98
bool m_doRun
Definition: scheduler.h:261
static QStringList BuildMatchRequest(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
QDateTime m_lastPrepareTime
Definition: scheduler.h:280
bool m_specSched
Definition: scheduler.h:252
void RescheduleCheck(const RecordingInfo &recinfo, const QString &why)
Definition: scheduler.h:63
static GlobalSpinBoxSetting * idleTimeoutSecs()
void EnqueueMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
Definition: scheduler.h:220
QString m_priorityTable
Definition: scheduler.h:132
void ReschedulePlace(const QString &why)
Definition: scheduler.h:65
void PrintList(bool onlyFutureRecordings=false)
Definition: scheduler.h:97
QWaitCondition m_reschedWait
Definition: scheduler.h:240
RecList::iterator RecIter
Definition: mythscheduler.h:17
IsSameCacheType m_cacheIsSameProgram
Definition: scheduler.h:289
string hostname
Definition: caa.py:17
bool HaveQueuedRequests(void)
Definition: scheduler.h:230
unsigned int uint
Definition: compat.h:140
QString m_recordTable
Definition: scheduler.h:131
QMap< int, bool > m_schedAfterStartMap
Definition: scheduler.h:254
void SetExpirer(AutoExpire *autoExpirer)
Definition: scheduler.h:56
QMutex m_resetIdleTimeLock
Definition: scheduler.h:265
void Wait(void)
Definition: scheduler.h:54
RecList m_workList
Definition: scheduler.h:242
static GlobalSpinBoxSetting * idleWaitForRecordingTime()
void EnqueueCheck(const RecordingInfo &recinfo, const QString &why)
Definition: scheduler.h:224
QDateTime m_schedTime
Definition: scheduler.h:249
Used to expire recordings to make space for new recordings.
Definition: autoexpire.h:61
std::deque< RecordingInfo * > RecList
Definition: mythscheduler.h:12
static QStringList BuildPlaceRequest(const QString &why)
pair< const RecordingInfo *, const RecordingInfo * > IsSameKey
Definition: scheduler.h:287
RecList m_recList
Definition: scheduler.h:241
QMutex m_recordMatchLock
Definition: scheduler.h:239
static int Reschedule(const MythUtilCommandLineParser &)
QMap< uint, RecList > m_recordIdListMap
Definition: scheduler.h:246
QDateTime m_livetvTime
Definition: scheduler.h:278
OpenEndType m_openEnd
Definition: scheduler.h:284
MythDeque< QStringList > m_reschedQueue
Definition: scheduler.h:237
vector< uint > m_groupInputs
Definition: scheduler.h:41
QMap< int, EncoderLink * > tvList
QMutex m_schedLock
Definition: scheduler.h:238
MSqlDatabase Info, used by MSqlQuery. Do not use directly.
Definition: mythdbcon.h:90
RecList m_livetvList
Definition: scheduler.h:243
int GetError(void) const
Definition: scheduler.h:116