Skip to content

Commit

Permalink
pvr: fix deadlock in TriggerEPGUpdate
Browse files Browse the repository at this point in the history
  • Loading branch information
FernetMenta committed Sep 24, 2014
1 parent 82ea9fd commit 66060b4
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 13 deletions.
15 changes: 2 additions & 13 deletions xbmc/addons/AddonCallbacksPVR.cpp
Expand Up @@ -24,7 +24,7 @@
#include "utils/log.h"
#include "dialogs/GUIDialogKaiToast.h"

#include "epg/Epg.h"
#include "epg/EpgContainer.h"
#include "pvr/PVRManager.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
#include "pvr/channels/PVRChannelGroupInternal.h"
Expand Down Expand Up @@ -307,18 +307,7 @@ void CAddonCallbacksPVR::PVRTriggerEpgUpdate(void *addonData, unsigned int iChan
return;
}

// get the channel
CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(iChannelUid, client->GetID());
CEpg* epg(NULL);
// get the EPG for the channel
if (!channel || (epg = channel->GetEPG()) == NULL)
{
CLog::Log(LOGERROR, "PVR - %s - invalid channel or channel doesn't have an EPG", __FUNCTION__);
return;
}

// force an update
epg->ForceUpdate();
g_EpgContainer.UpdateRequest(client->GetID(), iChannelUid);
}

void CAddonCallbacksPVR::PVRFreeDemuxPacket(void *addonData, DemuxPacket* pPacket)
Expand Down
34 changes: 34 additions & 0 deletions xbmc/epg/EpgContainer.cpp
Expand Up @@ -278,6 +278,31 @@ void CEpgContainer::Process(void)
RemoveOldEntries();

/* check for pending manual EPG updates */
while (!m_bStop)
{
SUpdateRequest request;
{
CSingleLock lock(m_updateRequestsLock);
if (m_updateRequests.empty())
break;
request = m_updateRequests.front();
m_updateRequests.pop_front();
}

// get the channel
CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(request.channelID, request.clientID);
CEpg* epg(NULL);

// get the EPG for the channel
if (!channel || (epg = channel->GetEPG()) == NULL)
{
CLog::Log(LOGERROR, "PVR - %s - invalid channel or channel doesn't have an EPG", __FUNCTION__);
continue;
}

// force an update
epg->ForceUpdate();
}
if (!m_bStop)
{
{
Expand Down Expand Up @@ -718,3 +743,12 @@ void CEpgContainer::SetHasPendingUpdates(bool bHasPendingUpdates /* = true */)
else
m_pendingUpdates = 0;
}

void CEpgContainer::UpdateRequest(int clientID, unsigned int channelID)
{
CSingleLock lock(m_updateRequestsLock);
SUpdateRequest request;
request.clientID = clientID;
request.channelID = channelID;
m_updateRequests.push_back(request);
}
14 changes: 14 additions & 0 deletions xbmc/epg/EpgContainer.h
Expand Up @@ -38,6 +38,12 @@ namespace EPG
{
#define g_EpgContainer CEpgContainer::Get()

struct SUpdateRequest
{
int clientID;
unsigned int channelID;
};

class CEpgContainer : public Observer,
public Observable,
public ISettingCallback,
Expand Down Expand Up @@ -227,6 +233,11 @@ namespace EPG

bool PersistTables(void);

/*!
* @brief client can trigger an update request for a channel
*/
void UpdateRequest(int clientID, unsigned int channelID);

protected:
/*!
* @brief Load the EPG settings.
Expand Down Expand Up @@ -295,5 +306,8 @@ namespace EPG
CGUIDialogProgressBarHandle * m_progressHandle; /*!< the progress dialog that is visible when updating the first time */
CCriticalSection m_critSection; /*!< a critical section for changes to this container */
CEvent m_updateEvent; /*!< trigger when an update finishes */

std::list<SUpdateRequest> m_updateRequests; /*!< list of update requests triggered by addon*/
CCriticalSection m_updateRequestsLock; /*!< protect update requests*/
};
}

0 comments on commit 66060b4

Please sign in to comment.