diff options
author | Kai Sommerfeld <kai.sommerfeld@gmx.com> | 2017-01-25 19:57:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-25 19:57:21 +0100 |
commit | d73ae2bf3099c51113200a1b41704da433c28873 (patch) | |
tree | 8d8f897d27a7e8c855a5a7f3f7b5e756060ecf18 | |
parent | 3079409a0e2dad242859b98e4774d3a4ccf25f2a (diff) | |
parent | 9504273e13a0a726c082cb7cd56d3313062933ac (diff) |
Merge pull request #11536 from ksooo/pvr-fix-channeliconsearch-deadlock
[PVR] Trac 17246: Fix deadlock that might occur during initial channel icon search.
-rw-r--r-- | xbmc/pvr/channels/PVRChannelGroup.cpp | 32 | ||||
-rw-r--r-- | xbmc/pvr/channels/PVRChannelGroup.h | 14 |
2 files changed, 37 insertions, 9 deletions
diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp index d3096b992f..302836dec1 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.cpp +++ b/xbmc/pvr/channels/PVRChannelGroup.cpp @@ -33,6 +33,7 @@ #include "settings/lib/Setting.h" #include "settings/Settings.h" #include "threads/SingleLock.h" +#include "utils/JobManager.h" #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" @@ -268,26 +269,37 @@ bool CPVRChannelGroup::MoveChannel(unsigned int iOldChannelNumber, unsigned int void CPVRChannelGroup::SearchAndSetChannelIcons(bool bUpdateDb /* = false */) { + // searching and setting channel icons may take some time, and (more important) + // it triggers GUI which might lead to deadlocks if directly called. + PVR_CHANNEL_GROUP_MEMBERS groupMembers; + { + CSingleLock lock(m_critSection); + groupMembers = m_members; + } + + CJobManager::GetInstance().AddJob(new CPVRSearchAndSetChannelIcons(groupMembers, bUpdateDb), nullptr); +} + +bool CPVRSearchAndSetChannelIcons::DoWork() +{ std::string iconPath = CServiceBroker::GetSettings().GetString(CSettings::SETTING_PVRMENU_ICONPATH); if (iconPath.empty()) - return; + return true; const CPVRDatabasePtr database(g_PVRManager.GetTVDatabase()); if (!database) - return; + return false; /* fetch files in icon path for fast lookup */ CFileItemList fileItemList; XFILE::CDirectory::GetDirectory(iconPath, fileItemList, ".jpg|.png|.tbn"); if (fileItemList.IsEmpty()) - return; + return true; CGUIDialogExtendedProgressBar* dlgProgress = (CGUIDialogExtendedProgressBar*)g_windowManager.GetWindow(WINDOW_DIALOG_EXT_PROGRESS); CGUIDialogProgressBarHandle* dlgProgressHandle = dlgProgress ? dlgProgress->GetHandle(g_localizeStrings.Get(19287)) : NULL; - CSingleLock lock(m_critSection); - /* create a map for fast lookup of normalized file base name */ std::map<std::string, std::string> fileItemMap; const VECFILEITEMS &items = fileItemList.GetList(); @@ -301,14 +313,14 @@ void CPVRChannelGroup::SearchAndSetChannelIcons(bool bUpdateDb /* = false */) int channelIndex = 0; CPVRChannelPtr channel; - for(PVR_CHANNEL_GROUP_MEMBERS::const_iterator it = m_members.begin(); it != m_members.end(); ++it) + for(const auto &groupMember : m_groupMembers) { - channel = it->second.channel; + channel = groupMember.second.channel; /* update progress dialog */ if (dlgProgressHandle) { - dlgProgressHandle->SetProgress(channelIndex++, m_members.size()); + dlgProgressHandle->SetProgress(channelIndex++, m_groupMembers.size()); dlgProgressHandle->SetText(channel->ChannelName()); } @@ -333,7 +345,7 @@ void CPVRChannelGroup::SearchAndSetChannelIcons(bool bUpdateDb /* = false */) channel->SetIconPath(itItem->second, g_advancedSettings.m_bPVRAutoScanIconsUserSet); } - if (bUpdateDb) + if (m_bUpdateDb) channel->Persist(); //! @todo start channel icon scraper here if nothing was found @@ -341,6 +353,8 @@ void CPVRChannelGroup::SearchAndSetChannelIcons(bool bUpdateDb /* = false */) if (dlgProgressHandle) dlgProgressHandle->MarkFinished(); + + return true; } /********** sort methods **********/ diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h index 5fd56c7c9d..d598ac9ad8 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.h +++ b/xbmc/pvr/channels/PVRChannelGroup.h @@ -540,4 +540,18 @@ namespace PVR private: CPVRChannelGroupPtr m_group; }; + + class CPVRSearchAndSetChannelIcons : public CJob + { + public: + CPVRSearchAndSetChannelIcons(const PVR_CHANNEL_GROUP_MEMBERS &groupMembers, bool bUpdateDb) + : m_groupMembers(groupMembers), m_bUpdateDb(bUpdateDb) {} + virtual ~CPVRSearchAndSetChannelIcons() {} + virtual const char *GetType() const { return "pvr-channelgroup-searchandsetchannelicons"; } + + virtual bool DoWork(); + private: + PVR_CHANNEL_GROUP_MEMBERS m_groupMembers; + const bool m_bUpdateDb; + }; } |