From 4a2de2ed99c67703f412a58c25f13693074bb765 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Mon, 8 Jul 2013 17:37:28 +1000 Subject: [PATCH] Fix infinite loop If we have a registration from a client which will survive MythMainWindow, the screen would have been re-created, which would have re-created the screen stack, which would have caused an infinite loop in MythMainWindow destructor. Only create a screen stack once. --- .../libmythui/mythuinotificationcenter.cpp | 56 ++++++++++--------- .../mythuinotificationcenter_private.h | 1 - 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/mythtv/libs/libmythui/mythuinotificationcenter.cpp b/mythtv/libs/libmythui/mythuinotificationcenter.cpp index 500ea6beda1..3f9b06c1cf2 100644 --- a/mythtv/libs/libmythui/mythuinotificationcenter.cpp +++ b/mythtv/libs/libmythui/mythuinotificationcenter.cpp @@ -473,9 +473,11 @@ void MythUINotificationScreen::SetSingleShotTimer(int s) /////////////////////// NCPrivate NCPrivate::NCPrivate() - : m_screenStack(NULL), m_currentId(0) + : m_currentId(0) { - + m_screenStack = new MythNotificationScreenStack(GetMythMainWindow(), + "mythuinotification", + this); } NCPrivate::~NCPrivate() @@ -547,16 +549,24 @@ void NCPrivate::ScreenDeleted(void) { if (!duefordeletion) { - // don't remove the id from the list, as the application is still registered - // re-create the screen - MythUINotificationScreen *newscreen = - new MythUINotificationScreen(GetScreenStack(), *screen); - connect(newscreen, SIGNAL(ScreenDeleted()), this, SLOT(ScreenDeleted())); - m_registrations[screen->m_id] = newscreen; - // Screen was deleted, add it to suspended list - m_suspended.append(screen->m_id); - LOG(VB_GUI, LOG_DEBUG, LOC + - "ScreenDeleted: Suspending registered screen"); + if (!m_screenStack) + { + // we're in the middle of being deleted + m_registrations.remove(screen->m_id); + } + else + { + // don't remove the id from the list, as the application is still registered + // re-create the screen + MythUINotificationScreen *newscreen = + new MythUINotificationScreen(m_screenStack, *screen); + connect(newscreen, SIGNAL(ScreenDeleted()), this, SLOT(ScreenDeleted())); + m_registrations[screen->m_id] = newscreen; + // Screen was deleted, add it to suspended list + m_suspended.append(screen->m_id); + LOG(VB_GUI, LOG_DEBUG, LOC + + "ScreenDeleted: Suspending registered screen"); + } } else { @@ -688,11 +698,11 @@ MythUINotificationScreen *NCPrivate::CreateScreen(MythNotification *n, int id) if (n) { - screen = new MythUINotificationScreen(GetScreenStack(), *n); + screen = new MythUINotificationScreen(m_screenStack, *n); } else { - screen = new MythUINotificationScreen(GetScreenStack(), id); + screen = new MythUINotificationScreen(m_screenStack, id); } if (!screen->Create()) // Reads screen definition from xml, and constructs screen @@ -761,17 +771,6 @@ void NCPrivate::UnRegister(void *from, int id, bool closeimemdiately) GetMythMainWindow(), new MythUINotificationCenterEvent()); } -MythNotificationScreenStack *NCPrivate::GetScreenStack(void) -{ - if (!m_screenStack) - { - m_screenStack = new MythNotificationScreenStack(GetMythMainWindow(), - "mythuinotification", - this); - } - return m_screenStack; -} - void NCPrivate::DeleteAllRegistrations(void) { QMap::iterator it = m_registrations.begin(); @@ -884,11 +883,14 @@ void NCPrivate::GetNotificationScreens(QList &_screens) QList list; QVector screens; - GetScreenStack()->CheckDeletes(); + if (!m_screenStack) + return; + + m_screenStack->CheckDeletes(); QMutexLocker lock(&m_lock); - GetScreenStack()->GetScreenList(screens); + m_screenStack->GetScreenList(screens); QVector::const_iterator it = screens.begin(); QVector::const_iterator itend = screens.end(); diff --git a/mythtv/libs/libmythui/mythuinotificationcenter_private.h b/mythtv/libs/libmythui/mythuinotificationcenter_private.h index 9c327ed9a2e..923379d5efd 100644 --- a/mythtv/libs/libmythui/mythuinotificationcenter_private.h +++ b/mythtv/libs/libmythui/mythuinotificationcenter_private.h @@ -106,7 +106,6 @@ public slots: MythUINotificationScreen *CreateScreen(MythNotification *notification, int id = -1); - MythNotificationScreenStack *GetScreenStack(void); void DeleteAllRegistrations(void); void DeleteAllScreens(void); int InsertScreen(MythUINotificationScreen *screen);