diff options
-rw-r--r-- | xbmc/Application.cpp | 1 | ||||
-rw-r--r-- | xbmc/epg/Epg.cpp | 21 | ||||
-rw-r--r-- | xbmc/epg/EpgContainer.cpp | 44 | ||||
-rw-r--r-- | xbmc/epg/EpgInfoTag.cpp | 39 | ||||
-rw-r--r-- | xbmc/epg/EpgInfoTag.h | 6 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/PVROperations.cpp | 36 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/PlayerOperations.cpp | 8 | ||||
-rw-r--r-- | xbmc/pvr/PVRManager.cpp | 43 | ||||
-rw-r--r-- | xbmc/pvr/PVRManager.h | 28 | ||||
-rw-r--r-- | xbmc/pvr/addons/PVRClients.cpp | 3 | ||||
-rw-r--r-- | xbmc/pvr/channels/PVRChannelGroup.cpp | 19 | ||||
-rw-r--r-- | xbmc/pvr/channels/PVRChannelGroupInternal.cpp | 3 | ||||
-rw-r--r-- | xbmc/pvr/channels/PVRChannelGroups.cpp | 6 | ||||
-rw-r--r-- | xbmc/pvr/recordings/PVRRecordings.cpp | 2 | ||||
-rw-r--r-- | xbmc/pvr/timers/PVRTimerInfoTag.cpp | 4 | ||||
-rw-r--r-- | xbmc/pvr/timers/PVRTimers.cpp | 43 | ||||
-rw-r--r-- | xbmc/pvr/windows/GUIWindowPVRBase.cpp | 35 | ||||
-rw-r--r-- | xbmc/pvr/windows/GUIWindowPVRGuide.cpp | 5 | ||||
-rw-r--r-- | xbmc/utils/AlarmClock.cpp | 2 |
19 files changed, 216 insertions, 132 deletions
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index f2a8d41406..1570714ece 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -1337,6 +1337,7 @@ void CApplication::StopPVRManager() StopPlaying(); // stop pvr manager thread and clear all pvr data g_PVRManager.Stop(); + g_PVRManager.Clear(); // stop epg container thread and clear all epg data g_EpgContainer.Stop(); g_EpgContainer.Clear(); diff --git a/xbmc/epg/Epg.cpp b/xbmc/epg/Epg.cpp index 8e7ad7cd41..2cd2921c69 100644 --- a/xbmc/epg/Epg.cpp +++ b/xbmc/epg/Epg.cpp @@ -292,20 +292,25 @@ std::vector<CEpgInfoTagPtr> CEpg::GetTagsBetween(const CDateTime &beginTime, con void CEpg::AddEntry(const CEpgInfoTag &tag) { CEpgInfoTagPtr newTag; - CSingleLock lock(m_critSection); - std::map<CDateTime, CEpgInfoTagPtr>::iterator itr = m_tags.find(tag.StartAsUTC()); - if (itr != m_tags.end()) - newTag = itr->second; - else + CPVRChannelPtr channel; { - newTag.reset(new CEpgInfoTag(this, m_pvrChannel, m_strName, m_pvrChannel ? m_pvrChannel->IconPath() : "")); - m_tags.insert(make_pair(tag.StartAsUTC(), newTag)); + CSingleLock lock(m_critSection); + std::map<CDateTime, CEpgInfoTagPtr>::iterator itr = m_tags.find(tag.StartAsUTC()); + if (itr != m_tags.end()) + newTag = itr->second; + else + { + newTag.reset(new CEpgInfoTag(this, m_pvrChannel, m_strName, m_pvrChannel ? m_pvrChannel->IconPath() : "")); + m_tags.insert(make_pair(tag.StartAsUTC(), newTag)); + } + + channel = m_pvrChannel; } if (newTag) { newTag->Update(tag); - newTag->SetPVRChannel(m_pvrChannel); + newTag->SetPVRChannel(channel); newTag->SetEpg(this); newTag->SetTimer(g_PVRTimers->GetTimerForEpgTag(newTag)); newTag->SetRecording(g_PVRRecordings->GetRecordingForEpgTag(newTag)); diff --git a/xbmc/epg/EpgContainer.cpp b/xbmc/epg/EpgContainer.cpp index 5e6a047783..85820b1a9b 100644 --- a/xbmc/epg/EpgContainer.cpp +++ b/xbmc/epg/EpgContainer.cpp @@ -179,18 +179,24 @@ void CEpgContainer::Start(bool bAsync) LoadFromDB(); - CSingleLock lock(m_critSection); - if (!m_bStop) + bool bStop = false; { - CheckPlayingEvents(); + CSingleLock lock(m_critSection); + bStop = m_bStop; + if (!m_bStop) + { + CheckPlayingEvents(); - Create(); - SetPriority(-1); + Create(); + SetPriority(-1); - m_bStarted = true; + m_bStarted = true; + } + } + if (!bStop) + { g_PVRManager.TriggerEpgsCreate(); - CLog::Log(LOGNOTICE, "%s - EPG thread started", __FUNCTION__); } } @@ -772,25 +778,37 @@ int CEpgContainer::GetEPGSearch(CFileItemList &results, const EpgSearchFilter &f bool CEpgContainer::CheckPlayingEvents(void) { bool bReturn(false); - time_t iNow; bool bFoundChanges(false); { - CSingleLock lock(m_critSection); + time_t iNextEpgActiveTagCheck; + { + CSingleLock lock(m_critSection); + iNextEpgActiveTagCheck = m_iNextEpgActiveTagCheck; + } + + time_t iNow; CDateTime::GetCurrentDateTime().GetAsUTCDateTime().GetAsTime(iNow); - if (iNow >= m_iNextEpgActiveTagCheck) + if (iNow >= iNextEpgActiveTagCheck) { for (const auto &epgEntry : m_epgs) bFoundChanges = epgEntry.second->CheckPlayingEvent() || bFoundChanges; - CDateTime::GetCurrentDateTime().GetAsUTCDateTime().GetAsTime(m_iNextEpgActiveTagCheck); - m_iNextEpgActiveTagCheck += g_advancedSettings.m_iEpgActiveTagCheckInterval; + + CDateTime::GetCurrentDateTime().GetAsUTCDateTime().GetAsTime(iNextEpgActiveTagCheck); + iNextEpgActiveTagCheck += g_advancedSettings.m_iEpgActiveTagCheckInterval; /* pvr tags always start on the full minute */ if (g_PVRManager.IsStarted()) - m_iNextEpgActiveTagCheck -= m_iNextEpgActiveTagCheck % 60; + iNextEpgActiveTagCheck -= iNextEpgActiveTagCheck % 60; bReturn = true; } + + if (bReturn) + { + CSingleLock lock(m_critSection); + m_iNextEpgActiveTagCheck = iNextEpgActiveTagCheck; + } } if (bFoundChanges) diff --git a/xbmc/epg/EpgInfoTag.cpp b/xbmc/epg/EpgInfoTag.cpp index d69b469eca..44c97e9939 100644 --- a/xbmc/epg/EpgInfoTag.cpp +++ b/xbmc/epg/EpgInfoTag.cpp @@ -340,18 +340,22 @@ int CEpgInfoTag::GetDuration(void) const return end - start > 0 ? end - start : 3600; } -std::string CEpgInfoTag::Title(bool bOverrideParental /* = false */) const +bool CEpgInfoTag::IsParentalLocked() const { - std::string strTitle; - bool bParentalLocked(false); - + CPVRChannelPtr channel; { CSingleLock lock(m_critSection); - if (m_pvrChannel) - bParentalLocked = g_PVRManager.IsParentalLocked(m_pvrChannel); + channel = m_pvrChannel; } - if (!bOverrideParental && bParentalLocked) + return channel && g_PVRManager.IsParentalLocked(channel); +} + +std::string CEpgInfoTag::Title(bool bOverrideParental /* = false */) const +{ + std::string strTitle; + + if (!bOverrideParental && IsParentalLocked()) strTitle = g_localizeStrings.Get(19266); // parental locked else if (m_strTitle.empty() && !CSettings::GetInstance().GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE)) strTitle = g_localizeStrings.Get(19055); // no information available @@ -365,11 +369,8 @@ std::string CEpgInfoTag::PlotOutline(bool bOverrideParental /* = false */) const { std::string retVal; - { - CSingleLock lock(m_critSection); - if (bOverrideParental || !m_pvrChannel || !g_PVRManager.IsParentalLocked(m_pvrChannel)) - retVal = m_strPlotOutline; - } + if (bOverrideParental || !IsParentalLocked()) + retVal = m_strPlotOutline; return retVal; } @@ -378,11 +379,8 @@ std::string CEpgInfoTag::Plot(bool bOverrideParental /* = false */) const { std::string retVal; - { - CSingleLock lock(m_critSection); - if (bOverrideParental || !m_pvrChannel || !g_PVRManager.IsParentalLocked(m_pvrChannel)) - retVal = m_strPlot; - } + if (bOverrideParental || !IsParentalLocked()) + retVal = m_strPlot; return retVal; } @@ -391,11 +389,8 @@ std::string CEpgInfoTag::OriginalTitle(bool bOverrideParental /* = false */) con { std::string retVal; - { - CSingleLock lock(m_critSection); - if (bOverrideParental || !m_pvrChannel || !g_PVRManager.IsParentalLocked(m_pvrChannel)) - retVal = m_strOriginalTitle; - } + if (bOverrideParental || !IsParentalLocked()) + retVal = m_strOriginalTitle; return retVal; } diff --git a/xbmc/epg/EpgInfoTag.h b/xbmc/epg/EpgInfoTag.h index cabc86c7de..945d6e8d37 100644 --- a/xbmc/epg/EpgInfoTag.h +++ b/xbmc/epg/EpgInfoTag.h @@ -170,6 +170,12 @@ namespace EPG int GetDuration(void) const; /*! + * @brief Check whether this event is parental locked. + * @return True if whether this event is parental locked, false otherwise. + */ + bool IsParentalLocked() const; + + /*! * @brief Get the title of this event. * @param bOverrideParental True to override parental control, false check it. * @return The title. diff --git a/xbmc/interfaces/json-rpc/PVROperations.cpp b/xbmc/interfaces/json-rpc/PVROperations.cpp index 941f71d750..0ebca7547f 100644 --- a/xbmc/interfaces/json-rpc/PVROperations.cpp +++ b/xbmc/interfaces/json-rpc/PVROperations.cpp @@ -62,8 +62,8 @@ JSONRPC_STATUS CPVROperations::GetChannelGroups(const std::string &method, ITran if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups; - if (channelGroupContainer == NULL) + CPVRChannelGroupsContainerPtr channelGroupContainer = g_PVRChannelGroups; + if (!channelGroupContainer) return FailedToExecute; CPVRChannelGroups *channelGroups = channelGroupContainer->Get(parameterObject["channeltype"].asString().compare("radio") == 0); @@ -85,8 +85,8 @@ JSONRPC_STATUS CPVROperations::GetChannelGroupDetails(const std::string &method, if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups; - if (channelGroupContainer == NULL) + CPVRChannelGroupsContainerPtr channelGroupContainer = g_PVRChannelGroups; + if (!channelGroupContainer) return FailedToExecute; CPVRChannelGroupPtr channelGroup; @@ -109,8 +109,8 @@ JSONRPC_STATUS CPVROperations::GetChannels(const std::string &method, ITransport if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups; - if (channelGroupContainer == NULL) + CPVRChannelGroupsContainerPtr channelGroupContainer = g_PVRChannelGroups; + if (!channelGroupContainer) return FailedToExecute; CPVRChannelGroupPtr channelGroup; @@ -137,8 +137,8 @@ JSONRPC_STATUS CPVROperations::GetChannelDetails(const std::string &method, ITra if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups; - if (channelGroupContainer == NULL) + CPVRChannelGroupsContainerPtr channelGroupContainer = g_PVRChannelGroups; + if (!channelGroupContainer) return FailedToExecute; CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["channelid"].asInteger()); @@ -155,8 +155,8 @@ JSONRPC_STATUS CPVROperations::GetBroadcasts(const std::string &method, ITranspo if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRChannelGroupsContainer *channelGroupContainer = g_PVRManager.ChannelGroups(); - if (channelGroupContainer == NULL) + CPVRChannelGroupsContainerPtr channelGroupContainer = g_PVRManager.ChannelGroups(); + if (!channelGroupContainer) return FailedToExecute; CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["channelid"].asInteger()); @@ -214,8 +214,8 @@ JSONRPC_STATUS CPVROperations::Record(const std::string &method, ITransportLayer } else if (channel.isInteger()) { - CPVRChannelGroupsContainer *channelGroupContainer = g_PVRManager.ChannelGroups(); - if (channelGroupContainer == NULL) + CPVRChannelGroupsContainerPtr channelGroupContainer = g_PVRManager.ChannelGroups(); + if (!channelGroupContainer) return FailedToExecute; pChannel = channelGroupContainer->GetChannelById((int)channel.asInteger()); @@ -307,7 +307,7 @@ JSONRPC_STATUS CPVROperations::GetTimers(const std::string &method, ITransportLa if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRTimers* timers = g_PVRTimers; + CPVRTimersPtr timers = g_PVRTimers; if (!timers) return FailedToExecute; @@ -324,7 +324,7 @@ JSONRPC_STATUS CPVROperations::GetTimerDetails(const std::string &method, ITrans if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRTimers* timers = g_PVRTimers; + CPVRTimersPtr timers = g_PVRTimers; if (!timers) return FailedToExecute; @@ -387,7 +387,9 @@ JSONRPC_STATUS CPVROperations::DeleteTimer(const std::string &method, ITransport if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRTimers* timers = g_PVRTimers; + CPVRTimersPtr timers = g_PVRTimers; + if (!timers) + return FailedToExecute; CPVRTimerInfoTagPtr timer = timers->GetById(parameterObject["timerid"].asInteger()); if (!timer) @@ -444,7 +446,7 @@ JSONRPC_STATUS CPVROperations::GetRecordings(const std::string &method, ITranspo if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRRecordings* recordings = g_PVRRecordings; + CPVRRecordingsPtr recordings = g_PVRRecordings; if (!recordings) return FailedToExecute; @@ -461,7 +463,7 @@ JSONRPC_STATUS CPVROperations::GetRecordingDetails(const std::string &method, IT if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRRecordings* recordings = g_PVRRecordings; + CPVRRecordingsPtr recordings = g_PVRRecordings; if (!recordings) return FailedToExecute; diff --git a/xbmc/interfaces/json-rpc/PlayerOperations.cpp b/xbmc/interfaces/json-rpc/PlayerOperations.cpp index 4827bbb598..e192b54d0b 100644 --- a/xbmc/interfaces/json-rpc/PlayerOperations.cpp +++ b/xbmc/interfaces/json-rpc/PlayerOperations.cpp @@ -571,8 +571,8 @@ JSONRPC_STATUS CPlayerOperations::Open(const std::string &method, ITransportLaye if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups; - if (channelGroupContainer == NULL) + CPVRChannelGroupsContainerPtr channelGroupContainer = g_PVRChannelGroups; + if (!channelGroupContainer) return FailedToExecute; CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["item"]["channelid"].asInteger()); @@ -596,8 +596,8 @@ JSONRPC_STATUS CPlayerOperations::Open(const std::string &method, ITransportLaye if (!g_PVRManager.IsStarted()) return FailedToExecute; - CPVRRecordings *recordingsContainer = g_PVRRecordings; - if (recordingsContainer == NULL) + CPVRRecordingsPtr recordingsContainer = g_PVRRecordings; + if (!recordingsContainer) return FailedToExecute; CFileItemPtr fileItem = recordingsContainer->GetById((int)parameterObject["item"]["recordingid"].asInteger()); diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 4013b2c787..b0fffccba1 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -77,6 +77,7 @@ using KODI::MESSAGING::HELPERS::DialogResponse; CPVRManager::CPVRManager(void) : CThread("PVRManager"), + m_addons(new CPVRClients), m_triggerEvent(true), m_currentFile(NULL), m_database(NULL), @@ -88,15 +89,12 @@ CPVRManager::CPVRManager(void) : m_isChannelPreview(false) { CAnnouncementManager::GetInstance().AddAnnouncer(this); - m_addons.reset(new CPVRClients); } CPVRManager::~CPVRManager(void) { CSettings::GetInstance().UnregisterCallback(this); CAnnouncementManager::GetInstance().RemoveAnnouncer(this); - Stop(); - m_addons.reset(); CLog::Log(LOGDEBUG,"PVRManager - destroyed"); } @@ -138,6 +136,30 @@ CPVRManager &CPVRManager::GetInstance() return CServiceBroker::GetPVRManager(); } +CPVRChannelGroupsContainerPtr CPVRManager::ChannelGroups(void) const +{ + CSingleLock lock(m_critSection); + return m_channelGroups; +} + +CPVRRecordingsPtr CPVRManager::Recordings(void) const +{ + CSingleLock lock(m_critSection); + return m_recordings; +} + +CPVRTimersPtr CPVRManager::Timers(void) const +{ + CSingleLock lock(m_critSection); + return m_timers; +} + +CPVRClientsPtr CPVRManager::Clients(void) const +{ + // note: m_addons is const (only set/reset in ctor/dtor). no need for a lock here. + return m_addons; +} + void CPVRManager::OnSettingChanged(const CSetting *setting) { if (setting == NULL) @@ -221,7 +243,7 @@ void CPVRManager::OnSettingAction(const CSetting *setting) } } -void CPVRManager::Cleanup(void) +void CPVRManager::Clear(void) { CSingleLock lock(m_critSection); @@ -248,14 +270,12 @@ void CPVRManager::Cleanup(void) } HideProgressDialog(); - - SetState(ManagerStateStopped); } void CPVRManager::ResetProperties(void) { CSingleLock lock(m_critSection); - Cleanup(); + Clear(); m_channelGroups.reset(new CPVRChannelGroupsContainer); m_recordings.reset(new CPVRRecordings); @@ -341,8 +361,7 @@ void CPVRManager::Stop(void) if (m_database->IsOpen()) m_database->Close(); - /* unload all data */ - Cleanup(); + SetState(ManagerStateStopped); } CPVRManager::ManagerState CPVRManager::GetState(void) const @@ -724,7 +743,7 @@ void CPVRManager::ResetDatabase(bool bResetEPGOnly /* = false */) CLog::Log(LOGNOTICE,"PVRManager - %s - restarting the PVRManager", __FUNCTION__); m_database->Open(); - Cleanup(); + Start(); pDlgProgress->SetPercentage(100); @@ -1893,8 +1912,10 @@ bool CPVRManager::CreateChannelEpgs(void) if (EpgsCreated()) return true; + bool bEpgsCreated = m_channelGroups->CreateChannelEpgs(); + CSingleLock lock(m_critSection); - m_bEpgsCreated = m_channelGroups->CreateChannelEpgs(); + m_bEpgsCreated = bEpgsCreated; return m_bEpgsCreated; } diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h index 56561e094e..9a3863cb04 100644 --- a/xbmc/pvr/PVRManager.h +++ b/xbmc/pvr/PVRManager.h @@ -51,12 +51,16 @@ namespace PVR { class CPVRClient; class CPVRClients; + typedef std::shared_ptr<CPVRClients> CPVRClientsPtr; class CPVRChannel; typedef std::shared_ptr<CPVRChannel> CPVRChannelPtr; class CPVRChannelGroupsContainer; + typedef std::shared_ptr<CPVRChannelGroupsContainer> CPVRChannelGroupsContainerPtr; class CPVRChannelGroup; class CPVRRecordings; + typedef std::shared_ptr<CPVRRecordings> CPVRRecordingsPtr; class CPVRTimers; + typedef std::shared_ptr<CPVRTimers> CPVRTimersPtr; class CPVRTimerInfoTag; typedef std::shared_ptr<CPVRTimerInfoTag> CPVRTimerInfoTagPtr; class CPVRGUIInfo; @@ -130,25 +134,25 @@ private: * @brief Get the channel groups container. * @return The groups container. */ - CPVRChannelGroupsContainer *ChannelGroups(void) const { return m_channelGroups.get(); } + CPVRChannelGroupsContainerPtr ChannelGroups(void) const; /*! * @brief Get the recordings container. * @return The recordings container. */ - CPVRRecordings *Recordings(void) const { return m_recordings.get(); } + CPVRRecordingsPtr Recordings(void) const; /*! * @brief Get the timers container. * @return The timers container. */ - CPVRTimers *Timers(void) const { return m_timers.get(); } + CPVRTimersPtr Timers(void) const; /*! * @brief Get the timers container. * @return The timers container. */ - CPVRClients *Clients(void) const { return m_addons.get(); } + CPVRClientsPtr Clients(void) const; /*! * @brief Init PVRManager. @@ -161,14 +165,14 @@ private: void Reinit(void); /*! - * @brief Stop the PVRManager and destroy all objects it created. + * @brief Stop the PVRManager. */ void Stop(void); /*! - * @brief Delete PVRManager's objects. + * @brief Destroy PVRManager's objects. */ - void Cleanup(void); + void Clear(void); /*! * @brief Get the TV database. @@ -661,11 +665,11 @@ private: /** @name containers */ //@{ - std::unique_ptr<CPVRChannelGroupsContainer> m_channelGroups; /*!< pointer to the channel groups container */ - std::unique_ptr<CPVRRecordings> m_recordings; /*!< pointer to the recordings container */ - std::unique_ptr<CPVRTimers> m_timers; /*!< pointer to the timers container */ - std::unique_ptr<CPVRClients> m_addons; /*!< pointer to the pvr addon container */ - std::unique_ptr<CPVRGUIInfo> m_guiInfo; /*!< pointer to the guiinfo data */ + CPVRChannelGroupsContainerPtr m_channelGroups; /*!< pointer to the channel groups container */ + CPVRRecordingsPtr m_recordings; /*!< pointer to the recordings container */ + CPVRTimersPtr m_timers; /*!< pointer to the timers container */ + const CPVRClientsPtr m_addons; /*!< pointer to the pvr addon container */ + std::unique_ptr<CPVRGUIInfo> m_guiInfo; /*!< pointer to the guiinfo data */ //@} CCriticalSection m_critSectionTriggers; /*!< critical section for triggered updates */ diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp index 7e89c3f062..a524f1097c 100644 --- a/xbmc/pvr/addons/PVRClients.cpp +++ b/xbmc/pvr/addons/PVRClients.cpp @@ -198,6 +198,9 @@ bool CPVRClients::HasEnabledClients(void) const bool CPVRClients::StopClient(AddonPtr client, bool bRestart) { + /* stop playback */ + CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP); + CSingleLock lock(m_critSection); int iId = GetClientId(client); PVR_CLIENT mappedClient; diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp index c1201fba8f..1c96b53a8e 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.cpp +++ b/xbmc/pvr/channels/PVRChannelGroup.cpp @@ -555,10 +555,11 @@ PVR_CHANNEL_GROUP_SORTED_MEMBERS CPVRChannelGroup::GetMembers(void) const int CPVRChannelGroup::GetMembers(CFileItemList &results, bool bGroupMembers /* = true */) const { + const CPVRChannelGroup* channels = bGroupMembers ? this : g_PVRChannelGroups->GetGroupAll(m_bRadio).get(); int iOrigSize = results.Size(); - CSingleLock lock(m_critSection); - const CPVRChannelGroup* channels = bGroupMembers ? this : g_PVRChannelGroups->GetGroupAll(m_bRadio).get(); + CSingleLock lock(channels->m_critSection); + for (PVR_CHANNEL_GROUP_SORTED_MEMBERS::const_iterator it = channels->m_sortedMembers.begin(); it != channels->m_sortedMembers.end(); ++it) { if (bGroupMembers || !IsGroupMember((*it).channel)) @@ -606,16 +607,17 @@ bool CPVRChannelGroup::AddAndUpdateChannels(const CPVRChannelGroup &channels, bo { bool bReturn(false); bool bPreventSortAndRenumber(PreventSortAndRenumber()); - CSingleLock lock(m_critSection); + const CPVRChannelGroupPtr groupAll(g_PVRChannelGroups->GetGroupAll(m_bRadio)); SetPreventSortAndRenumber(); /* go through the channel list and check for new channels. channels will only by updated in CPVRChannelGroupInternal to prevent dupe updates */ + CSingleLock lock(channels.m_critSection); for (PVR_CHANNEL_GROUP_MEMBERS::const_iterator it = channels.m_members.begin(); it != channels.m_members.end(); ++it) { /* check whether this channel is known in the internal group */ - const PVRChannelGroupMember& existingChannel(g_PVRChannelGroups->GetGroupAll(m_bRadio)->GetByUniqueID(it->first)); + const PVRChannelGroupMember& existingChannel(groupAll->GetByUniqueID(it->first)); if (!existingChannel.channel) continue; @@ -640,11 +642,14 @@ bool CPVRChannelGroup::AddAndUpdateChannels(const CPVRChannelGroup &channels, bo bool CPVRChannelGroup::RemoveDeletedChannels(const CPVRChannelGroup &channels) { bool bReturn(false); + CPVRChannelGroups *groups = g_PVRChannelGroups->Get(m_bRadio); + CSingleLock lock(m_critSection); /* check for deleted channels */ for (PVR_CHANNEL_GROUP_SORTED_MEMBERS::iterator it = m_sortedMembers.begin(); it != m_sortedMembers.end();) { + CSingleLock lock(channels.m_critSection); if (channels.m_members.find((*it).channel->StorageId()) == channels.m_members.end()) { /* channel was not found */ @@ -659,7 +664,7 @@ bool CPVRChannelGroup::RemoveDeletedChannels(const CPVRChannelGroup &channels) /* remove this channel from all non-system groups if this is the internal group */ if (IsInternalGroup()) { - g_PVRChannelGroups->Get(m_bRadio)->RemoveFromAllGroups((*it).channel); + groups->RemoveFromAllGroups((*it).channel); /* since it was not found in the internal group, it was deleted from the backend */ group.channel->Delete(); @@ -761,6 +766,8 @@ bool CPVRChannelGroup::RemoveFromGroup(const CPVRChannelPtr &channel) bool CPVRChannelGroup::AddToGroup(const CPVRChannelPtr &channel, int iChannelNumber /* = 0 */) { + const CPVRChannelGroupPtr groupAll(g_PVRChannelGroups->GetGroupAll(m_bRadio)); + CSingleLock lock(m_critSection); bool bReturn(false); @@ -772,7 +779,7 @@ bool CPVRChannelGroup::AddToGroup(const CPVRChannelPtr &channel, int iChannelNum const PVRChannelGroupMember& realChannel(IsInternalGroup() ? GetByUniqueID(channel->StorageId()) : - g_PVRChannelGroups->GetGroupAll(m_bRadio)->GetByUniqueID(channel->StorageId())); + groupAll->GetByUniqueID(channel->StorageId())); if (realChannel.channel) { diff --git a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp index eb00a59bb7..a7baacfdf5 100644 --- a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp +++ b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp @@ -160,7 +160,6 @@ bool CPVRChannelGroupInternal::AddToGroup(const CPVRChannelPtr &channel, int iCh bool CPVRChannelGroupInternal::RemoveFromGroup(const CPVRChannelPtr &channel) { - CSingleLock lock(m_critSection); assert(channel.get()); if (!IsGroupMember(channel)) @@ -174,6 +173,8 @@ bool CPVRChannelGroupInternal::RemoveFromGroup(const CPVRChannelPtr &channel) return false; } + CSingleLock lock(m_critSection); + /* switch the hidden flag */ if (!channel->IsHidden()) { diff --git a/xbmc/pvr/channels/PVRChannelGroups.cpp b/xbmc/pvr/channels/PVRChannelGroups.cpp index 06e23a2c55..4cd9e1ccf6 100644 --- a/xbmc/pvr/channels/PVRChannelGroups.cpp +++ b/xbmc/pvr/channels/PVRChannelGroups.cpp @@ -518,6 +518,7 @@ bool CPVRChannelGroups::DeleteGroup(const CPVRChannelGroup &group) } bool bFound(false); + CPVRChannelGroupPtr playingGroup; // delete the group in this container { @@ -529,7 +530,7 @@ bool CPVRChannelGroups::DeleteGroup(const CPVRChannelGroup &group) // update the selected group in the gui if it's deleted CPVRChannelGroupPtr selectedGroup = GetSelectedGroup(); if (selectedGroup && *selectedGroup == group) - g_PVRManager.SetPlayingGroup(GetGroupAll()); + playingGroup = GetGroupAll(); it = m_groups.erase(it); bFound = true; @@ -541,6 +542,9 @@ bool CPVRChannelGroups::DeleteGroup(const CPVRChannelGroup &group) } } + if (playingGroup) + g_PVRManager.SetPlayingGroup(playingGroup); + if (group.GroupID() > 0) { // delete the group from the database diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp index 7e840da89c..9cab2e8990 100644 --- a/xbmc/pvr/recordings/PVRRecordings.cpp +++ b/xbmc/pvr/recordings/PVRRecordings.cpp @@ -164,9 +164,9 @@ void CPVRRecordings::Update(void) lock.Enter(); m_bIsUpdating = false; - g_PVRManager.SetChanged(); lock.Leave(); + g_PVRManager.SetChanged(); g_PVRManager.NotifyObservers(ObservableMessageRecordings); g_PVRManager.PublishEvent(RecordingsInvalidated); } diff --git a/xbmc/pvr/timers/PVRTimerInfoTag.cpp b/xbmc/pvr/timers/PVRTimerInfoTag.cpp index 70715900e7..096c0ea1fa 100644 --- a/xbmc/pvr/timers/PVRTimerInfoTag.cpp +++ b/xbmc/pvr/timers/PVRTimerInfoTag.cpp @@ -1015,8 +1015,10 @@ CPVRChannelPtr CPVRTimerInfoTag::ChannelTag(void) const CPVRChannelPtr CPVRTimerInfoTag::UpdateChannel(void) { + const CPVRChannelPtr channel(g_PVRChannelGroups->Get(m_bIsRadio)->GetGroupAll()->GetByUniqueID(m_iClientChannelUid, m_iClientId)); + CSingleLock lock(m_critSection); - m_channel = g_PVRChannelGroups->Get(m_bIsRadio)->GetGroupAll()->GetByUniqueID(m_iClientChannelUid, m_iClientId); + m_channel = channel; return m_channel; } diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp index e486128cdf..dba374b316 100644 --- a/xbmc/pvr/timers/PVRTimers.cpp +++ b/xbmc/pvr/timers/PVRTimers.cpp @@ -166,7 +166,7 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers, const std::vector<int> bChanged = true; existingTimer->ResetChildState(); - if (bStateChanged && g_PVRManager.IsStarted()) + if (bStateChanged) { std::string strMessage; existingTimer->GetNotificationText(strMessage); @@ -202,12 +202,9 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers, const std::vector<int> bChanged = true; bAddedOrDeleted = true; - if (g_PVRManager.IsStarted()) - { - std::string strMessage; - newTimer->GetNotificationText(strMessage); - timerNotifications.push_back(std::make_pair(newTimer->m_iClientId, strMessage)); - } + std::string strMessage; + newTimer->GetNotificationText(strMessage); + timerNotifications.push_back(std::make_pair(newTimer->m_iClientId, strMessage)); CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); @@ -246,8 +243,7 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers, const std::vector<int> CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); - if (g_PVRManager.IsStarted()) - timerNotifications.push_back(std::make_pair(timer->m_iClientId, timer->GetDeletedNotificationText())); + timerNotifications.push_back(std::make_pair(timer->m_iClientId, timer->GetDeletedNotificationText())); ClearEpgTagTimer(timer); @@ -323,24 +319,27 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers, const std::vector<int> if (bChanged) { UpdateChannels(); - g_PVRManager.SetChanged(); lock.Leave(); + g_PVRManager.SetChanged(); g_PVRManager.NotifyObservers(bAddedOrDeleted ? ObservableMessageTimersReset : ObservableMessageTimers); - /* queue notifications / fill eventlog */ - for (const auto &entry : timerNotifications) + if (g_PVRManager.IsStarted()) { - if (CSettings::GetInstance().GetBool(CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS)) - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(19166), entry.second); + /* queue notifications / fill eventlog */ + for (const auto &entry : timerNotifications) + { + if (CSettings::GetInstance().GetBool(CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS)) + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(19166), entry.second); - std::string strName; - g_PVRClients->GetClientAddonName(entry.first, strName); + std::string strName; + g_PVRClients->GetClientAddonName(entry.first, strName); - std::string strIcon; - g_PVRClients->GetClientAddonIcon(entry.first, strIcon); + std::string strIcon; + g_PVRClients->GetClientAddonIcon(entry.first, strIcon); - CEventLog::GetInstance().Add(EventPtr(new CNotificationEvent(strName, entry.second, strIcon, EventLevel::Information))); + CEventLog::GetInstance().Add(EventPtr(new CNotificationEvent(strName, entry.second, strIcon, EventLevel::Information))); + } } } @@ -642,6 +641,7 @@ bool CPVRTimers::GetDirectory(const std::string& strPath, CFileItemList &items) bool CPVRTimers::DeleteTimersOnChannel(const CPVRChannelPtr &channel, bool bDeleteTimerRules /* = true */, bool bCurrentlyActiveOnly /* = false */) { bool bReturn = false; + bool bChanged = false; { CSingleLock lock(m_critSection); @@ -657,12 +657,15 @@ bool CPVRTimers::DeleteTimersOnChannel(const CPVRChannelPtr &channel, bool bDele { CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); bReturn = (*timerIt)->DeleteFromClient(true) || bReturn; - g_PVRManager.SetChanged(); + bChanged = true; } } } } + if (bChanged) + g_PVRManager.SetChanged(); + g_PVRManager.NotifyObservers(ObservableMessageTimersReset); return bReturn; diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp index 71e9d6230c..a0943c1188 100644 --- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp @@ -104,17 +104,20 @@ void CGUIWindowPVRBase::UpdateSelectedItemPath() void CGUIWindowPVRBase::RegisterObservers(void) { - CSingleLock lock(m_critSection); g_PVRManager.RegisterObserver(this); + + CSingleLock lock(m_critSection); if (m_channelGroup) m_channelGroup->RegisterObserver(this); }; void CGUIWindowPVRBase::UnregisterObservers(void) { - CSingleLock lock(m_critSection); - if (m_channelGroup) - m_channelGroup->UnregisterObserver(this); + { + CSingleLock lock(m_critSection); + if (m_channelGroup) + m_channelGroup->UnregisterObserver(this); + } g_PVRManager.UnregisterObserver(this); }; @@ -428,18 +431,26 @@ CPVRChannelGroupPtr CGUIWindowPVRBase::GetChannelGroup(void) void CGUIWindowPVRBase::SetChannelGroup(const CPVRChannelGroupPtr &group) { - CSingleLock lock(m_critSection); if (!group) return; - if (m_channelGroup != group) + CPVRChannelGroupPtr channelGroup; { - if (m_channelGroup) - m_channelGroup->UnregisterObserver(this); - m_channelGroup = group; - // we need to register the window to receive changes from the new group - m_channelGroup->RegisterObserver(this); - g_PVRManager.SetPlayingGroup(m_channelGroup); + CSingleLock lock(m_critSection); + if (m_channelGroup != group) + { + if (m_channelGroup) + m_channelGroup->UnregisterObserver(this); + m_channelGroup = group; + // we need to register the window to receive changes from the new group + m_channelGroup->RegisterObserver(this); + channelGroup = m_channelGroup; + } + } + + if (channelGroup) + { + g_PVRManager.SetPlayingGroup(channelGroup); Update(GetDirectoryPath()); } } diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp index 44bb4120b4..93e875c94f 100644 --- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp @@ -42,7 +42,6 @@ using namespace EPG; CGUIWindowPVRGuide::CGUIWindowPVRGuide(bool bRadio) : CGUIWindowPVRBase(bRadio, bRadio ? WINDOW_RADIO_GUIDE : WINDOW_TV_GUIDE, "MyPVRGuide.xml"), - m_refreshTimelineItemsThread(new CPVRRefreshTimelineItemsThread(this)), m_cachedChannelGroup(new CPVRChannelGroup) { m_bRefreshTimelineItems = false; @@ -106,12 +105,14 @@ void CGUIWindowPVRGuide::OnDeinitWindow(int nextWindowID) void CGUIWindowPVRGuide::StartRefreshTimelineItemsThread() { StopRefreshTimelineItemsThread(); + m_refreshTimelineItemsThread.reset(new CPVRRefreshTimelineItemsThread(this)); m_refreshTimelineItemsThread->Create(); } void CGUIWindowPVRGuide::StopRefreshTimelineItemsThread() { - m_refreshTimelineItemsThread->StopThread(false); + if (m_refreshTimelineItemsThread) + m_refreshTimelineItemsThread->StopThread(false); } void CGUIWindowPVRGuide::Notify(const Observable &obs, const ObservableMessage msg) diff --git a/xbmc/utils/AlarmClock.cpp b/xbmc/utils/AlarmClock.cpp index 065673604a..2e941724ad 100644 --- a/xbmc/utils/AlarmClock.cpp +++ b/xbmc/utils/AlarmClock.cpp @@ -125,7 +125,7 @@ void CAlarmClock::Stop(const std::string& strName, bool bSilent /* false */) } else { - CApplicationMessenger::GetInstance().SendMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, iter->second.m_strCommand); + CApplicationMessenger::GetInstance().PostMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, iter->second.m_strCommand); if (iter->second.m_loop) { iter->second.watch.Reset(); |