MythTV  master
programinfoupdater.cpp
Go to the documentation of this file.
1 // MythTV headers
2 #include "programinfoupdater.h"
3 #include "mthreadpool.h"
4 #include "mythlogging.h"
5 #include "mythcorecontext.h"
6 #include "remoteutil.h"
7 
8 #include <unistd.h> // for usleep()
9 
11  uint recordedid, PIAction action, uint64_t filesize)
12 {
13  QMutexLocker locker(&m_lock);
15  {
16  QHash<uint,PIKeyData>::iterator it = m_needsUpdate.find(recordedid);
17  // If there is no action in the set we can insert
18  // If it is the same type of action we can overwrite,
19  // If it the new action is a full update we can overwrite
20  if (it == m_needsUpdate.end())
21  m_needsUpdate.insert(recordedid, PIKeyData(action, filesize));
22  else if (((*it).m_action == action) || (kPIUpdate == action))
23  (*it) = PIKeyData(action, filesize);
24  }
25  else
26  {
27  m_needsAddDelete.emplace_back(recordedid, action);
28  }
29 
30  // Start a new run() if one isn't already running..
31  // The lock prevents anything from getting stuck on a queue.
32  if (!m_isRunning)
33  {
34  m_isRunning = true;
35  MThreadPool::globalInstance()->start(this, "ProgramInfoUpdater");
36  }
37  else
38  m_moreWork.wakeAll();
39 }
40 
42 {
43  bool workDone = false;
44 
45  do {
46  workDone = false;
47 
48  // we don't need instant updates allow a few to queue up
49  // if they come in quick succession, this allows multiple
50  // updates to be consolidated into one update...
51  usleep(200 * 1000); // 200ms
52 
53  m_lock.lock();
54 
55  // send adds and deletes in the order they were queued
56  auto ita = m_needsAddDelete.begin();
57  for (; ita != m_needsAddDelete.end(); ++ita)
58  {
59  if (kPIAdd != (*ita).m_action && kPIDelete != (*ita).m_action)
60  continue;
61 
62  QString type = (kPIAdd == (*ita).m_action) ? "ADD" : "DELETE";
63  QString msg = QString("RECORDING_LIST_CHANGE %1 %2")
64  .arg(type).arg((*ita).m_recordedid);
65 
66  workDone = true;
68  }
69  m_needsAddDelete.clear();
70 
71  // Send updates in any old order, we just need
72  // one per updated ProgramInfo.
73  QHash<uint,PIKeyData>::iterator itu = m_needsUpdate.begin();
74  for (; itu != m_needsUpdate.end(); ++itu)
75  {
76  QString msg;
77 
78  if (kPIUpdateFileSize == (*itu).m_action)
79  {
80  msg = QString("UPDATE_FILE_SIZE %1 %2")
81  .arg(itu.key())
82  .arg((*itu).m_filesize);
83  }
84  else
85  {
86  msg = QString("MASTER_UPDATE_REC_INFO %1")
87  .arg(itu.key());
88  }
89 
90  workDone = true;
92  }
93  m_needsUpdate.clear();
94 
95  if ( workDone )
96  m_moreWork.wait(&m_lock, 1000);
97 
98  m_lock.unlock();
99  } while( workDone );
100 
101  m_isRunning = false;
102 }
103 
104 /*
105  * vim:ts=4:sw=4:ai:et:si:sts=4
106  */
QWaitCondition m_moreWork
void run(void) override
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QHash< uint, PIKeyData > m_needsUpdate
void SendMessage(const QString &message)
void insert(uint recordedid, PIAction action, uint64_t filesize=0ULL)
unsigned int uint
Definition: compat.h:140
static MThreadPool * globalInstance(void)
void start(QRunnable *runnable, const QString &debugName, int priority=0)
std::vector< PIKeyAction > m_needsAddDelete