aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Sommerfeld <kai.sommerfeld@gmx.com>2017-01-25 19:57:21 +0100
committerGitHub <noreply@github.com>2017-01-25 19:57:21 +0100
commitd73ae2bf3099c51113200a1b41704da433c28873 (patch)
tree8d8f897d27a7e8c855a5a7f3f7b5e756060ecf18
parent3079409a0e2dad242859b98e4774d3a4ccf25f2a (diff)
parent9504273e13a0a726c082cb7cd56d3313062933ac (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.cpp32
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.h14
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;
+ };
}