From 9665e956da0f27535c2fe17642d6474df43f5f97 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Tue, 9 Jul 2013 21:45:50 +1000 Subject: [PATCH] Fix notifications not using their allocated screen should the client unregistered before notifications queued could be processed. Fix notification leaks should screen failing to be created... --- .../libmythui/mythuinotificationcenter.cpp | 63 +++++++++++++++---- .../mythuinotificationcenter_private.h | 2 + 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/mythtv/libs/libmythui/mythuinotificationcenter.cpp b/mythtv/libs/libmythui/mythuinotificationcenter.cpp index c0488aa9952..0765093b109 100644 --- a/mythtv/libs/libmythui/mythuinotificationcenter.cpp +++ b/mythtv/libs/libmythui/mythuinotificationcenter.cpp @@ -489,6 +489,7 @@ NCPrivate::~NCPrivate() QMutexLocker lock(&m_lock); + DeleteUnregistered(); DeleteAllRegistrations(); DeleteAllScreens(); @@ -550,6 +551,7 @@ void NCPrivate::ScreenDeleted(void) { // we're in the middle of being deleted m_registrations.remove(screen->m_id); + m_unregistered.remove(screen->m_id); } else { @@ -648,6 +650,7 @@ void NCPrivate::ProcessQueue(void) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("ProcessQueue: couldn't create required screen")); + delete n; continue; // something is wrong ; ignore } if (id > 0) @@ -667,6 +670,7 @@ void NCPrivate::ProcessQueue(void) if (!screen->Create()) { delete screen; + delete n; continue; } created = true; @@ -683,6 +687,8 @@ void NCPrivate::ProcessQueue(void) delete n; } m_notifications.clear(); + + DeleteUnregistered(); } /** @@ -748,19 +754,9 @@ void NCPrivate::UnRegister(void *from, int id, bool closeimemdiately) .arg(id)); } - if (m_registrations.contains(id)) - { - MythUINotificationScreen *screen = m_registrations[id]; - if (screen != NULL) - { - // mark the screen for deletion if no timer is set - if (screen->m_duration <= 0 || closeimemdiately) - { - m_deletedScreens.append(screen); - } - } - m_registrations.remove(id); - } + // queue the de-registration + m_unregistered[id] = closeimemdiately; + m_clients.remove(id); // Tell the GUI thread we have something to process @@ -793,6 +789,47 @@ void NCPrivate::DeleteAllScreens(void) } } +void NCPrivate::DeleteUnregistered(void) +{ + QMap::iterator it = m_unregistered.begin(); + bool needdelete = false; + + for (; it != m_unregistered.end(); ++it) + { + int id = it.key(); + bool closeimemdiately = it.value(); + MythUINotificationScreen *screen = NULL; + + if (m_registrations.contains(id)) + { + screen = m_registrations[id]; + if (screen != NULL && !m_suspended.contains(id)) + { + // mark the screen for deletion if no timer is set + if (screen->m_duration <= 0 || closeimemdiately) + { + m_deletedScreens.append(screen); + needdelete = true; + } + } + m_registrations.remove(id); + } + + if (m_suspended.contains(id)) + { + // screen had been suspended, delete suspended screen + delete screen; + m_suspended.removeAll(id); + } + } + m_unregistered.clear(); + + if (needdelete) + { + DeleteAllScreens(); + } +} + /** * Insert screen into list of screens. * Returns index in screens list. diff --git a/mythtv/libs/libmythui/mythuinotificationcenter_private.h b/mythtv/libs/libmythui/mythuinotificationcenter_private.h index e37efe45030..eb8128785e7 100644 --- a/mythtv/libs/libmythui/mythuinotificationcenter_private.h +++ b/mythtv/libs/libmythui/mythuinotificationcenter_private.h @@ -108,6 +108,7 @@ public slots: int id = -1); void DeleteAllRegistrations(void); void DeleteAllScreens(void); + void DeleteUnregistered(void); int InsertScreen(MythUINotificationScreen *screen); int RemoveScreen(MythUINotificationScreen *screen); void RefreshScreenPosition(int from = 0); @@ -118,6 +119,7 @@ public slots: QList m_deletedScreens; QMap m_registrations; QList m_suspended; + QMap m_unregistered; QMap m_clients; QMutex m_lock; int m_currentId;