MythTV  master
mainserver.h
Go to the documentation of this file.
1 #ifndef MAINSERVER_H_
2 #define MAINSERVER_H_
3 
4 #include <QReadWriteLock>
5 #include <QStringList>
6 #include <QRunnable>
7 #include <QEvent>
8 #include <QMutex>
9 #include <QHash>
10 #include <QMap>
11 
12 #include <vector>
13 using namespace std;
14 
15 #include "tv.h"
16 #include "playbacksock.h"
17 #include "mthreadpool.h"
18 #include "encoderlink.h"
19 #include "exitcodes.h"
20 #include "filetransfer.h"
21 #include "scheduler.h"
22 #include "livetvchain.h"
23 #include "autoexpire.h"
24 #include "mythsocket.h"
25 #include "mythdeque.h"
26 #include "mythdownloadmanager.h"
27 
28 #ifdef DeleteFile
29 #undef DeleteFile
30 #endif
31 
32 class QUrl;
33 class MythServer;
34 class QTimer;
35 class FileSystemInfo;
36 class MetadataFactory;
37 class FreeSpaceUpdater;
38 
40 {
41  friend class MainServer;
42  public:
43  DeleteStruct(MainServer *ms, const QString& filename, const QString& title,
44  uint chanid, QDateTime recstartts, QDateTime recendts,
45  uint recordedId,
46  bool forceMetadataDelete) :
47  m_ms(ms), m_filename(filename), m_title(title),
48  m_chanid(chanid), m_recstartts(recstartts),
49  m_recendts(recendts), m_recordedid(recordedId),
50  m_forceMetadataDelete(forceMetadataDelete)
51  {
52  }
53 
54  DeleteStruct(MainServer *ms, const QString& filename, int fd, off_t size) :
55  m_ms(ms), m_filename(filename), m_fd(fd), m_size(size)
56  {
57  }
58 
59  protected:
60  MainServer *m_ms {nullptr};
61  QString m_filename;
62  QString m_title;
63  uint m_chanid {0};
64  QDateTime m_recstartts;
65  QDateTime m_recendts;
66  uint m_recordedid {0};
67  bool m_forceMetadataDelete {false};
68  int m_fd {-1};
69  off_t m_size {0};
70 };
71 
72 class DeleteThread : public QRunnable, public DeleteStruct
73 {
74  public:
75  DeleteThread(MainServer *ms, const QString& filename, const QString& title, uint chanid,
76  QDateTime recstartts, QDateTime recendts, uint recordingId,
77  bool forceMetadataDelete) :
78  DeleteStruct(ms, filename, title, chanid, recstartts,
79  recendts, recordingId, forceMetadataDelete) {}
80  void start(void)
81  { MThreadPool::globalInstance()->startReserved(this, "DeleteThread"); }
82  void run(void) override; // QRunnable
83 };
84 
85 class TruncateThread : public QRunnable, public DeleteStruct
86 {
87  public:
88  TruncateThread(MainServer *ms, const QString& filename, int fd, off_t size) :
89  DeleteStruct(ms, filename, fd, size) {}
90  void start(void)
91  { MThreadPool::globalInstance()->start(this, "Truncate"); }
92  void run(void) override; // QRunnable
93 };
94 
95 class RenameThread : public QRunnable
96 {
97 public:
99  const QString& src, const QString& dst)
100  : m_ms(ms), m_pbs(pbs), m_src(src), m_dst(dst) {}
101  void run(void) override; // QRunnable
102 
103 private:
104  static QMutex s_renamelock;
105 
108  QString m_src, m_dst;
109 };
110 
111 class MainServer : public QObject, public MythSocketCBs
112 {
113  Q_OBJECT
114 
115  friend class DeleteThread;
116  friend class TruncateThread;
117  friend class FreeSpaceUpdater;
118  friend class RenameThread;
119  public:
120  MainServer(bool master, int port,
121  QMap<int, EncoderLink *> *tvList,
123 
124  ~MainServer();
125 
126  void Stop(void);
127 
128  void customEvent(QEvent *e) override; // QObject
129 
130  bool isClientConnected(bool onlyBlockingClients = false);
131  void ShutSlaveBackendsDown(QString &haltcmd);
132 
133  void ProcessRequest(MythSocket *sock);
134 
135  void readyRead(MythSocket *socket) override; // MythSocketCBs
136  void connectionClosed(MythSocket *socket) override; // MythSocketCBs
137  void connectionFailed(MythSocket *socket) override // MythSocketCBs
138  { (void)socket; }
139  void connected(MythSocket *socket) override // MythSocketCBs
140  { (void)socket; }
141 
142  void DeletePBS(PlaybackSock *sock);
143 
144  size_t GetCurrentMaxBitrate(void);
145  void BackendQueryDiskSpace(QStringList &strlist, bool consolidated,
146  bool allHosts);
147  void GetFilesystemInfos(QList<FileSystemInfo> &fsInfos,
148  bool useCache=true);
149 
150  int GetExitCode() const { return m_exitCode; }
151 
152  void UpdateSystemdStatus(void);
153 
154  protected slots:
155  void reconnectTimeout(void);
156  void deferredDeleteSlot(void);
157  void autoexpireUpdate(void);
158 
159  private slots:
160  void NewConnection(qt_socket_fd_t socketDescriptor);
161 
162  private:
163 
164  void ProcessRequestWork(MythSocket *sock);
165  void HandleAnnounce(QStringList &slist, QStringList commands,
166  MythSocket *socket);
167  void HandleDone(MythSocket *socket);
168 
169  void GetActiveBackends(QStringList &hosts);
170  void HandleActiveBackendsQuery(PlaybackSock *pbs);
171  void HandleIsActiveBackendQuery(QStringList &slist, PlaybackSock *pbs);
172  void HandleMoveFile(PlaybackSock *pbs, const QString &storagegroup,
173  const QString &src, const QString &dst);
174  bool HandleDeleteFile(QStringList &slist, PlaybackSock *pbs);
175  bool HandleDeleteFile(const QString& filename, const QString& storagegroup,
176  PlaybackSock *pbs = nullptr);
177  void HandleQueryRecordings(const QString& type, PlaybackSock *pbs);
178  void HandleQueryRecording(QStringList &slist, PlaybackSock *pbs);
179  void HandleStopRecording(QStringList &slist, PlaybackSock *pbs);
180  void DoHandleStopRecording(RecordingInfo &recinfo, PlaybackSock *pbs);
181  void HandleDeleteRecording(QString &chanid, QString &starttime,
182  PlaybackSock *pbs, bool forceMetadataDelete,
183  bool forgetHistory);
184  void HandleDeleteRecording(QStringList &slist, PlaybackSock *pbs,
185  bool forceMetadataDelete);
186  void DoHandleDeleteRecording(RecordingInfo &recinfo, PlaybackSock *pbs,
187  bool forceMetadataDelete, bool expirer=false,
188  bool forgetHistory=false);
189  void HandleUndeleteRecording(QStringList &slist, PlaybackSock *pbs);
190  void DoHandleUndeleteRecording(RecordingInfo &recinfo, PlaybackSock *pbs);
191  void HandleForgetRecording(QStringList &slist, PlaybackSock *pbs);
192  void HandleRescheduleRecordings(const QStringList &request,
193  PlaybackSock *pbs);
194  bool HandleAddChildInput(uint inputid);
195  void HandleGoToSleep(PlaybackSock *pbs);
196  void HandleQueryFreeSpace(PlaybackSock *pbs, bool allHosts);
197  void HandleQueryFreeSpaceSummary(PlaybackSock *pbs);
198  void HandleQueryCheckFile(QStringList &slist, PlaybackSock *pbs);
199  void HandleQueryFileExists(QStringList &slist, PlaybackSock *pbs);
200  void HandleQueryFindFile(QStringList &slist, PlaybackSock *pbs);
201  void HandleQueryFileHash(QStringList &slist, PlaybackSock *pbs);
202  void HandleQueryGuideDataThrough(PlaybackSock *pbs);
203  void HandleGetPendingRecordings(PlaybackSock *pbs, const QString& table = "", int recordid=-1);
204  void HandleGetScheduledRecordings(PlaybackSock *pbs);
205  void HandleGetConflictingRecordings(QStringList &slist, PlaybackSock *pbs);
206  void HandleGetExpiringRecordings(PlaybackSock *pbs);
207  void HandleSGGetFileList(QStringList &sList, PlaybackSock *pbs);
208  void HandleSGFileQuery(QStringList &sList, PlaybackSock *pbs);
209  void HandleGetFreeInputInfo(PlaybackSock *pbs, uint excluded_input);
210  void HandleGetNextFreeRecorder(QStringList &slist, PlaybackSock *pbs);
211  void HandleGetFreeRecorder(PlaybackSock *pbs);
212  void HandleGetFreeRecorderCount(PlaybackSock *pbs);
213  void HandleGetFreeRecorderList(PlaybackSock *pbs);
214  void HandleGetConnectedRecorderList(PlaybackSock *pbs);
215  void HandleRecorderQuery(QStringList &slist, QStringList &commands,
216  PlaybackSock *pbs);
217  void HandleSetNextLiveTVDir(QStringList &commands, PlaybackSock *pbs);
218  void HandleFileTransferQuery(QStringList &slist, QStringList &commands,
219  PlaybackSock *pbs);
220  void HandleGetRecorderNum(QStringList &slist, PlaybackSock *pbs);
221  void HandleGetRecorderFromNum(QStringList &slist, PlaybackSock *pbs);
222  void HandleMessage(QStringList &slist, PlaybackSock *pbs);
223  void HandleSetVerbose(QStringList &slist, PlaybackSock *pbs);
224  void HandleSetLogLevel(QStringList &slist, PlaybackSock *pbs);
225  void HandleGenPreviewPixmap(QStringList &slist, PlaybackSock *pbs);
226  void HandlePixmapLastModified(QStringList &slist, PlaybackSock *pbs);
227  void HandlePixmapGetIfModified(const QStringList &slist, PlaybackSock *pbs);
228  void HandleIsRecording(QStringList &slist, PlaybackSock *pbs);
229  void HandleCheckRecordingActive(QStringList &slist, PlaybackSock *pbs);
230  void HandleFillProgramInfo(QStringList &slist, PlaybackSock *pbs);
231  void HandleSetChannelInfo(QStringList &slist, PlaybackSock *pbs);
232  void HandleRemoteEncoder(QStringList &slist, QStringList &commands,
233  PlaybackSock *pbs);
234  void HandleLockTuner(PlaybackSock *pbs, int cardid = -1);
235  void HandleFreeTuner(int cardid, PlaybackSock *pbs);
236  void HandleCutMapQuery(const QString &chanid, const QString &starttime,
237  PlaybackSock *pbs, bool commbreak);
238  void HandleCommBreakQuery(const QString &chanid, const QString &starttime,
239  PlaybackSock *pbs);
240  void HandleCutlistQuery(const QString &chanid, const QString &starttime,
241  PlaybackSock *pbs);
242  void HandleBookmarkQuery(const QString &chanid, const QString &starttime,
243  PlaybackSock *pbs);
244  void HandleSetBookmark(QStringList &tokens, PlaybackSock *pbs);
245  void HandleSettingQuery(QStringList &tokens, PlaybackSock *pbs);
246  void HandleSetSetting(QStringList &tokens, PlaybackSock *pbs);
247  void HandleScanVideos(PlaybackSock *pbs);
248  void HandleScanMusic(const QStringList &slist, PlaybackSock *pbs);
249  void HandleMusicTagUpdateVolatile(const QStringList &slist, PlaybackSock *pbs);
250  void HandleMusicTagUpdateMetadata(const QStringList &slist, PlaybackSock *pbs);
251  void HandleMusicFindAlbumArt(const QStringList &slist, PlaybackSock *pbs);
252  void HandleMusicTagGetImage(const QStringList &slist, PlaybackSock *pbs);
253  void HandleMusicTagAddImage(const QStringList &slist, PlaybackSock *pbs);
254  void HandleMusicTagRemoveImage(const QStringList &slist, PlaybackSock *pbs);
255  void HandleMusicTagChangeImage(const QStringList &slist, PlaybackSock *pbs);
256  void HandleMusicCalcTrackLen(const QStringList &slist, PlaybackSock *pbs);
257  void HandleMusicFindLyrics(const QStringList &slist, PlaybackSock *pbs);
258  void HandleMusicGetLyricGrabbers(const QStringList &slist, PlaybackSock *pbs);
259  void HandleMusicSaveLyrics(const QStringList &slist, PlaybackSock *pbs);
260  void HandleVersion(MythSocket *socket, const QStringList &slist);
261  void HandleBackendRefresh(MythSocket *socket);
262  void HandleQueryLoad(PlaybackSock *pbs);
263  void HandleQueryUptime(PlaybackSock *pbs);
264  void HandleQueryHostname(PlaybackSock *pbs);
265  void HandleQueryMemStats(PlaybackSock *pbs);
266  void HandleQueryTimeZone(PlaybackSock *pbs);
267  void HandleBlockShutdown(bool blockShutdown, PlaybackSock *pbs);
268  void HandleDownloadFile(const QStringList &command, PlaybackSock *pbs);
269  void HandleSlaveDisconnectedEvent(const MythEvent &event);
270 
271  void SendResponse(MythSocket *sock, QStringList &commands);
272  void SendErrorResponse(MythSocket *sock, const QString &error);
273  void SendErrorResponse(PlaybackSock *pbs, const QString &error);
274  void SendSlaveDisconnectedEvent(const QList<uint> &offlineEncoderIDs,
275  bool needsReschedule);
276 
277  void getGuideDataThrough(QDateTime &GuideDataThrough);
278 
279  PlaybackSock *GetSlaveByHostname(const QString &hostname);
280  PlaybackSock *GetMediaServerByHostname(const QString &hostname);
281  PlaybackSock *GetPlaybackBySock(MythSocket *socket);
282  FileTransfer *GetFileTransferByID(int id);
283  FileTransfer *GetFileTransferBySock(MythSocket *socket);
284 
285  QString LocalFilePath(const QString &path, const QString &wantgroup);
286 
287  int GetfsID(const QList<FileSystemInfo>::iterator& fsInfo);
288 
289  void DoTruncateThread(DeleteStruct *ds);
290  void DoDeleteThread(DeleteStruct *ds);
291  void DeleteRecordedFiles(DeleteStruct *ds);
292  void DoDeleteInDB(DeleteStruct *ds);
293 
294  LiveTVChain *GetExistingChain(const QString &id);
295  LiveTVChain *GetExistingChain(const MythSocket *sock);
296  LiveTVChain *GetChainWithRecording(const ProgramInfo &pginfo);
297  void AddToChains(LiveTVChain *chain);
298  void DeleteChain(LiveTVChain *chain);
299 
300  void SetExitCode(int exitCode, bool closeApplication);
301 
302  static int DeleteFile(const QString &filename, bool followLinks,
303  bool deleteBrokenSymlinks = false);
304  static int OpenAndUnlink(const QString &filename);
305  static bool TruncateAndClose(ProgramInfo *pginfo,
306  int fd, const QString &filename,
307  off_t fsize);
308 
309  vector<LiveTVChain*> m_liveTVChains;
311 
312  QMap<int, EncoderLink *> *m_encoderList {nullptr};
313 
314  MythServer *m_mythserver {nullptr};
315  MetadataFactory *m_metadatafactory {nullptr};
316 
317  QReadWriteLock m_sockListLock;
318  vector<PlaybackSock *> m_playbackList;
319  vector<FileTransfer *> m_fileTransferList;
320  QSet<MythSocket*> m_controlSocketList;
321  vector<MythSocket*> m_decrRefSocketList;
322 
324  FreeSpaceUpdater * volatile m_masterFreeSpaceListUpdater {nullptr};
327 
328  QTimer *m_masterServerReconnect {nullptr}; // audited ref #5318
329  PlaybackSock *m_masterServer {nullptr};
330 
332 
333  QMutex m_deletelock;
335 
336  bool m_masterBackendOverride {false};
337 
338  Scheduler *m_sched {nullptr};
339  AutoExpire *m_expirer {nullptr};
341 
343  {
345  QDateTime ts;
346  };
347 
349  QTimer *m_deferredDeleteTimer {nullptr}; // audited ref #5318
351 
352  QTimer *m_autoexpireUpdateTimer {nullptr}; // audited ref #5318
354 
355  QMap<QString, int> m_fsIDcache;
357  QList<FileSystemInfo> m_fsInfosCache;
359 
361  QMap<QString, QString> m_downloadURLs;
362 
363  int m_exitCode {GENERIC_EXIT_OK};
364 
365  typedef QHash<QString,QString> RequestedBy;
367 
368  bool m_stopped {false};
369 
371 };
372 
373 #endif
374 
375 /* vim: set expandtab tabstop=4 shiftwidth=4: */
vector< MythSocket * > m_decrRefSocketList
Definition: mainserver.h:321
void connected(MythSocket *socket) override
Definition: mainserver.h:139
QHash< QString, QString > RequestedBy
Definition: mainserver.h:365
QMutex m_downloadURLsLock
Definition: mainserver.h:360
unsigned int slots[4]
Definition: element.c:38
void startReserved(QRunnable *runnable, QString debugName, int waitForAvailMS=0)
QMutex m_deferredDeleteLock
Definition: mainserver.h:348
vector< FileTransfer * > m_fileTransferList
Definition: mainserver.h:319
void start(void)
Definition: mainserver.h:90
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
RequestedBy m_previewRequestedBy
Definition: mainserver.h:366
QDateTime m_recstartts
Definition: mainserver.h:64
QMutex m_fsInfosCacheLock
Definition: mainserver.h:358
static const uint kMasterServerReconnectTimeout
Definition: mainserver.h:370
static void error(const char *str,...)
Definition: vbi.c:42
MythDeque< DeferredDeleteStruct > m_deferredDeleteList
Definition: mainserver.h:350
static QMutex s_renamelock
Definition: mainserver.h:104
DeleteStruct(MainServer *ms, const QString &filename, int fd, off_t size)
Definition: mainserver.h:54
QList< FileSystemInfo > m_fsInfosCache
Definition: mainserver.h:357
static QMutex s_truncate_and_close_lock
Definition: mainserver.h:353
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:34
QMutex m_deletelock
Definition: mainserver.h:333
unsigned int uint
Definition: compat.h:140
qintptr qt_socket_fd_t
Definition: mythqtcompat.h:4
void start(void)
Definition: mainserver.h:80
vector< LiveTVChain * > m_liveTVChains
Definition: mainserver.h:309
#define off_t
DeleteThread(MainServer *ms, const QString &filename, const QString &title, uint chanid, QDateTime recstartts, QDateTime recendts, uint recordingId, bool forceMetadataDelete)
Definition: mainserver.h:75
Holds information on recordings and videos.
Definition: programinfo.h:66
static int run(MythMediaDevice *dev=nullptr, bool startRandomShow=false)
This class is used as a container for messages.
Definition: mythevent.h:16
QStringList m_masterFreeSpaceList
Definition: mainserver.h:326
QMap< QString, int > m_fsIDcache
Definition: mainserver.h:355
QString m_src
Definition: mainserver.h:108
vector< PlaybackSock * > m_playbackList
Definition: mainserver.h:318
RenameThread(MainServer &ms, PlaybackSock &pbs, const QString &src, const QString &dst)
Definition: mainserver.h:98
string hostname
Definition: caa.py:17
bool m_ismaster
Definition: mainserver.h:331
void connectionFailed(MythSocket *socket) override
Definition: mainserver.h:137
int GetExitCode() const
Definition: mainserver.h:150
QString m_filename
Definition: mainserver.h:61
QString m_title
Definition: mainserver.h:62
DeleteStruct(MainServer *ms, const QString &filename, const QString &title, uint chanid, QDateTime recstartts, QDateTime recendts, uint recordedId, bool forceMetadataDelete)
Definition: mainserver.h:43
static MThreadPool * globalInstance(void)
MainServer & m_ms
Definition: mainserver.h:106
QMutex m_addChildInputLock
Definition: mainserver.h:340
Definition: pbs.py:1
QReadWriteLock m_sockListLock
Definition: mainserver.h:317
void start(QRunnable *runnable, const QString &debugName, int priority=0)
QMap< QString, QString > m_downloadURLs
Definition: mainserver.h:361
Used to expire recordings to make space for new recordings.
Definition: autoexpire.h:61
AutoExpire * expirer
QSet< MythSocket * > m_controlSocketList
Definition: mainserver.h:320
QDateTime m_recendts
Definition: mainserver.h:65
Class for communcating between myth backends and frontends.
Definition: mythsocket.h:26
Scheduler * sched
QWaitCondition m_masterFreeSpaceListWait
Definition: mainserver.h:325
QMutex m_fsIDcacheLock
Definition: mainserver.h:356
QMutex m_masterFreeSpaceListLock
Definition: mainserver.h:323
PlaybackSock & m_pbs
Definition: mainserver.h:107
TruncateThread(MainServer *ms, const QString &filename, int fd, off_t size)
Definition: mainserver.h:88
Keeps track of recordings in a current LiveTV instance.
Definition: livetvchain.h:31
QMap< int, EncoderLink * > tvList
MThreadPool m_threadPool
Definition: mainserver.h:334
QMutex m_liveTVChainsLock
Definition: mainserver.h:310
MythDeque is similar to QPtrQueue, while being based off deque, this allows that items that are not a...
Definition: mythdeque.h:28