diff --git a/xbmc/addons/AddonCallbacksPVR.cpp b/xbmc/addons/AddonCallbacksPVR.cpp index 3e297f4eca15e..8056f8cdd686c 100644 --- a/xbmc/addons/AddonCallbacksPVR.cpp +++ b/xbmc/addons/AddonCallbacksPVR.cpp @@ -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" @@ -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) diff --git a/xbmc/epg/EpgContainer.cpp b/xbmc/epg/EpgContainer.cpp index e672ee59997bc..425adbab65271 100644 --- a/xbmc/epg/EpgContainer.cpp +++ b/xbmc/epg/EpgContainer.cpp @@ -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) { { @@ -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); +} diff --git a/xbmc/epg/EpgContainer.h b/xbmc/epg/EpgContainer.h index 5f00319921579..4d0dd87957fbf 100644 --- a/xbmc/epg/EpgContainer.h +++ b/xbmc/epg/EpgContainer.h @@ -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, @@ -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. @@ -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 m_updateRequests; /*!< list of update requests triggered by addon*/ + CCriticalSection m_updateRequestsLock; /*!< protect update requests*/ }; }