00001 #include <QCoreApplication>
00002 #include <QRunnable>
00003 #include <QString>
00004 #include <QEvent>
00005 #include <QTimer>
00006
00007 #include "backendconnectionmanager.h"
00008 #include "mythcorecontext.h"
00009 #include "mythdialogbox.h"
00010 #include "mythscreenstack.h"
00011 #include "mythmainwindow.h"
00012 #include "mthreadpool.h"
00013 #include "mythlogging.h"
00014 #include "exitcodes.h"
00015 #include "mythmiscutil.h"
00016
00017 class Reconnect : public QRunnable
00018 {
00019 public:
00020 Reconnect()
00021 {
00022 setAutoDelete(false);
00023 }
00024
00025 virtual void run(void)
00026 {
00027 if (gCoreContext->GetMasterHostPrefix().isEmpty())
00028 gCoreContext->dispatch(MythEvent(QString("RECONNECT_FAILURE")));
00029 else
00030 gCoreContext->dispatch(MythEvent(QString("RECONNECT_SUCCESS")));
00031 }
00032 };
00033
00034 BackendConnectionManager::BackendConnectionManager() :
00035 QObject(), m_reconnecting(NULL), m_reconnect_timer(NULL), m_first_time(true)
00036 {
00037 gCoreContext->addListener(this);
00038
00039 uint reconnect_timeout = 1;
00040 m_reconnect_timer = new QTimer(this);
00041 m_reconnect_timer->setSingleShot(true);
00042 connect(m_reconnect_timer, SIGNAL(timeout()),
00043 this, SLOT(ReconnectToBackend()));
00044 m_reconnect_timer->start(reconnect_timeout);
00045 }
00046
00047 BackendConnectionManager::~BackendConnectionManager()
00048 {
00049 while (m_reconnecting)
00050 usleep(250*1000);
00051 gCoreContext->removeListener(this);
00052 }
00053
00054 void BackendConnectionManager::customEvent(QEvent *event)
00055 {
00056 bool reconnect = false;
00057 uint reconnect_timeout = 5000;
00058
00059 if ((MythEvent::Type)(event->type()) == MythEvent::MythEventMessage)
00060 {
00061 MythEvent *me = (MythEvent *)event;
00062 QString message = me->Message();
00063
00064 if (message == "BACKEND_SOCKETS_CLOSED")
00065 {
00066 if (!m_reconnecting)
00067 {
00068 reconnect = true;
00069 reconnect_timeout = 500;
00070 }
00071 }
00072 else if (message == "RECONNECT_SUCCESS")
00073 {
00074 delete m_reconnecting;
00075 m_reconnecting = NULL;
00076 if (m_first_time && !checkTimeZone())
00077 {
00078
00079
00080 LOG(VB_GENERAL, LOG_ERR,
00081 "The time and/or time zone settings on this "
00082 "system do not match those in use on the master "
00083 "backend. Please ensure all frontend and backend "
00084 "systems are configured to use the same time "
00085 "zone and have the current time properly set.");
00086 LOG(VB_GENERAL, LOG_ERR,
00087 "Unable to run with invalid time settings. Exiting.");
00088 MythScreenStack *popupStack = GetMythMainWindow()->
00089 GetStack("popup stack");
00090 QString message = tr("Your frontend and backend are configured "
00091 "in different timezones. You must "
00092 "correct this mismatch to continue.");
00093 MythConfirmationDialog *error = new MythConfirmationDialog(
00094 popupStack, message, false);
00095 if (error->Create())
00096 {
00097 QObject::connect(error, SIGNAL(haveResult(bool)),
00098 qApp, SLOT(quit()));
00099 popupStack->AddScreen(error);
00100 }
00101 else
00102 {
00103 delete error;
00104 delete popupStack;
00105 qApp->exit(GENERIC_EXIT_INVALID_TIMEZONE);
00106 }
00107 }
00108 m_first_time = false;
00109 }
00110 else if (message == "RECONNECT_FAILURE")
00111 {
00112 delete m_reconnecting;
00113 m_reconnecting = NULL;
00114 reconnect = true;
00115 }
00116 }
00117
00118 if (reconnect)
00119 {
00120 if (!m_reconnect_timer)
00121 {
00122 m_reconnect_timer = new QTimer(this);
00123 m_reconnect_timer->setSingleShot(true);
00124 connect(m_reconnect_timer, SIGNAL(timeout()),
00125 this, SLOT(ReconnectToBackend()));
00126 }
00127 m_reconnect_timer->start(reconnect_timeout);
00128 }
00129 }
00130
00131 void BackendConnectionManager::ReconnectToBackend(void)
00132 {
00133 m_reconnecting = new Reconnect();
00134 MThreadPool::globalInstance()->start(m_reconnecting, "Reconnect");
00135 }