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