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