MythTV  master
threadedfilewriter.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 #ifndef TFW_H_
3 #define TFW_H_
4 
5 #include <cstdint>
6 #include <fcntl.h>
7 #include <utility>
8 #include <vector>
9 using namespace std;
10 
11 // Qt headers
12 #include <QWaitCondition>
13 #include <QDateTime>
14 #include <QString>
15 #include <QMutex>
16 
17 // MythTV headers
18 #include "mythbaseexp.h"
19 #include "mthread.h"
20 
21 class ThreadedFileWriter;
22 
23 class TFWWriteThread : public MThread
24 {
25  public:
26  explicit TFWWriteThread(ThreadedFileWriter *p) : MThread("TFWWrite"), m_parent(p) {}
27  ~TFWWriteThread() override { wait(); m_parent = nullptr; }
28  void run(void) override; // MThread
29  private:
30  ThreadedFileWriter *m_parent {nullptr};
31 };
32 
33 class TFWSyncThread : public MThread
34 {
35  public:
36  explicit TFWSyncThread(ThreadedFileWriter *p) : MThread("TFWSync"), m_parent(p) {}
37  ~TFWSyncThread() override { wait(); m_parent = nullptr; }
38  void run(void) override; // MThread
39  private:
40  ThreadedFileWriter *m_parent {nullptr};
41 };
42 
44 {
45  friend class TFWWriteThread;
46  friend class TFWSyncThread;
47  public:
51  ThreadedFileWriter(QString fname, int flags, mode_t mode)
52  : m_filename(std::move(fname)), m_flags(flags), m_mode(mode) {}
54 
55  bool Open(void);
56  bool ReOpen(const QString& newFilename = "");
57 
58  long long Seek(long long pos, int whence);
59  int Write(const void *data, uint count);
60 
61  void SetWriteBufferMinWriteSize(uint newMinSize = kMinWriteSize);
62 
63  void Sync(void);
64  void Flush(void);
65  bool SetBlocking(bool block = true);
66  bool WritesFailing(void) const { return m_ignoreWrites; }
67 
68  protected:
69  void DiskLoop(void);
70  void SyncLoop(void);
71  void TrimEmptyBuffers(void);
72 
73  private:
74  // file info
75  QString m_filename;
76  int m_flags;
77  mode_t m_mode;
78  int m_fd {-1};
79 
80  // state
81  bool m_flush {false}; // protected by buflock
82  bool m_inDtor {false}; // protected by buflock
83  bool m_ignoreWrites {false}; // protected by buflock
84  uint m_tfwMinWriteSize {kMinWriteSize}; // protected by buflock
85  uint m_totalBufferUse {0}; // protected by buflock
86 
87  // buffers
88  class TFWBuffer
89  {
90  public:
91  vector<char> data;
92  QDateTime lastUsed;
93  };
94  mutable QMutex m_bufLock;
95  QList<TFWBuffer*> m_writeBuffers; // protected by buflock
96  QList<TFWBuffer*> m_emptyBuffers; // protected by buflock
97 
98  // threads
99  TFWWriteThread *m_writeThread {nullptr};
100  TFWSyncThread *m_syncThread {nullptr};
101 
102  // wait conditions
103  QWaitCondition m_bufferEmpty;
104  QWaitCondition m_bufferHasData;
105  QWaitCondition m_bufferSyncWait;
106  QWaitCondition m_bufferWasFreed;
107 
108  // constants
109  static const uint kMaxBufferSize;
111  static const uint kMinWriteSize;
113  static const uint kMaxBlockSize;
114 
115  bool m_warned {false};
116  bool m_blocking {false};
117  bool m_registered {false};
118 };
119 
120 #endif
QList< TFWBuffer * > m_emptyBuffers
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:46
~TFWSyncThread() override
TFWWriteThread(ThreadedFileWriter *p)
QWaitCondition m_bufferWasFreed
TFWSyncThread(ThreadedFileWriter *p)
#define MBASE_PUBLIC
Definition: mythbaseexp.h:15
bool WritesFailing(void) const
QWaitCondition m_bufferEmpty
unsigned int uint
Definition: compat.h:140
QWaitCondition m_bufferSyncWait
~TFWWriteThread() override
static const uint kMaxBlockSize
Maximum block size to write at a time.
This class supports the writing of recordings to disk.
static const uint kMinWriteSize
Minimum to write to disk in a single write, when not flushing buffer.
ThreadedFileWriter(QString fname, int flags, mode_t mode)
Creates a threaded file writer.
QList< TFWBuffer * > m_writeBuffers
QWaitCondition m_bufferHasData
static const uint kMaxBufferSize