Skip to content

Commit

Permalink
Merge pull request #11536 from ksooo/pvr-fix-channeliconsearch-deadlock
Browse files Browse the repository at this point in the history
[PVR] Trac 17246: Fix deadlock that might occur during initial channel icon search.
  • Loading branch information
ksooo committed Jan 25, 2017
2 parents 3079409 + 9504273 commit d73ae2b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
32 changes: 23 additions & 9 deletions xbmc/pvr/channels/PVRChannelGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -267,27 +268,38 @@ 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();
Expand All @@ -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());
}

Expand All @@ -333,14 +345,16 @@ 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
}

if (dlgProgressHandle)
dlgProgressHandle->MarkFinished();

return true;
}

/********** sort methods **********/
Expand Down
14 changes: 14 additions & 0 deletions xbmc/pvr/channels/PVRChannelGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
}

0 comments on commit d73ae2b

Please sign in to comment.