MythTV  master
mythcorecontext.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QtGlobal>
3 #include <QCoreApplication>
4 #include <QUrl>
5 #include <QDir>
6 #include <QFileInfo>
7 #include <QDebug>
8 #include <QMutex>
9 #include <QRunnable>
10 #include <QWaitCondition>
11 #include <QAbstractSocket>
12 #include <QHostAddress>
13 #include <QHostInfo>
14 #include <QNetworkInterface>
15 #include <QNetworkAddressEntry>
16 #include <QLocale>
17 #include <QPair>
18 #include <QDateTime>
19 
20 // Std
21 #include <algorithm>
22 #include <cmath>
23 #include <cstdarg>
24 #include <queue>
25 #include <unistd.h> // for usleep()
26 
27 #ifdef _WIN32
28 #include <winsock2.h>
29 #else
30 #include <clocale>
31 #include <utility>
32 #endif
33 
34 // MythTV
35 #include "compat.h"
36 #include "mythdownloadmanager.h"
37 #include "mythcorecontext.h"
38 #include "mythsocket.h"
39 #include "mythsystemlegacy.h"
40 #include "mthreadpool.h"
41 #include "exitcodes.h"
42 #include "mythlogging.h"
43 #include "mythversion.h"
44 #include "logging.h"
45 #include "mthread.h"
46 #include "serverpool.h"
47 #include "mythdate.h"
48 #include "mythplugin.h"
49 #include "mythmiscutil.h"
50 #include "mythpower.h"
51 
52 #define LOC QString("MythCoreContext::%1(): ").arg(__func__)
53 
55 
56 class MythCoreContextPrivate : public QObject
57 {
58  public:
59  MythCoreContextPrivate(MythCoreContext *lparent, QString binversion,
60  QObject *guicontext);
61  ~MythCoreContextPrivate() override;
62 
63  bool WaitForWOL(std::chrono::milliseconds timeout = std::chrono::milliseconds::max());
64 
65  public:
66  MythCoreContext *m_parent { nullptr };
67  QObject *m_guiContext { nullptr };
68  QObject *m_guiObject { nullptr };
70 
71  QMutex m_localHostLock;
72  QString m_localHostname;
74  QString m_masterHostname;
75  QMutex m_scopesLock;
76  QMap<QString, QString> m_scopes;
77 
78  QMutex m_sockLock;
79  MythSocket *m_serverSock { nullptr };
80  MythSocket *m_eventSock { nullptr };
81 
84  bool m_wolInProgress { false };
85  bool m_isWOLAllowed { true };
86 
87  bool m_backend { false };
88  bool m_frontend { false };
89 
90  MythDB *m_database { nullptr };
91 
92  QThread *m_uiThread { nullptr };
93 
94  MythLocale *m_locale { nullptr };
95  QString m_language;
96 
97  MythScheduler *m_scheduler { nullptr };
98 
99  bool m_blockingClient { true };
100 
101  QMap<QObject *, MythCoreContext::PlaybackStartCb> m_playbackClients;
103  bool m_inwanting { false };
104  bool m_intvwanting { false };
105 
106  bool m_announcedProtocol { false };
107 
109 
110  bool m_isexiting { false };
111 
112  QMap<QString, QPair<int64_t, uint64_t> > m_fileswritten;
113  QMutex m_fileslock;
114 
116 
117  QList<QHostAddress> m_approvedIps;
118  QList<QHostAddress> m_deniedIps;
119 
120  MythPower *m_power { nullptr };
121 };
122 
124  QString binversion,
125  QObject *guicontext)
126  : m_parent(lparent),
127  m_guiContext(guicontext),
128  m_appBinaryVersion(std::move(binversion)),
129  m_database(GetMythDB()),
130  m_uiThread(QThread::currentThread())
131 {
132  MThread::ThreadSetup("CoreContext");
133 }
134 
135 static void delete_sock(
136 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
137  QMutexLocker &locker,
138 #else
139  QMutexLocker<QMutex> &locker,
140 #endif
141  MythSocket **s)
142 {
143  if (*s)
144  {
145  MythSocket *tmp = *s;
146  *s = nullptr;
147  locker.unlock();
148  tmp->DecrRef();
149  locker.relock();
150  }
151 }
152 
154 {
155  if (m_power)
156  MythPower::AcquireRelease(this, false);
157 
159 
160  {
161  QMutexLocker locker(&m_sockLock);
162  delete_sock(locker, &m_serverSock);
163  delete_sock(locker, &m_eventSock);
164  }
165 
166  delete m_locale;
167 
168  delete m_sessionManager;
169 
171 
173 
175 
176  // This has already been run in the MythContext dtor. Do we need it here
177  // too?
178 #if 0
179  logStop(); // need to shutdown db logger before we kill db
180 #endif
181 
183 
184  GetMythDB()->GetDBManager()->CloseDatabases();
185 
186  if (m_database) {
187  DestroyMythDB();
188  m_database = nullptr;
189  }
190 
192 }
193 
197 bool MythCoreContextPrivate::WaitForWOL(std::chrono::milliseconds timeout)
198 {
199  std::chrono::milliseconds timeout_remaining = timeout;
200  while (m_wolInProgress && (timeout_remaining > 0ms))
201  {
202  LOG(VB_GENERAL, LOG_INFO, LOC + "Wake-On-LAN in progress, waiting...");
203 
204  std::chrono::milliseconds max_wait = std::min(1000ms, timeout_remaining);
205  m_wolInProgressWaitCondition.wait(&m_wolInProgressLock, max_wait.count());
206  timeout_remaining -= max_wait;
207  }
208 
209  return !m_wolInProgress;
210 }
211 
212 MythCoreContext::MythCoreContext(const QString &binversion,
213  QObject *guiContext)
214 {
215  d = new MythCoreContextPrivate(this, binversion, guiContext);
216 }
217 
219 {
220  if (!d)
221  {
222  LOG(VB_GENERAL, LOG_EMERG, LOC + "Out-of-memory");
223  return false;
224  }
225 
227  {
228  LOG(VB_GENERAL, LOG_CRIT,
229  QString("Application binary version (%1) does not "
230  "match libraries (%2)")
232 
233  QString warning = tr("This application is not compatible with the "
234  "installed MythTV libraries. Please recompile "
235  "after a make distclean");
236  LOG(VB_GENERAL, LOG_WARNING, warning);
237 
238  return false;
239  }
240 
241 #ifndef _WIN32
242  QString lang_variables("");
243  QString lc_value = setlocale(LC_CTYPE, nullptr);
244  if (lc_value.isEmpty())
245  {
246  // try fallback to environment variables for non-glibc systems
247  // LC_ALL, then LC_CTYPE
248  lc_value = qEnvironmentVariable("LC_ALL");
249  if (lc_value.isEmpty())
250  lc_value = qEnvironmentVariable("LC_CTYPE");
251  }
252  if (!lc_value.contains("UTF-8", Qt::CaseInsensitive))
253  lang_variables.append("LC_ALL or LC_CTYPE");
254  lc_value = qEnvironmentVariable("LANG");
255  if (!lc_value.contains("UTF-8", Qt::CaseInsensitive))
256  {
257  if (!lang_variables.isEmpty())
258  lang_variables.append(", and ");
259  lang_variables.append("LANG");
260  }
261  LOG(VB_GENERAL, LOG_INFO, QString("Assumed character encoding: %1")
262  .arg(lc_value));
263  if (!lang_variables.isEmpty())
264  {
265  LOG(VB_GENERAL, LOG_WARNING, QString("This application expects to "
266  "be running a locale that specifies a UTF-8 codeset, and many "
267  "features may behave improperly with your current language "
268  "settings. Please set the %1 variable(s) in the environment "
269  "in which this program is executed to include a UTF-8 codeset "
270  "(such as 'en_US.UTF-8').").arg(lang_variables));
271  }
272 #endif
273 
274  return true;
275 }
276 
278 {
279  delete d;
280  d = nullptr;
281 }
282 
283 void MythCoreContext::setTestIntSettings(QMap<QString,int> &overrides)
284 {
285  m_testOverrideInts = std::move(overrides);
286 }
287 
288 void MythCoreContext::setTestFloatSettings(QMap<QString,double> &overrides)
289 {
290  m_testOverrideFloats = std::move(overrides);
291 }
292 
293 void MythCoreContext::setTestStringSettings(QMap<QString,QString> &overrides)
294 {
295  m_testOverrideStrings = std::move(overrides);
296 }
297 
299  const QString &announcement,
300  std::chrono::milliseconds timeout,
301  bool &proto_mismatch)
302 {
303  proto_mismatch = false;
304 
305 #ifndef IGNORE_PROTO_VER_MISMATCH
306  if (!CheckProtoVersion(serverSock, timeout, true))
307  {
308  proto_mismatch = true;
309  return false;
310  }
311 #else
312  Q_UNUSED(timeout);
313 #endif
314 
315  QStringList strlist(announcement);
316 
317  if (!serverSock->WriteStringList(strlist))
318  {
319  LOG(VB_GENERAL, LOG_ERR, LOC + "Connecting server socket to "
320  "master backend, socket write failed");
321  return false;
322  }
323 
324  if (!serverSock->ReadStringList(strlist, MythSocket::kShortTimeout) ||
325  strlist.empty() || (strlist[0] == "ERROR"))
326  {
327  if (!strlist.empty())
328  {
329  LOG(VB_GENERAL, LOG_ERR, LOC + "Problem connecting "
330  "server socket to master backend");
331  }
332  else
333  {
334  LOG(VB_GENERAL, LOG_ERR, LOC + "Timeout connecting "
335  "server socket to master backend");
336  }
337  return false;
338  }
339 
340  return true;
341 }
342 
343 // Connects to master server safely (i.e. by taking m_sockLock)
345  bool openEventSocket)
346 {
347  QMutexLocker locker(&d->m_sockLock);
348  bool success = ConnectToMasterServer(blockingClient, openEventSocket);
349 
350  return success;
351 }
352 
353 // Assumes that either m_sockLock is held, or the app is still single
354 // threaded (i.e. during startup).
355 bool MythCoreContext::ConnectToMasterServer(bool blockingClient,
356  bool openEventSocket)
357 {
358  if (IsMasterBackend())
359  {
360  // Should never get here unless there is a bug in the code somewhere.
361  // If this happens, it can cause endless event loops.
362  LOG(VB_GENERAL, LOG_ERR, LOC + "ERROR: Master backend tried to connect back "
363  "to itself!");
364  return false;
365  }
366  if (IsExiting())
367  return false;
368 
369  QString server = GetMasterServerIP();
370  if (server.isEmpty())
371  return false;
372 
373  int port = GetMasterServerPort();
374  bool proto_mismatch = false;
375 
376  if (d->m_serverSock && !d->m_serverSock->IsConnected())
377  {
378  d->m_serverSock->DecrRef();
379  d->m_serverSock = nullptr;
380  }
381 
382  if (!d->m_serverSock)
383  {
384  QString type = IsFrontend() ? "Frontend" : (blockingClient ? "Playback" : "Monitor");
385  QString ann = QString("ANN %1 %2 %3")
386  .arg(type, d->m_localHostname, QString::number(static_cast<int>(false)));
388  server, port, ann, &proto_mismatch);
389  }
390 
391  if (!d->m_serverSock)
392  return false;
393 
394  d->m_blockingClient = blockingClient;
395 
396  if (!openEventSocket)
397  return true;
398 
399 
400  if (!IsBackend())
401  {
402  if (d->m_eventSock && !d->m_eventSock->IsConnected())
403  {
404  d->m_eventSock->DecrRef();
405  d->m_eventSock = nullptr;
406  }
407  if (!d->m_eventSock)
408  d->m_eventSock = ConnectEventSocket(server, port);
409 
410  if (!d->m_eventSock)
411  {
412  d->m_serverSock->DecrRef();
413  d->m_serverSock = nullptr;
414 
415  QCoreApplication::postEvent(
416  d->m_guiContext, new MythEvent("CONNECTION_FAILURE"));
417 
418  return false;
419  }
420  }
421 
422  return true;
423 }
424 
426  const QString &hostname, int port, const QString &announce,
427  bool *p_proto_mismatch, int maxConnTry, std::chrono::milliseconds setup_timeout)
428 {
429  MythSocket *serverSock = nullptr;
430 
431  {
432  QMutexLocker locker(&d->m_wolInProgressLock);
433  d->WaitForWOL();
434  }
435 
436  QString WOLcmd;
437  if (IsWOLAllowed())
438  WOLcmd = GetSetting("WOLbackendCommand", "");
439 
440  if (maxConnTry < 1)
441  maxConnTry = std::max(GetNumSetting("BackendConnectRetry", 1), 1);
442 
443  std::chrono::seconds WOLsleepTime = 0s;
444  int WOLmaxConnTry = 0;
445  if (!WOLcmd.isEmpty())
446  {
447  WOLsleepTime = GetDurSetting<std::chrono::seconds>("WOLbackendReconnectWaitTime", 0s);
448  WOLmaxConnTry = std::max(GetNumSetting("WOLbackendConnectRetry", 1), 1);
449  maxConnTry = std::max(maxConnTry, WOLmaxConnTry);
450  }
451 
452  bool we_attempted_wol = false;
453 
454  if (setup_timeout <= 0ms)
455  setup_timeout = MythSocket::kShortTimeout;
456 
457  bool proto_mismatch = false;
458  for (int cnt = 1; cnt <= maxConnTry; cnt++)
459  {
460  LOG(VB_GENERAL, LOG_INFO, LOC +
461  QString("Connecting to backend server: %1:%2 (try %3 of %4)")
462  .arg(hostname).arg(port).arg(cnt).arg(maxConnTry));
463 
464  serverSock = new MythSocket();
465 
466  std::chrono::microseconds sleepus = 0us;
467  if (serverSock->ConnectToHost(hostname, port))
468  {
469  if (SetupCommandSocket(
470  serverSock, announce, setup_timeout, proto_mismatch))
471  {
472  break;
473  }
474 
475  if (proto_mismatch)
476  {
477  if (p_proto_mismatch)
478  *p_proto_mismatch = true;
479 
480  serverSock->DecrRef();
481  serverSock = nullptr;
482  break;
483  }
484 
485  setup_timeout += setup_timeout / 2;
486  }
487  else if (!WOLcmd.isEmpty() && (cnt < maxConnTry))
488  {
489  if (!we_attempted_wol)
490  {
491  QMutexLocker locker(&d->m_wolInProgressLock);
492  if (d->m_wolInProgress)
493  {
494  d->WaitForWOL();
495  continue;
496  }
497 
498  d->m_wolInProgress = we_attempted_wol = true;
499  }
500 
503  sleepus = WOLsleepTime;
504  }
505 
506  serverSock->DecrRef();
507  serverSock = nullptr;
508 
509  if (cnt == 1)
510  {
511  QCoreApplication::postEvent(
512  d->m_guiContext, new MythEvent("CONNECTION_FAILURE"));
513  }
514 
515  if (sleepus != 0us)
516  usleep(sleepus.count());
517  }
518 
519  if (we_attempted_wol)
520  {
521  QMutexLocker locker(&d->m_wolInProgressLock);
522  d->m_wolInProgress = false;
523  d->m_wolInProgressWaitCondition.wakeAll();
524  }
525 
526  if (!serverSock && !proto_mismatch)
527  {
528  LOG(VB_GENERAL, LOG_ERR,
529  "Connection to master server timed out.\n\t\t\t"
530  "Either the server is down or the master server settings"
531  "\n\t\t\t"
532  "in mythtv-settings does not contain the proper IP address\n");
533  }
534  else
535  {
536  QCoreApplication::postEvent(
537  d->m_guiContext, new MythEvent("CONNECTION_RESTABLISHED"));
538  }
539 
540  return serverSock;
541 }
542 
544  int port)
545 {
546  auto *eventSock = new MythSocket(-1, this);
547 
548  // Assume that since we _just_ connected the command socket,
549  // this one won't need multiple retries to work...
550  if (!eventSock->ConnectToHost(hostname, port))
551  {
552  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to connect event "
553  "socket to master backend");
554  eventSock->DecrRef();
555  return nullptr;
556  }
557 
558  QString str = QString("ANN Monitor %1 %2")
559  .arg(d->m_localHostname).arg(static_cast<int>(true));
560  QStringList strlist(str);
561  eventSock->WriteStringList(strlist);
562  bool ok = true;
563  if (!eventSock->ReadStringList(strlist) || strlist.empty() ||
564  (strlist[0] == "ERROR"))
565  {
566  if (!strlist.empty())
567  {
568  LOG(VB_GENERAL, LOG_ERR, LOC +
569  "Problem connecting event socket to master backend");
570  }
571  else
572  {
573  LOG(VB_GENERAL, LOG_ERR, LOC +
574  "Timeout connecting event socket to master backend");
575  }
576  ok = false;
577  }
578 
579  if (!ok)
580  {
581  eventSock->DecrRef();
582  eventSock = nullptr;
583  }
584 
585  return eventSock;
586 }
587 
589 {
590  QMutexLocker locker(&d->m_sockLock);
591  return d->m_serverSock;
592 }
593 
595 {
596  QStringList strlist;
597 
598  QMutexLocker locker(&d->m_sockLock);
599  if (d->m_serverSock == nullptr)
600  return;
601 
602  strlist << "BLOCK_SHUTDOWN";
604 
605  d->m_blockingClient = true;
606 }
607 
609 {
610  QStringList strlist;
611 
612  QMutexLocker locker(&d->m_sockLock);
613  if (d->m_serverSock == nullptr)
614  return;
615 
616  strlist << "ALLOW_SHUTDOWN";
618 
619  d->m_blockingClient = false;
620 }
621 
623 {
624  return d->m_blockingClient;
625 }
626 
628 {
629  d->m_isWOLAllowed = allow;
630 }
631 
633 {
634  return d->m_isWOLAllowed;
635 }
636 
638 {
639  d->m_backend = backend;
640 }
641 
643 {
644  return d->m_backend;
645 }
646 
648 {
649  d->m_frontend = frontend;
650 }
651 
653 {
654  return d->m_frontend;
655 }
656 
658 {
659  QString host = GetHostName();
660  return IsMasterHost(host);
661 }
662 
663 bool MythCoreContext::IsMasterHost(const QString &host)
664 {
665  // Temporary code here only to facilitate the upgrade
666  // from 1346 or earlier. The way of determining master host is
667  // changing, and the new way of determning master host
668  // will not work with earlier databases.
669  // This code can be removed when updating from prior to
670  // 1347 is no longer allowed.
671  // Note that we are deprecating some settings including
672  // MasterServerIP, and can remove them at a future time.
673  if (GetNumSetting("DBSchemaVer") < 1347)
674  {
675  // Temporary copy of code from old version of
676  // IsThisHost(Qstring&,QString&)
677  QString addr(resolveSettingAddress("MasterServerIP"));
678  if (addr.toLower() == host.toLower())
679  return true;
680  QHostAddress addrfix(addr);
681  addrfix.setScopeId(QString());
682  QString addrstr = addrfix.toString();
683  if (addrfix.isNull())
684  addrstr = resolveAddress(addr);
685  QString thisip = GetBackendServerIP4(host);
686  QString thisip6 = GetBackendServerIP6(host);
687  return !addrstr.isEmpty()
688  && ((addrstr == thisip) || (addrstr == thisip6));
689  }
690  return GetSetting("MasterServerName") == host;
691 }
692 
694 {
695  return (IsBackend() && IsMasterHost());
696 }
697 
699 {
700 #if defined(Q_OS_DARWIN) || defined(__FreeBSD__) || defined(__OpenBSD__)
701  const char *command = "ps -axc | grep -i mythbackend | grep -v grep > /dev/null";
702 #elif defined _WIN32
703  const char *command = "%systemroot%\\system32\\tasklist.exe "
704  " | %systemroot%\\system32\\find.exe /i \"mythbackend.exe\" ";
705 #else
706  const char *command = "ps ch -C mythbackend -o pid > /dev/null";
707 #endif
708  uint res = myth_system(command, kMSDontBlockInputDevs |
711  return (res == GENERIC_EXIT_OK);
712 }
713 
714 bool MythCoreContext::IsThisBackend(const QString &addr)
715 {
716  return IsBackend() && IsThisHost(addr);
717 }
718 
719 bool MythCoreContext::IsThisHost(const QString &addr)
720 {
721  return IsThisHost(addr, GetHostName());
722 }
723 
724 bool MythCoreContext::IsThisHost(const QString &addr, const QString &host)
725 {
726  if (addr.toLower() == host.toLower())
727  return true;
728 
729  QHostAddress addrfix(addr);
730  addrfix.setScopeId(QString());
731  QString addrstr = addrfix.toString();
732 
733  if (addrfix.isNull())
734  {
735  addrstr = resolveAddress(addr);
736  }
737 
738  QString thisip = GetBackendServerIP(host);
739 
740  return !addrstr.isEmpty() && ((addrstr == thisip));
741 }
742 
744 {
745  // find out if a backend runs on this host...
746  bool backendOnLocalhost = false;
747 
748  QStringList strlist("QUERY_IS_ACTIVE_BACKEND");
749  strlist << GetHostName();
750 
751  SendReceiveStringList(strlist);
752 
753  backendOnLocalhost = strlist[0] != "FALSE";
754 
755  return !backendOnLocalhost;
756 }
757 
758 QString MythCoreContext::GenMythURL(const QString& host, int port, QString path, const QString& storageGroup)
759 {
760  QUrl ret;
761 
762  QString m_host;
763 
764  QHostAddress addr(host);
765  if (!addr.isNull())
766  {
767  LOG(VB_GENERAL, LOG_CRIT, LOC + QString("(%1/%2): Given "
768  "IP address instead of hostname "
769  "(ID). This is invalid.").arg(host, path));
770  }
771 
772  m_host = host;
773 
774  // Basically if it appears to be an IPv6 IP surround the IP with [] otherwise don't bother
775  if (!addr.isNull() && addr.protocol() == QAbstractSocket::IPv6Protocol)
776  m_host = "[" + addr.toString().toLower() + "]";
777 
778  ret.setScheme("myth");
779  if (!storageGroup.isEmpty())
780  ret.setUserName(storageGroup);
781  ret.setHost(m_host);
782  if (port > 0 && port != 6543)
783  ret.setPort(port);
784  if (!path.startsWith("/"))
785  path = QString("/") + path;
786  ret.setPath(path);
787 
788 #if 0
789  LOG(VB_GENERAL, LOG_DEBUG, LOC +
790  QString("GenMythURL returning %1").arg(ret.toString()));
791 #endif
792 
793  return ret.toString();
794 }
795 
796 QString MythCoreContext::GetMasterHostPrefix(const QString &storageGroup,
797  const QString &path)
798 {
799  return GenMythURL(GetMasterHostName(),
801  path,
802  storageGroup);
803 }
804 
806 {
807  QMutexLocker locker(&d->m_masterHostLock);
808 
809  if (d->m_masterHostname.isEmpty())
810  {
811 
812  if (IsMasterBackend())
814  else
815  {
816  QStringList strlist("QUERY_HOSTNAME");
817 
818  if (SendReceiveStringList(strlist))
819  d->m_masterHostname = strlist[0];
820  }
821  }
822 
823  return d->m_masterHostname;
824 }
825 
826 void MythCoreContext::ClearSettingsCache(const QString &myKey)
827 {
828  d->m_database->ClearSettingsCache(myKey);
829 }
830 
832 {
833  d->m_database->ActivateSettingsCache(activate);
834 }
835 
837 {
838  QMutexLocker locker(&d->m_localHostLock);
839  return d->m_localHostname;
840 }
841 
843 {
844  return GetSetting("RecordFilePrefix");
845 }
846 
848  int &width, int &height,
849  double &forced_aspect,
850  double &refresh_rate,
851  int index)
852 {
853  d->m_database->GetResolutionSetting(type, width, height, forced_aspect,
854  refresh_rate, index);
855 }
856 
857 void MythCoreContext::GetResolutionSetting(const QString &t, int &w,
858  int &h, int i)
859 {
860  d->m_database->GetResolutionSetting(t, w, h, i);
861 }
862 
864 {
865  return d->m_database->GetDBManager();
866 }
867 
875 {
876  return d->m_database->IsDatabaseIgnored();
877 }
878 
879 void MythCoreContext::SaveSetting(const QString &key, int newValue)
880 {
881  d->m_database->SaveSetting(key, newValue);
882 }
883 
884 void MythCoreContext::SaveSetting(const QString &key, const QString &newValue)
885 {
886  d->m_database->SaveSetting(key, newValue);
887 }
888 
889 bool MythCoreContext::SaveSettingOnHost(const QString &key,
890  const QString &newValue,
891  const QString &host)
892 {
893  return d->m_database->SaveSettingOnHost(key, newValue, host);
894 }
895 
896 QString MythCoreContext::GetSetting(const QString &key,
897  const QString &defaultval)
898 {
899  if (!m_testOverrideStrings.empty())
900  return m_testOverrideStrings[key];
901  return d->m_database->GetSetting(key, defaultval);
902 }
903 
904 bool MythCoreContext::GetBoolSetting(const QString &key, bool defaultval)
905 {
906  int result = GetNumSetting(key, static_cast<int>(defaultval));
907  return result > 0;
908 }
909 
910 int MythCoreContext::GetNumSetting(const QString &key, int defaultval)
911 {
912  if (!m_testOverrideInts.empty())
913  return m_testOverrideInts[key];
914  return d->m_database->GetNumSetting(key, defaultval);
915 }
916 
917 double MythCoreContext::GetFloatSetting(const QString &key, double defaultval)
918 {
919  if (!m_testOverrideFloats.empty())
920  return m_testOverrideFloats[key];
921  return d->m_database->GetFloatSetting(key, defaultval);
922 }
923 
924 QString MythCoreContext::GetSettingOnHost(const QString &key,
925  const QString &host,
926  const QString &defaultval)
927 {
928  if (!m_testOverrideStrings.empty())
929  return m_testOverrideStrings[key];
930  return d->m_database->GetSettingOnHost(key, host, defaultval);
931 }
932 
934  const QString &host,
935  bool defaultval)
936 {
937  int result = GetNumSettingOnHost(key, host, static_cast<int>(defaultval));
938  return result > 0;
939 }
940 
942  const QString &host,
943  int defaultval)
944 {
945  if (!m_testOverrideInts.empty())
946  return m_testOverrideInts[key];
947  return d->m_database->GetNumSettingOnHost(key, host, defaultval);
948 }
949 
950 double MythCoreContext::GetFloatSettingOnHost(const QString &key,
951  const QString &host,
952  double defaultval)
953 {
954  if (!m_testOverrideFloats.empty())
955  return m_testOverrideFloats[key];
956  return d->m_database->GetFloatSettingOnHost(key, host, defaultval);
957 }
958 
965 {
966  QString masterserver = gCoreContext->GetSetting("MasterServerName");
967  QString masterip = resolveSettingAddress("BackendServerAddr",masterserver);
968  // Even if empty, return it here if we were to assume that localhost
969  // should be used it just causes a lot of unnecessary error messages.
970  return masterip;
971 }
972 
979 {
980  QString masterserver = gCoreContext->GetSetting
981  ("MasterServerName");
983  ("BackendServerPort", masterserver, 6543);
984 }
985 
992 {
993  QString masterhost = GetMasterHostName();
994 
995  return GetBackendStatusPort(masterhost);
996 }
997 
1003 {
1005 }
1006 
1016 QString MythCoreContext::GetBackendServerIP(const QString &host)
1017 {
1018  return resolveSettingAddress("BackendServerAddr",host);
1019 }
1020 
1026 {
1028 }
1029 
1035 QString MythCoreContext::GetBackendServerIP4(const QString &host)
1036 {
1037  return resolveSettingAddress("BackendServerIP", host, ResolveIPv4);
1038 }
1039 
1045 {
1047 }
1048 
1054 QString MythCoreContext::GetBackendServerIP6(const QString &host)
1055 {
1056  return resolveSettingAddress("BackendServerIP6", host, ResolveIPv6);
1057 }
1058 
1063 {
1065 }
1066 
1067 QHash<QString,int> MythCoreContext::s_serverPortCache;
1068 
1070 {
1071  s_serverPortCache.clear();
1072 }
1073 
1078 {
1079  int port = s_serverPortCache.value(host, -1);
1080  if (port != -1)
1081  return port;
1082  port = GetNumSettingOnHost("BackendServerPort", host, 6543);
1083  s_serverPortCache[host] = port;
1084  return port;
1085 }
1086 
1091 {
1093 }
1094 
1099 {
1100  return GetNumSettingOnHost("BackendStatusPort", host, 6544);
1101 }
1102 
1107 bool MythCoreContext::GetScopeForAddress(QHostAddress &addr) const
1108 {
1109  QHostAddress addr1 = addr;
1110  addr1.setScopeId(QString());
1111  QString addrstr = addr1.toString();
1112  QMutexLocker lock(&d->m_scopesLock);
1113 
1114  if (!d->m_scopes.contains(addrstr))
1115  return false;
1116 
1117  addr.setScopeId(d->m_scopes[addrstr]);
1118  return true;
1119 }
1120 
1127 void MythCoreContext::SetScopeForAddress(const QHostAddress &addr)
1128 {
1129  QHostAddress addr1 = addr;
1130  addr1.setScopeId(QString());
1131  QMutexLocker lock(&d->m_scopesLock);
1132 
1133  d->m_scopes.insert(addr1.toString(), addr.scopeId());
1134 }
1135 
1141 void MythCoreContext::SetScopeForAddress(const QHostAddress &addr, int scope)
1142 {
1143  QHostAddress addr1 = addr;
1144  addr1.setScopeId(QString());
1145  QMutexLocker lock(&d->m_scopesLock);
1146 
1147  d->m_scopes.insert(addr1.toString(), QString::number(scope));
1148 }
1149 
1161 QString MythCoreContext::resolveSettingAddress(const QString &name,
1162  const QString &host,
1163  ResolveType type, bool keepscope)
1164 {
1165  QString value;
1166 
1167  if (host.isEmpty())
1168  {
1169  value = GetSetting(name);
1170  }
1171  else
1172  {
1173  value = GetSettingOnHost(name, host);
1174  }
1175 
1176  return resolveAddress(value, type, keepscope);
1177 }
1178 
1190 QString MythCoreContext::resolveAddress(const QString &host, ResolveType type,
1191  bool keepscope)
1192 {
1193  QHostAddress addr(host);
1194 
1195  if (!host.isEmpty() && addr.isNull())
1196  {
1197  // address is likely a hostname, attempts to resolve it
1198  QHostInfo info = QHostInfo::fromName(host);
1199  QList<QHostAddress> list = info.addresses();
1200 
1201  if (list.isEmpty())
1202  {
1203  LOG(VB_GENERAL, LOG_WARNING, LOC +
1204  QString("Can't resolve hostname:'%1', using localhost").arg(host));
1205  return type == ResolveIPv4 ? "127.0.0.1" : "::1";
1206  }
1207  QHostAddress v4;
1208  QHostAddress v6;
1209 
1210  // Return the first address fitting the type critera
1211  for (const auto& item : qAsConst(list))
1212  {
1213  addr = item;
1214  QAbstractSocket::NetworkLayerProtocol prot = addr.protocol();
1215 
1216  if (prot == QAbstractSocket::IPv4Protocol)
1217  {
1218  v4 = addr;
1219  if (type == 0)
1220  break;
1221  }
1222  else if (prot == QAbstractSocket::IPv6Protocol)
1223  {
1224  v6 = addr;
1225  if (type != 0)
1226  break;
1227  }
1228  }
1229  switch (type)
1230  {
1231  case ResolveIPv4:
1232  addr = v4.isNull() ? QHostAddress::LocalHost : v4;
1233  break;
1234  case ResolveIPv6:
1235  addr = v6.isNull() ? QHostAddress::LocalHostIPv6 : v6;
1236  break;
1237  default:
1238  addr = v6.isNull() ?
1239  (v4.isNull() ? QHostAddress::LocalHostIPv6 : v4) : v6;
1240  break;
1241  }
1242  }
1243  else if (host.isEmpty())
1244  {
1245  return {};
1246  }
1247 
1248  if (!keepscope)
1249  {
1250  addr.setScopeId(QString());
1251  }
1252  return addr.toString();
1253 }
1254 
1266 bool MythCoreContext::CheckSubnet(const QAbstractSocket *socket)
1267 {
1268  QHostAddress peer = socket->peerAddress();
1269  return CheckSubnet(peer);
1270 }
1271 
1283 bool MythCoreContext::CheckSubnet(const QHostAddress &peer)
1284 {
1285  static const QHostAddress kLinkLocal("fe80::");
1286  if (GetBoolSetting("AllowConnFromAll",false))
1287  return true;
1288  if (d->m_approvedIps.contains(peer))
1289  return true;
1290  if (d->m_deniedIps.contains(peer))
1291  {
1292  LOG(VB_GENERAL, LOG_WARNING, LOC +
1293  QString("Repeat denied connection from ip address: %1")
1294  .arg(peer.toString()));
1295  return false;
1296  }
1297 
1298  // allow all link-local
1299  if (peer.isInSubnet(kLinkLocal,10))
1300  {
1301  d->m_approvedIps.append(peer);
1302  return true;
1303  }
1304 
1305  // loop through all available interfaces
1306  QList<QNetworkInterface> IFs = QNetworkInterface::allInterfaces();
1307  for (const auto & qni : qAsConst(IFs))
1308  {
1309  if ((qni.flags() & QNetworkInterface::IsRunning) == 0)
1310  continue;
1311 
1312  QList<QNetworkAddressEntry> IPs = qni.addressEntries();
1313  for (const auto & qnai : qAsConst(IPs))
1314  {
1315  int pfxlen = qnai.prefixLength();
1316  // Set this to test rejection without having an extra
1317  // network.
1318  if (GetBoolSetting("DebugSubnet"))
1319  pfxlen += 4;
1320  if (peer.isInSubnet(qnai.ip(),pfxlen))
1321  {
1322  d->m_approvedIps.append(peer);
1323  return true;
1324  }
1325  }
1326  }
1327  d->m_deniedIps.append(peer);
1328  LOG(VB_GENERAL, LOG_WARNING, LOC +
1329  QString("Denied connection from ip address: %1")
1330  .arg(peer.toString()));
1331  return false;
1332 }
1333 
1334 
1336  const QString &value)
1337 {
1338  d->m_database->OverrideSettingForSession(key, value);
1339 }
1340 
1342 {
1343  d->m_database->ClearOverrideSettingForSession(key);
1344 }
1345 
1347 {
1348  return is_current_thread(d->m_uiThread);
1349 }
1350 
1370  QStringList &strlist, bool quickTimeout, bool block)
1371 {
1372  QString msg;
1373  if (HasGUI() && IsUIThread())
1374  {
1375  msg = "SendReceiveStringList(";
1376  for (uint i=0; i<(uint)strlist.size() && i<2; i++)
1377  msg += (i?",":"") + strlist[i];
1378  msg += (strlist.size() > 2) ? "...)" : ")";
1379  LOG(VB_GENERAL, LOG_DEBUG, LOC + msg + " called from UI thread");
1380  }
1381 
1382  QString query_type = "UNKNOWN";
1383 
1384  if (!strlist.isEmpty())
1385  query_type = strlist[0];
1386 
1387  QMutexLocker locker(&d->m_sockLock);
1388  if (!d->m_serverSock)
1389  {
1390  bool blockingClient = d->m_blockingClient &&
1391  (GetNumSetting("idleTimeoutSecs",0) > 0);
1392  ConnectToMasterServer(blockingClient);
1393  }
1394 
1395  bool ok = false;
1396 
1397  if (d->m_serverSock)
1398  {
1399  std::chrono::milliseconds timeout = quickTimeout ?
1401  ok = d->m_serverSock->SendReceiveStringList(strlist, 0, timeout);
1402 
1403  if (!ok)
1404  {
1405  LOG(VB_GENERAL, LOG_NOTICE, LOC +
1406  QString("Connection to backend server lost"));
1407  d->m_serverSock->DecrRef();
1408  d->m_serverSock = nullptr;
1409 
1410  if (d->m_eventSock)
1411  {
1412  d->m_eventSock->DecrRef();
1413  d->m_eventSock = nullptr;
1414  }
1415 
1416  if (block)
1417  {
1419 
1420  if (d->m_serverSock)
1421  {
1423  strlist, 0, timeout);
1424  }
1425  }
1426  }
1427 
1428  // this should not happen
1429  while (ok && strlist[0] == "BACKEND_MESSAGE")
1430  {
1431  // oops, not for us
1432  LOG(VB_GENERAL, LOG_EMERG, LOC + "SRSL you shouldn't see this!!");
1433  QString message = strlist[1];
1434  strlist.pop_front(); strlist.pop_front();
1435 
1436  MythEvent me(message, strlist);
1437  dispatch(me);
1438 
1439  ok = d->m_serverSock->ReadStringList(strlist, timeout);
1440  }
1441 
1442  if (!ok)
1443  {
1444  if (d->m_serverSock)
1445  {
1446  d->m_serverSock->DecrRef();
1447  d->m_serverSock = nullptr;
1448  }
1449 
1450  LOG(VB_GENERAL, LOG_CRIT, LOC +
1451  QString("Reconnection to backend server failed"));
1452 
1453  QCoreApplication::postEvent(d->m_guiContext,
1454  new MythEvent("PERSISTENT_CONNECTION_FAILURE"));
1455  }
1456  }
1457 
1458  if (ok)
1459  {
1460  if (strlist.isEmpty())
1461  ok = false;
1462  else if (strlist[0] == "ERROR")
1463  {
1464  if (strlist.size() == 2)
1465  {
1466  LOG(VB_GENERAL, LOG_INFO, LOC +
1467  QString("Protocol query '%1' responded with the error '%2'")
1468  .arg(query_type, strlist[1]));
1469  }
1470  else
1471  {
1472  LOG(VB_GENERAL, LOG_INFO, LOC +
1473  QString("Protocol query '%1' responded with an error, but "
1474  "no error message.") .arg(query_type));
1475  }
1476 
1477  ok = false;
1478  }
1479  else if (strlist[0] == "UNKNOWN_COMMAND")
1480  {
1481  LOG(VB_GENERAL, LOG_ERR, LOC +
1482  QString("Protocol query '%1' responded with the error 'UNKNOWN_COMMAND'")
1483  .arg(query_type));
1484 
1485  ok = false;
1486  }
1487  }
1488 
1489  return ok;
1490 }
1491 
1492 class SendAsyncMessage : public QRunnable
1493 {
1494  public:
1495  SendAsyncMessage(QString msg, QStringList extra) :
1496  m_message(std::move(msg)), m_extraData(std::move(extra))
1497  {
1498  }
1499 
1500  explicit SendAsyncMessage(QString msg) : m_message(std::move(msg)) { }
1501 
1502  void run(void) override // QRunnable
1503  {
1504  QStringList strlist("MESSAGE");
1505  strlist << m_message;
1506  strlist << m_extraData;
1508  }
1509 
1510  private:
1511  QString m_message;
1512  QStringList m_extraData;
1513 };
1514 
1515 void MythCoreContext::SendMessage(const QString &message)
1516 {
1517  if (IsBackend())
1518  {
1519  dispatch(MythEvent(message));
1520  }
1521  else
1522  {
1524  new SendAsyncMessage(message), "SendMessage");
1525  }
1526 }
1527 
1529 {
1530  if (IsBackend())
1531  {
1532  dispatch(event);
1533  }
1534  else
1535  {
1537  new SendAsyncMessage(event.Message(), event.ExtraDataList()),
1538  "SendEvent");
1539  }
1540 }
1541 
1542 void MythCoreContext::SendSystemEvent(const QString &msg)
1543 {
1544  if (QCoreApplication::applicationName() == MYTH_APPNAME_MYTHTV_SETUP)
1545  return;
1546 
1547  SendMessage(QString("SYSTEM_EVENT %1 SENDER %2")
1548  .arg(msg, GetHostName()));
1549 }
1550 
1552  const QString &hostname,
1553  const QString &args)
1554 {
1555  SendSystemEvent(QString("%1 HOST %2 %3").arg(msg, hostname, args));
1556 }
1557 
1558 
1560 {
1561  do
1562  {
1563  QStringList strlist;
1564  if (!sock->ReadStringList(strlist))
1565  continue;
1566 
1567  if (strlist.size() < 2)
1568  continue;
1569 
1570  QString prefix = strlist[0];
1571  QString message = strlist[1];
1572 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
1573  QStringList tokens = message.split(" ", QString::SkipEmptyParts);
1574 #else
1575  QStringList tokens = message.split(" ", Qt::SkipEmptyParts);
1576 #endif
1577 
1578  if (prefix == "OK")
1579  {
1580  }
1581  else if (prefix != "BACKEND_MESSAGE")
1582  {
1583  LOG(VB_NETWORK, LOG_ERR, LOC +
1584  QString("Received a: %1 message from the backend "
1585  "but I don't know what to do with it.")
1586  .arg(prefix));
1587  }
1588  else if (message == "CLEAR_SETTINGS_CACHE")
1589  {
1590  // No need to dispatch this message to ourself, so handle it
1591  LOG(VB_NETWORK, LOG_INFO, LOC + "Received remote 'Clear Cache' request");
1593  }
1594  else if (message.startsWith("FILE_WRITTEN"))
1595  {
1596  QString file;
1597  uint64_t size = 0;
1598  int NUMTOKENS = 3; // Number of tokens expected
1599 
1600  if (tokens.size() == NUMTOKENS)
1601  {
1602  file = tokens[1];
1603  size = tokens[2].toULongLong();
1604  }
1605  else
1606  {
1607  LOG(VB_NETWORK, LOG_ERR, LOC +
1608  QString("FILE_WRITTEN event received "
1609  "with invalid number of arguments, "
1610  "%1 expected, %2 actual")
1611  .arg(NUMTOKENS-1)
1612  .arg(tokens.size()-1));
1613  return;
1614  }
1615  // No need to dispatch this message to ourself, so handle it
1616  LOG(VB_NETWORK, LOG_INFO, LOC +
1617  QString("Received remote 'FILE_WRITTEN %1' request").arg(file));
1618  RegisterFileForWrite(file, size);
1619  }
1620  else if (message.startsWith("FILE_CLOSED"))
1621  {
1622  QString file;
1623  int NUMTOKENS = 2; // Number of tokens expected
1624 
1625  if (tokens.size() == NUMTOKENS)
1626  {
1627  file = tokens[1];
1628  }
1629  else
1630  {
1631  LOG(VB_NETWORK, LOG_ERR, LOC +
1632  QString("FILE_CLOSED event received "
1633  "with invalid number of arguments, "
1634  "%1 expected, %2 actual")
1635  .arg(NUMTOKENS-1)
1636  .arg(tokens.size()-1));
1637  return;
1638  }
1639  // No need to dispatch this message to ourself, so handle it
1640  LOG(VB_NETWORK, LOG_INFO, LOC +
1641  QString("Received remote 'FILE_CLOSED %1' request").arg(file));
1643  }
1644  else
1645  {
1646  strlist.pop_front();
1647  strlist.pop_front();
1648  MythEvent me(message, strlist);
1649  dispatch(me);
1650  }
1651  }
1652  while (sock->IsDataAvailable());
1653 }
1654 
1656 {
1657  (void)sock;
1658 
1659  LOG(VB_GENERAL, LOG_NOTICE, LOC +
1660  "Event socket closed. No connection to the backend.");
1661 
1662  dispatch(MythEvent("BACKEND_SOCKETS_CLOSED"));
1663 }
1664 
1666  std::chrono::milliseconds timeout,
1667  bool error_dialog_desired)
1668 {
1669  if (!socket)
1670  return false;
1671 
1672  QStringList strlist(QString("MYTH_PROTO_VERSION %1 %2")
1673  .arg(MYTH_PROTO_VERSION,
1674  QString::fromUtf8(MYTH_PROTO_TOKEN)));
1675  socket->WriteStringList(strlist);
1676 
1677  if (!socket->ReadStringList(strlist, timeout) || strlist.empty())
1678  {
1679  LOG(VB_GENERAL, LOG_CRIT, "Protocol version check failure.\n\t\t\t"
1680  "The response to MYTH_PROTO_VERSION was empty.\n\t\t\t"
1681  "This happens when the backend is too busy to respond,\n\t\t\t"
1682  "or has deadlocked due to bugs or hardware failure.");
1683 
1684  return false;
1685  }
1686  if (strlist[0] == "REJECT" && strlist.size() >= 2)
1687  {
1688  LOG(VB_GENERAL, LOG_CRIT, LOC + QString("Protocol version or token mismatch "
1689  "(frontend=%1/%2,backend=%3/\?\?)\n")
1690  .arg(MYTH_PROTO_VERSION,
1691  QString::fromUtf8(MYTH_PROTO_TOKEN),
1692  strlist[1]));
1693 
1694  if (error_dialog_desired && d->m_guiContext)
1695  {
1696  QStringList list(strlist[1]);
1697  QCoreApplication::postEvent(
1698  d->m_guiContext, new MythEvent("VERSION_MISMATCH", list));
1699  }
1700 
1701  return false;
1702  }
1703  if (strlist[0] == "ACCEPT")
1704  {
1705  if (!d->m_announcedProtocol)
1706  {
1707  d->m_announcedProtocol = true;
1708  LOG(VB_GENERAL, LOG_INFO, LOC +
1709  QString("Using protocol version %1 %2")
1710  .arg(MYTH_PROTO_VERSION,
1711  QString::fromUtf8(MYTH_PROTO_TOKEN)));
1712  }
1713 
1714  return true;
1715  }
1716 
1717  LOG(VB_GENERAL, LOG_ERR, LOC +
1718  QString("Unexpected response to MYTH_PROTO_VERSION: %1")
1719  .arg(strlist[0]));
1720  return false;
1721 }
1722 
1724 {
1725  LOG(VB_NETWORK, LOG_INFO, LOC + QString("MythEvent: %1").arg(event.Message()));
1726 
1727  MythObservable::dispatch(event);
1728 }
1729 
1731 {
1732  QMutexLocker locker(&d->m_localHostLock);
1734  d->m_database->SetLocalHostname(hostname);
1735 }
1736 
1738 {
1739  d->m_guiObject = gui;
1740 }
1741 
1742 bool MythCoreContext::HasGUI(void) const
1743 {
1744  return d->m_guiObject;
1745 }
1746 
1748 {
1749  return d->m_guiObject;
1750 }
1751 
1753 {
1754  return d->m_guiContext;
1755 }
1756 
1758 {
1759  return d->m_database;
1760 }
1761 
1763 {
1764  return d->m_locale;
1765 }
1766 
1772 {
1773  return GetLanguageAndVariant().left(2);
1774 }
1775 
1784 {
1785  if (d->m_language.isEmpty())
1786  d->m_language = GetSetting("Language", "en_US").toLower();
1787 
1788  return d->m_language;
1789 }
1790 
1792 {
1793  d->m_language.clear();
1794 }
1795 
1797 {
1798  QMutexLocker locker(&d->m_sockLock);
1799  LOG(VB_GENERAL, LOG_INFO, "Restarting Backend Connections");
1800  if (d->m_serverSock)
1802  if (d->m_eventSock)
1804  dispatch(MythEvent("BACKEND_SOCKETS_CLOSED"));
1805 }
1806 
1808 {
1809  if (Create && !d->m_power)
1810  {
1812  }
1813  else if (!Create && d->m_power)
1814  {
1815  MythPower::AcquireRelease(d, false);
1816  d->m_power = nullptr;
1817  }
1818 }
1819 
1821 {
1822  if (!d->m_locale)
1823  d->m_locale = new MythLocale();
1824 
1825  QString localeCode = d->m_locale->GetLocaleCode();
1826  LOG(VB_GENERAL, LOG_NOTICE, QString("Setting QT default locale to %1")
1827  .arg(localeCode));
1828  QLocale::setDefault(d->m_locale->ToQLocale());
1829 }
1830 
1832 {
1833  if (!d->m_locale)
1834  d->m_locale = new MythLocale();
1835  else
1836  d->m_locale->ReInit();
1837 
1838  QString localeCode = d->m_locale->GetLocaleCode();
1839  LOG(VB_GENERAL, LOG_NOTICE, QString("Setting QT default locale to %1")
1840  .arg(localeCode));
1841  QLocale::setDefault(d->m_locale->ToQLocale());
1842 }
1843 
1845 {
1846  if (!d->m_locale)
1847  InitLocale();
1848 
1849  return d->m_locale->ToQLocale();
1850 }
1851 
1853 {
1854  if (!d->m_locale)
1855  InitLocale();
1856 
1857  if (!d->m_locale->GetLocaleCode().isEmpty())
1858  {
1859  LOG(VB_GENERAL, LOG_INFO,
1860  QString("Current locale %1") .arg(d->m_locale->GetLocaleCode()));
1861 
1863  return;
1864  }
1865 
1866  LOG(VB_GENERAL, LOG_ERR, LOC +
1867  "No locale defined! We weren't able to set locale defaults.");
1868 }
1869 
1871 {
1872  d->m_scheduler = sched;
1873 }
1874 
1876 {
1877  return d->m_scheduler;
1878 }
1879 
1884 void MythCoreContext::WaitUntilSignals(std::vector<CoreWaitInfo> & sigs) const
1885 {
1886  if (sigs.empty())
1887  return;
1888 
1889  QEventLoop eventLoop;
1890  for (const auto& s : sigs)
1891  {
1892  LOG(VB_GENERAL, LOG_DEBUG, LOC +
1893  QString("Waiting for signal %1")
1894  .arg(s.name));
1895  connect(this, s.fn, &eventLoop, &QEventLoop::quit);
1896  }
1897 
1898  eventLoop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
1899 }
1900 
1908 {
1909  if (!sender || !method)
1910  return;
1911 
1912  QMutexLocker lock(&d->m_playbackLock);
1913 
1914  if (!d->m_playbackClients.contains(sender))
1915  {
1916  d->m_playbackClients.insert(sender, method);
1918  sender, method,
1919  Qt::BlockingQueuedConnection);
1920  }
1921 }
1922 
1929 {
1930  QMutexLocker lock(&d->m_playbackLock);
1931 
1932  if (d->m_playbackClients.contains(sender))
1933  {
1934  PlaybackStartCb method = d->m_playbackClients.value(sender);
1935  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart,
1936  sender, method);
1937  d->m_playbackClients.remove(sender);
1938  }
1939 }
1940 
1948 {
1949  QMutexLocker lock(&d->m_playbackLock);
1950  PlaybackStartCb method { nullptr };
1951  d->m_inwanting = true;
1952 
1953  // If any registered client are in the same thread, they will deadlock, so rebuild
1954  // connections for any clients in the same thread as non-blocking connection
1955  QThread *currentThread = QThread::currentThread();
1956 
1957  QMap<QObject *, PlaybackStartCb>::iterator it = d->m_playbackClients.begin();
1958  for (; it != d->m_playbackClients.end(); ++it)
1959  {
1960  if (it.key() == sender)
1961  continue; // will be done separately, no need to do it again
1962 
1963  QThread *thread = it.key()->thread();
1964 
1965  if (thread != currentThread)
1966  continue;
1967 
1968  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart, it.key(), it.value());
1969  connect(this, &MythCoreContext::TVPlaybackAboutToStart, it.key(), it.value());
1970  }
1971 
1972  // disconnect sender so it won't receive the message
1973  if (d->m_playbackClients.contains(sender))
1974  {
1975  method = d->m_playbackClients.value(sender);
1976  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart, sender, method);
1977  }
1978 
1979  // emit signal
1980  emit TVPlaybackAboutToStart();
1981 
1982  // reconnect sender
1983  if (method)
1984  {
1986  sender, method,
1987  Qt::BlockingQueuedConnection);
1988  }
1989  // Restore blocking connections
1990  for (; it != d->m_playbackClients.end(); ++it)
1991  {
1992  if (it.key() == sender)
1993  continue; // already done above, no need to do it again
1994 
1995  QThread *thread = it.key()->thread();
1996 
1997  if (thread != currentThread)
1998  continue;
1999 
2000  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart,
2001  it.key(), it.value());
2003  it.key(), it.value(), Qt::BlockingQueuedConnection);
2004  }
2005  d->m_inwanting = false;
2006 }
2007 
2014 {
2015  // when called, it will be while the m_playbackLock is held
2016  // following a call to WantingPlayback
2017  d->m_intvwanting = b;
2018 }
2019 
2026 {
2027  bool locked = d->m_playbackLock.tryLock();
2028  bool intvplayback = d->m_intvwanting;
2029 
2030  if (!locked && d->m_inwanting)
2031  return true; // we're in the middle of WantingPlayback
2032 
2033  if (!locked)
2034  return false;
2035 
2036  d->m_playbackLock.unlock();
2037 
2038  return intvplayback;
2039 }
2040 
2042 {
2043  if (!d->m_sessionManager)
2045 
2046  return d->m_sessionManager;
2047 }
2048 
2049 bool MythCoreContext::TestPluginVersion(const QString &name,
2050  const QString &libversion,
2051  const QString &pluginversion)
2052 {
2053  if (libversion == pluginversion)
2054  return true;
2055 
2056  LOG(VB_GENERAL, LOG_EMERG, LOC +
2057  QString("Plugin %1 (%2) binary version does not "
2058  "match libraries (%3)")
2059  .arg(name, pluginversion, libversion));
2060  return false;
2061 }
2062 
2064 {
2065  if (d->m_pluginmanager == pmanager)
2066  return;
2067 
2068  if (d->m_pluginmanager)
2069  {
2070  delete d->m_pluginmanager;
2071  d->m_pluginmanager = nullptr;
2072  }
2073 
2074  d->m_pluginmanager = pmanager;
2075 }
2076 
2078 {
2079  return d->m_pluginmanager;
2080 }
2081 
2083 {
2084  d->m_isexiting = exiting;
2085 }
2086 
2088 {
2089  return d->m_isexiting;
2090 }
2091 
2092 void MythCoreContext::RegisterFileForWrite(const QString& file, uint64_t size)
2093 {
2094  QMutexLocker lock(&d->m_fileslock);
2095 
2096  QPair<int64_t, uint64_t> pair(QDateTime::currentMSecsSinceEpoch(), size);
2097  d->m_fileswritten.insert(file, pair);
2098 
2099  if (IsBackend())
2100  {
2101  QString message = QString("FILE_WRITTEN %1 %2").arg(file).arg(size);
2102  MythEvent me(message);
2103  dispatch(me);
2104  }
2105 
2106  LOG(VB_FILE, LOG_DEBUG, LOC +
2107  QString("%1").arg(file));
2108 }
2109 
2111 {
2112  QMutexLocker lock(&d->m_fileslock);
2113 
2114  d->m_fileswritten.remove(file);
2115 
2116  if (IsBackend())
2117  {
2118  QString message = QString("FILE_CLOSED %1").arg(file);
2119  MythEvent me(message);
2120  dispatch(me);
2121  }
2122 
2123  LOG(VB_FILE, LOG_DEBUG, LOC +
2124  QString("%1").arg(file));
2125 }
2126 
2128 {
2129  QMutexLocker lock(&d->m_fileslock);
2130 
2131  return d->m_fileswritten.contains(file);
2132 }
2133 
2134 /* vim: set expandtab tabstop=4 shiftwidth=4: */
MythCoreContext::resolveSettingAddress
QString resolveSettingAddress(const QString &name, const QString &host=QString(), ResolveType type=ResolveAny, bool keepscope=false)
Retrieve IP setting "name" for "host".
Definition: mythcorecontext.cpp:1161
MythCoreContext::SetPluginManager
void SetPluginManager(MythPluginManager *pmanager)
Definition: mythcorecontext.cpp:2063
loggingDeregisterThread
void loggingDeregisterThread(void)
Deregister the current thread's name.
Definition: logging.cpp:751
MythCoreContext::SetWOLAllowed
void SetWOLAllowed(bool allow)
Definition: mythcorecontext.cpp:627
build_compdb.args
args
Definition: build_compdb.py:11
DestroyMythDB
void DestroyMythDB(void)
Definition: mythdb.cpp:55
MythLocale::ReInit
void ReInit()
Definition: mythlocale.cpp:52
MythCoreContextPrivate::WaitForWOL
bool WaitForWOL(std::chrono::milliseconds timeout=std::chrono::milliseconds::max())
If another thread has already started WOL process, wait on them...
Definition: mythcorecontext.cpp:197
MythCoreContext::SendMessage
void SendMessage(const QString &message)
Definition: mythcorecontext.cpp:1515
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
MythCoreContext::GetMasterHostName
QString GetMasterHostName(void)
Definition: mythcorecontext.cpp:805
MythPower
Definition: mythpower.h:23
MythPluginManager
Definition: mythplugin.h:62
MythCoreContextPrivate::m_fileswritten
QMap< QString, QPair< int64_t, uint64_t > > m_fileswritten
Definition: mythcorecontext.cpp:112
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:125
MythScheduler
This is an generic interface to a program scheduler.
Definition: mythscheduler.h:17
kMSDontBlockInputDevs
@ kMSDontBlockInputDevs
avoid blocking LIRC & Joystick Menu
Definition: mythsystem.h:36
MythCoreContext::GetScheduler
MythScheduler * GetScheduler(void)
Definition: mythcorecontext.cpp:1875
MythCoreContext::SendReceiveStringList
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
Definition: mythcorecontext.cpp:1369
MythCoreContext::IsBlockingClient
bool IsBlockingClient(void) const
is this client blocking shutdown
Definition: mythcorecontext.cpp:622
MythCoreContext::IsFrontendOnly
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
Definition: mythcorecontext.cpp:743
MythCoreContext::AllowShutdown
void AllowShutdown(void)
Definition: mythcorecontext.cpp:608
MythCoreContextPrivate::m_masterHostLock
QMutex m_masterHostLock
Locking for m_masterHostname.
Definition: mythcorecontext.cpp:73
MythCoreContext::ResetSockets
void ResetSockets(void)
Definition: mythcorecontext.cpp:1796
MythLocale
Definition: mythlocale.h:12
MythCoreContext::GetDBManager
MDBManager * GetDBManager(void)
Definition: mythcorecontext.cpp:863
MythCoreContext::UnregisterFileForWrite
void UnregisterFileForWrite(const QString &file)
Definition: mythcorecontext.cpp:2110
MythCoreContext::ConnectToMasterServer
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
Definition: mythcorecontext.cpp:355
MythCoreContextPrivate::m_eventSock
MythSocket * m_eventSock
socket events arrive on
Definition: mythcorecontext.cpp:80
MythCoreContext::GetLocale
MythLocale * GetLocale(void) const
Definition: mythcorecontext.cpp:1762
MythCoreContext::~MythCoreContext
~MythCoreContext() override
Definition: mythcorecontext.cpp:277
mythplugin.h
MythCoreContext::InitLocale
void InitLocale(void)
Definition: mythcorecontext.cpp:1820
ShutdownMythDownloadManager
void ShutdownMythDownloadManager(void)
Deletes the running MythDownloadManager at program exit.
Definition: mythdownloadmanager.cpp:133
MythCoreContext::SetScheduler
void SetScheduler(MythScheduler *sched)
Definition: mythcorecontext.cpp:1870
MythCoreContext::GetBackendStatusPort
int GetBackendStatusPort(void)
Returns the locally defined backend status port.
Definition: mythcorecontext.cpp:1090
MythCoreContext::OverrideSettingForSession
void OverrideSettingForSession(const QString &key, const QString &value)
Definition: mythcorecontext.cpp:1335
MDBManager
DB connection pool, used by MSqlQuery. Do not use directly.
Definition: mythdbcon.h:55
MythCoreContextPrivate::m_backend
bool m_backend
Definition: mythcorecontext.cpp:87
MythLocale::ToQLocale
QLocale ToQLocale() const
Definition: mythlocale.h:29
MythCoreContext::s_serverPortCache
static QHash< QString, int > s_serverPortCache
Definition: mythcorecontext.h:207
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
MythCoreContextPrivate::m_appBinaryVersion
QString m_appBinaryVersion
Definition: mythcorecontext.cpp:69
sched
Scheduler * sched
MythCoreContext::RegisterFileForWrite
void RegisterFileForWrite(const QString &file, uint64_t size=0LL)
Definition: mythcorecontext.cpp:2092
MythCoreContext::IsDatabaseIgnored
bool IsDatabaseIgnored(void) const
/brief Returns true if database is being ignored.
Definition: mythcorecontext.cpp:874
MythCoreContext::GetGUIObject
QObject * GetGUIObject(void)
Definition: mythcorecontext.cpp:1747
MythCoreContext::GetFilePrefix
QString GetFilePrefix(void)
Definition: mythcorecontext.cpp:842
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1346
MythCoreContext::connectionClosed
void connectionClosed(MythSocket *sock) override
Definition: mythcorecontext.cpp:1655
MythSocket::DisconnectFromHost
void DisconnectFromHost(void)
Definition: mythsocket.cpp:504
MythCoreContext::CheckProtoVersion
bool CheckProtoVersion(MythSocket *socket, std::chrono::milliseconds timeout=kMythSocketLongTimeout, bool error_dialog_desired=false)
Definition: mythcorecontext.cpp:1665
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
is_current_thread
bool is_current_thread(MThread *thread)
Use this to determine if you are in the named thread.
Definition: mthread.cpp:40
MythCoreContextPrivate::m_blockingClient
bool m_blockingClient
Definition: mythcorecontext.cpp:99
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:50
MythCoreContext::TestPluginVersion
static bool TestPluginVersion(const QString &name, const QString &libversion, const QString &pluginversion)
Definition: mythcorecontext.cpp:2049
build_compdb.file
file
Definition: build_compdb.py:55
MythCoreContextPrivate::m_intvwanting
bool m_intvwanting
Definition: mythcorecontext.cpp:104
MythObservable::dispatch
void dispatch(const MythEvent &event)
Dispatch an event to all listeners.
Definition: mythobservable.cpp:73
myth_system
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
Definition: mythsystemlegacy.cpp:506
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:11
MythCoreContext::GetScopeForAddress
bool GetScopeForAddress(QHostAddress &addr) const
Return the cached scope Id for the given address.
Definition: mythcorecontext.cpp:1107
MythSocket::ConnectToHost
bool ConnectToHost(const QString &hostname, quint16 port)
connect to host
Definition: mythsocket.cpp:380
MythCoreContext::setTestStringSettings
void setTestStringSettings(QMap< QString, QString > &overrides)
Definition: mythcorecontext.cpp:293
MythCoreContext::InitPower
void InitPower(bool Create=true)
Definition: mythcorecontext.cpp:1807
MythCoreContext::SafeConnectToMasterServer
bool SafeConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
Definition: mythcorecontext.cpp:344
hardwareprofile.distros.mythtv_data.data_mythtv.prefix
string prefix
Definition: data_mythtv.py:40
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
MythSocket::IsConnected
bool IsConnected(void) const
Definition: mythsocket.cpp:557
MythCoreContextPrivate::m_wolInProgressWaitCondition
QWaitCondition m_wolInProgressWaitCondition
Definition: mythcorecontext.cpp:83
MythCoreContextPrivate::m_database
MythDB * m_database
Definition: mythcorecontext.cpp:90
MythCoreContext::GetMasterServerStatusPort
int GetMasterServerStatusPort(void)
Returns the Master Backend status port If no master server status port has been defined in the databa...
Definition: mythcorecontext.cpp:991
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
MythCoreContextPrivate::m_scopesLock
QMutex m_scopesLock
Locking for m_masterHostname.
Definition: mythcorecontext.cpp:75
mythversion.h
mythsystemlegacy.h
SendAsyncMessage::SendAsyncMessage
SendAsyncMessage(QString msg, QStringList extra)
Definition: mythcorecontext.cpp:1495
MYTH_APPNAME_MYTHTV_SETUP
static constexpr const char * MYTH_APPNAME_MYTHTV_SETUP
Definition: mythcorecontext.h:23
MythCoreContext::SendHostSystemEvent
void SendHostSystemEvent(const QString &msg, const QString &hostname, const QString &args)
Definition: mythcorecontext.cpp:1551
MythCoreContextPrivate::m_pluginmanager
MythPluginManager * m_pluginmanager
Definition: mythcorecontext.cpp:108
LOC
#define LOC
Definition: mythcorecontext.cpp:52
MythSocket
Class for communcating between myth backends and frontends.
Definition: mythsocket.h:25
MythCoreContext::ClearOverrideSettingForSession
void ClearOverrideSettingForSession(const QString &key)
Definition: mythcorecontext.cpp:1341
MythCoreContext::IsConnectedToMaster
bool IsConnectedToMaster(void)
Definition: mythcorecontext.cpp:588
MythCoreContext::MythCoreContext
MythCoreContext(const QString &binversion, QObject *guiContext)
Definition: mythcorecontext.cpp:212
quit
@ quit
Definition: lirc_client.h:30
MYTH_PROTO_VERSION
static constexpr const char * MYTH_PROTO_VERSION
Increment this whenever the MythTV network protocol changes.
Definition: mythversion.h:47
MThreadPool::ShutdownAllPools
static void ShutdownAllPools(void)
Definition: mthreadpool.cpp:336
MythCoreContext::UnregisterForPlayback
void UnregisterForPlayback(QObject *sender)
Definition: mythcorecontext.cpp:1928
MythCoreContext::IsRegisteredFileForWrite
bool IsRegisteredFileForWrite(const QString &file)
Definition: mythcorecontext.cpp:2127
MythCoreContext::IsMasterBackend
bool IsMasterBackend(void)
is this the actual MBE process
Definition: mythcorecontext.cpp:693
MythCoreContextPrivate::m_playbackLock
QMutex m_playbackLock
Definition: mythcorecontext.cpp:102
mythdate.h
MythCoreContextPrivate::m_localHostname
QString m_localHostname
hostname from config.xml or gethostname()
Definition: mythcorecontext.cpp:72
MythCoreContextPrivate::m_isWOLAllowed
bool m_isWOLAllowed
Definition: mythcorecontext.cpp:85
mythlogging.h
MythCoreContext::Init
bool Init(void)
Definition: mythcorecontext.cpp:218
MythCoreContext::GenMythURL
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
Definition: mythcorecontext.cpp:758
MythCoreContext::GetGUIContext
QObject * GetGUIContext(void)
Definition: mythcorecontext.cpp:1752
MythCoreContext::GetQLocale
QLocale GetQLocale(void)
Definition: mythcorecontext.cpp:1844
MythCoreContext::BackendIsRunning
static bool BackendIsRunning(void)
a backend process is running on this host
Definition: mythcorecontext.cpp:698
MythSocket::WriteStringList
bool WriteStringList(const QStringList &list)
Definition: mythsocket.cpp:307
MythCoreContext::SetAsFrontend
void SetAsFrontend(bool frontend)
Definition: mythcorecontext.cpp:647
MThreadPool::StopAllPools
static void StopAllPools(void)
Definition: mthreadpool.cpp:325
MythCoreContext::GetBackendServerPort
int GetBackendServerPort(void)
Returns the locally defined backend control port.
Definition: mythcorecontext.cpp:1062
MythCoreContext::SendSystemEvent
void SendSystemEvent(const QString &msg)
Definition: mythcorecontext.cpp:1542
MythCoreContextPrivate::m_isexiting
bool m_isexiting
Definition: mythcorecontext.cpp:110
MythCoreContext::SendEvent
void SendEvent(const MythEvent &event)
Definition: mythcorecontext.cpp:1528
MythCoreContext::GetMasterServerIP
QString GetMasterServerIP(void)
Returns the Master Backend IP address If the address is an IPv6 address, the scope Id is removed.
Definition: mythcorecontext.cpp:964
MythCoreContext::WaitUntilSignals
void WaitUntilSignals(std::vector< CoreWaitInfo > &sigs) const
Wait until any of the provided signals have been received.
Definition: mythcorecontext.cpp:1884
MythCoreContextPrivate::m_parent
MythCoreContext * m_parent
Definition: mythcorecontext.cpp:66
hardwareprofile.i18n.t
t
Definition: i18n.py:36
MythCoreContextPrivate::m_frontend
bool m_frontend
Definition: mythcorecontext.cpp:88
compat.h
MythPower::AcquireRelease
static MythPower * AcquireRelease(void *Reference, bool Acquire, std::chrono::seconds MinimumDelay=0s)
Definition: mythpower.cpp:75
MythCoreContext::GetBackendServerIP
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
Definition: mythcorecontext.cpp:1002
MythCoreContextPrivate::m_sessionManager
MythSessionManager * m_sessionManager
Definition: mythcorecontext.cpp:115
MythCoreContext::IsFrontend
bool IsFrontend(void) const
is this process a frontend process
Definition: mythcorecontext.cpp:652
MythCoreContextPrivate::m_guiObject
QObject * m_guiObject
Definition: mythcorecontext.cpp:68
MythCoreContext::GetDB
MythDB * GetDB(void)
Definition: mythcorecontext.cpp:1757
MythCoreContext::readyRead
void readyRead(MythSocket *sock) override
Definition: mythcorecontext.cpp:1559
MythWakeup
bool MythWakeup(const QString &wakeUpCommand, uint flags, std::chrono::seconds timeout)
Definition: mythmiscutil.cpp:631
MythCoreContext::GetNumSettingOnHost
int GetNumSettingOnHost(const QString &key, const QString &host, int defaultval=0)
Definition: mythcorecontext.cpp:941
MythCoreContextPrivate::m_approvedIps
QList< QHostAddress > m_approvedIps
Definition: mythcorecontext.cpp:117
MythCoreContextPrivate::m_wolInProgressLock
QMutex m_wolInProgressLock
Definition: mythcorecontext.cpp:82
MythCoreContext::GetResolutionSetting
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
Definition: mythcorecontext.cpp:847
MythCoreContext::RegisterForPlayback
void RegisterForPlayback(QObject *sender, PlaybackStartCb method)
Definition: mythcorecontext.cpp:1907
MythCoreContext::GetBackendServerIP4
QString GetBackendServerIP4(void)
Returns the IPv4 address defined for the current host see GetBackendServerIP4(host)
Definition: mythcorecontext.cpp:1025
MythCoreContext::m_testOverrideStrings
QMap< QString, QString > m_testOverrideStrings
Definition: mythcorecontext.h:322
SendAsyncMessage::m_message
QString m_message
Definition: mythcorecontext.cpp:1511
MythCoreContext::TVPlaybackAboutToStart
void TVPlaybackAboutToStart(void)
MythSocket::kShortTimeout
static constexpr std::chrono::milliseconds kShortTimeout
Definition: mythsocket.h:70
SendAsyncMessage
Definition: mythcorecontext.cpp:1492
MythCoreContext::ConnectCommandSocket
MythSocket * ConnectCommandSocket(const QString &hostname, int port, const QString &announcement, bool *proto_mismatch=nullptr, int maxConnTry=-1, std::chrono::milliseconds setup_timeout=-1ms)
Definition: mythcorecontext.cpp:425
MYTH_BINARY_VERSION
static constexpr const char * MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:15
uint
unsigned int uint
Definition: compat.h:79
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
SendAsyncMessage::m_extraData
QStringList m_extraData
Definition: mythcorecontext.cpp:1512
MythCoreContextPrivate::~MythCoreContextPrivate
~MythCoreContextPrivate() override
Definition: mythcorecontext.cpp:153
MythCoreContext::ConnectEventSocket
MythSocket * ConnectEventSocket(const QString &hostname, int port)
Definition: mythcorecontext.cpp:543
MythCoreContext::GetLanguage
QString GetLanguage(void)
Returns two character ISO-639 language descriptor for UI language.
Definition: mythcorecontext.cpp:1771
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:910
logStop
void logStop(void)
Entry point for stopping logging for an application.
Definition: logging.cpp:717
MythLocale::SaveLocaleDefaults
void SaveLocaleDefaults(bool overwrite=false)
Definition: mythlocale.cpp:171
MythCoreContext::ResolveIPv6
@ ResolveIPv6
Definition: mythcorecontext.h:212
MythCoreContext::resolveAddress
static QString resolveAddress(const QString &host, ResolveType type=ResolveAny, bool keepscope=false)
if host is an IP address, it will be returned or resolved otherwise.
Definition: mythcorecontext.cpp:1190
MythCoreContext::SetLocalHostname
void SetLocalHostname(const QString &hostname)
Definition: mythcorecontext.cpp:1730
MythCoreContextPrivate::m_locale
MythLocale * m_locale
Definition: mythcorecontext.cpp:94
SendAsyncMessage::run
void run(void) override
Definition: mythcorecontext.cpp:1502
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:904
mthreadpool.h
MythEvent::ExtraDataList
const QStringList & ExtraDataList() const
Definition: mythevent.h:67
MythCoreContext::GetMasterServerPort
static int GetMasterServerPort(void)
Returns the Master Backend control port If no master server port has been defined in the database,...
Definition: mythcorecontext.cpp:978
MythCoreContextPrivate::m_playbackClients
QMap< QObject *, MythCoreContext::PlaybackStartCb > m_playbackClients
Definition: mythcorecontext.cpp:101
MythCoreContext::InWantingPlayback
bool InWantingPlayback(void)
Returns true if a client has requested playback.
Definition: mythcorecontext.cpp:2025
MythCoreContext::ResolveIPv4
@ ResolveIPv4
Definition: mythcorecontext.h:212
MythCoreContext
This class contains the runtime context for MythTV.
Definition: mythcorecontext.h:63
mythmiscutil.h
MythCoreContext::setTestIntSettings
void setTestIntSettings(QMap< QString, int > &overrides)
Definition: mythcorecontext.cpp:283
mythcorecontext.h
MythCoreContext::m_testOverrideFloats
QMap< QString, double > m_testOverrideFloats
Definition: mythcorecontext.h:321
MythCoreContextPrivate::m_announcedProtocol
bool m_announcedProtocol
Definition: mythcorecontext.cpp:106
MythCoreContext::IsBackend
bool IsBackend(void) const
is this process a backend process
Definition: mythcorecontext.cpp:642
kLinkLocal
static QPair< QHostAddress, int > kLinkLocal
Definition: serverpool.cpp:27
MythCoreContextPrivate::m_masterHostname
QString m_masterHostname
master backend hostname
Definition: mythcorecontext.cpp:74
MythCoreContext::ResetLanguage
void ResetLanguage(void)
Definition: mythcorecontext.cpp:1791
MythCoreContext::GetSettingOnHost
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
Definition: mythcorecontext.cpp:924
MythCoreContextPrivate::m_scopes
QMap< QString, QString > m_scopes
Scope Id cache for Link-Local addresses.
Definition: mythcorecontext.cpp:76
kMSProcessEvents
@ kMSProcessEvents
process events while waiting
Definition: mythsystem.h:39
MythCoreContext::GetLanguageAndVariant
QString GetLanguageAndVariant(void)
Returns the user-set language and variant.
Definition: mythcorecontext.cpp:1783
std
Definition: mythchrono.h:23
MythCoreContextPrivate::m_serverSock
MythSocket * m_serverSock
socket for sending MythProto requests
Definition: mythcorecontext.cpp:79
serverpool.h
MythCoreContextPrivate::m_wolInProgress
bool m_wolInProgress
Definition: mythcorecontext.cpp:84
MythSocket::IsDataAvailable
bool IsDataAvailable(void)
Definition: mythsocket.cpp:563
MythCoreContextPrivate::m_inwanting
bool m_inwanting
Definition: mythcorecontext.cpp:103
MythCoreContext::ClearBackendServerPortCache
static void ClearBackendServerPortCache()
Definition: mythcorecontext.cpp:1069
logging.h
MYTH_PROTO_TOKEN
static constexpr const char * MYTH_PROTO_TOKEN
Definition: mythversion.h:48
mthread.h
MythCoreContext::TVInWantingPlayback
void TVInWantingPlayback(bool b)
Let the TV class tell us if we was interrupted following a call to WantingPlayback().
Definition: mythcorecontext.cpp:2013
MythCoreContext::d
MythCoreContextPrivate * d
Definition: mythcorecontext.h:313
MythCoreContextPrivate::m_uiThread
QThread * m_uiThread
Definition: mythcorecontext.cpp:92
SendAsyncMessage::SendAsyncMessage
SendAsyncMessage(QString msg)
Definition: mythcorecontext.cpp:1500
MythCoreContext::ActivateSettingsCache
void ActivateSettingsCache(bool activate=true)
Definition: mythcorecontext.cpp:831
MThread::Cleanup
static void Cleanup(void)
This will print out all the running threads, call exit(1) on each and then wait up to 5 seconds total...
Definition: mthread.cpp:142
MythCoreContext::ResolveType
ResolveType
Definition: mythcorecontext.h:212
MythCoreContextPrivate::m_sockLock
QMutex m_sockLock
protects both m_serverSock and m_eventSock
Definition: mythcorecontext.cpp:78
MythLocale::GetLocaleCode
QString GetLocaleCode() const
Name of language in that language.
Definition: mythlocale.h:27
MythCoreContext::WantingPlayback
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
Definition: mythcorecontext.cpp:1947
ShutdownMythSystemLegacy
void MBASE_PUBLIC ShutdownMythSystemLegacy(void)
Definition: mythsystemunix.cpp:75
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:836
MythCoreContextPrivate::m_scheduler
MythScheduler * m_scheduler
Definition: mythcorecontext.cpp:97
MythCoreContext::ReInitLocale
void ReInitLocale(void)
Definition: mythcorecontext.cpp:1831
MThread::ThreadSetup
static void ThreadSetup(const QString &name)
This is to be called on startup in those few threads that haven't been ported to MThread.
Definition: mthread.cpp:221
MythCoreContextPrivate::m_deniedIps
QList< QHostAddress > m_deniedIps
Definition: mythcorecontext.cpp:118
MythCoreContext::IsExiting
bool IsExiting(void)
Definition: mythcorecontext.cpp:2087
MythCoreContext::GetBoolSettingOnHost
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
Definition: mythcorecontext.cpp:933
MythCoreContext::ClearSettingsCache
void ClearSettingsCache(const QString &myKey=QString(""))
Definition: mythcorecontext.cpp:826
MythCoreContext::IsThisHost
bool IsThisHost(const QString &addr)
is this address mapped to this host
Definition: mythcorecontext.cpp:719
MythCoreContext::HasGUI
bool HasGUI(void) const
Definition: mythcorecontext.cpp:1742
MythCoreContext::IsMasterHost
bool IsMasterHost(void)
is this the same host as the master
Definition: mythcorecontext.cpp:657
MythCoreContextPrivate::m_localHostLock
QMutex m_localHostLock
Locking for m_localHostname.
Definition: mythcorecontext.cpp:71
musicbrainzngs.caa.hostname
string hostname
Definition: caa.py:17
mythpower.h
MythCoreContext::BlockShutdown
void BlockShutdown(void)
Definition: mythcorecontext.cpp:594
MythCoreContext::IsWOLAllowed
bool IsWOLAllowed() const
Definition: mythcorecontext.cpp:632
MythCoreContext::GetFloatSetting
double GetFloatSetting(const QString &key, double defaultval=0.0)
Definition: mythcorecontext.cpp:917
kMSDontDisableDrawing
@ kMSDontDisableDrawing
avoid disabling UI drawing
Definition: mythsystem.h:37
MythCoreContextPrivate::m_fileslock
QMutex m_fileslock
Definition: mythcorecontext.cpp:113
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:879
MythCoreContext::GetMasterHostPrefix
QString GetMasterHostPrefix(const QString &storageGroup=QString(), const QString &path=QString())
Definition: mythcorecontext.cpp:796
MythCoreContext::GetSessionManager
MythSessionManager * GetSessionManager(void)
Definition: mythcorecontext.cpp:2041
exitcodes.h
mythdownloadmanager.h
MythCoreContext::GetBackendServerIP6
QString GetBackendServerIP6(void)
Returns the IPv6 address defined for the current host see GetBackendServerIP6(host)
Definition: mythcorecontext.cpp:1044
delete_sock
static void delete_sock(QMutexLocker< QMutex > &locker, MythSocket **s)
Definition: mythcorecontext.cpp:135
MThreadPool::globalInstance
static MThreadPool * globalInstance(void)
Definition: mthreadpool.cpp:317
MythCoreContext::GetPluginManager
MythPluginManager * GetPluginManager(void)
Definition: mythcorecontext.cpp:2077
MythCoreContext::SetScopeForAddress
void SetScopeForAddress(const QHostAddress &addr)
Record the scope Id of the given IP address.
Definition: mythcorecontext.cpp:1127
MythSocket::kLongTimeout
static constexpr std::chrono::milliseconds kLongTimeout
Definition: mythsocket.h:71
MythCoreContext::SetupCommandSocket
bool SetupCommandSocket(MythSocket *serverSock, const QString &announcement, std::chrono::milliseconds timeout, bool &proto_mismatch)
Definition: mythcorecontext.cpp:298
MythCoreContext::CheckSubnet
bool CheckSubnet(const QAbstractSocket *socket)
Check if a socket is connected to an approved peer.
Definition: mythcorecontext.cpp:1266
mythsocket.h
MythCoreContextPrivate::m_guiContext
QObject * m_guiContext
Definition: mythcorecontext.cpp:67
MythCoreContextPrivate
Definition: mythcorecontext.cpp:56
MythCoreContext::SaveLocaleDefaults
void SaveLocaleDefaults(void)
Definition: mythcorecontext.cpp:1852
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1723
MythCoreContextPrivate::m_language
QString m_language
Definition: mythcorecontext.cpp:95
MythCoreContext::SaveSettingOnHost
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
Definition: mythcorecontext.cpp:889
MythSocket::ReadStringList
bool ReadStringList(QStringList &list, std::chrono::milliseconds timeoutMS=kShortTimeout)
Definition: mythsocket.cpp:319
MythCoreContext::SetAsBackend
void SetAsBackend(bool backend)
Definition: mythcorecontext.cpp:637
MythCoreContext::m_testOverrideInts
QMap< QString, int > m_testOverrideInts
Definition: mythcorecontext.h:320
MythCoreContext::PlaybackStartCb
void(QObject::*)(void) PlaybackStartCb
Definition: mythcorecontext.h:241
MythCoreContext::IsThisBackend
bool IsThisBackend(const QString &addr)
is this address mapped to this backend host
Definition: mythcorecontext.cpp:714
MythCoreContext::setTestFloatSettings
void setTestFloatSettings(QMap< QString, double > &overrides)
Definition: mythcorecontext.cpp:288
MythCoreContext::GetFloatSettingOnHost
double GetFloatSettingOnHost(const QString &key, const QString &host, double defaultval=0.0)
Definition: mythcorecontext.cpp:950
MThreadPool::start
void start(QRunnable *runnable, const QString &debugName, int priority=0)
Definition: mthreadpool.cpp:352
MythCoreContext::SetExiting
void SetExiting(bool exiting=true)
Definition: mythcorecontext.cpp:2082
MythCoreContext::SetGUIObject
void SetGUIObject(QObject *gui)
Definition: mythcorecontext.cpp:1737
MythSocket::SendReceiveStringList
bool SendReceiveStringList(QStringList &list, uint min_reply_length=0, std::chrono::milliseconds timeoutMS=kLongTimeout)
Definition: mythsocket.cpp:332
MythCoreContextPrivate::m_power
MythPower * m_power
Definition: mythcorecontext.cpp:120
MythCoreContextPrivate::MythCoreContextPrivate
MythCoreContextPrivate(MythCoreContext *lparent, QString binversion, QObject *guicontext)
Definition: mythcorecontext.cpp:123
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:896
MythSessionManager
Definition: mythsession.h:102