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