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