diff options
author | Jonathan Marshall <jmarshall@never.you.mind> | 2012-11-29 16:32:52 +1300 |
---|---|---|
committer | Jonathan Marshall <jmarshall@never.you.mind> | 2012-11-29 20:38:49 +1300 |
commit | d53406a32bc5cddeb7d8af44ef77714ea80ab1da (patch) | |
tree | fe7ae0e49b1393f036f48cf0ae80a532793090bd | |
parent | 8f38d64e3a2e0070812bef7689ca3879009a6e9d (diff) |
ensure that paused jobs don't get stuck on the top of the jobqueue, thus allowing no other jobs of the same priority to be processed. Fixes issue where CSaveFileStateJob didn't get run after playback if a stream details/thumb extraction job got in the way
-rw-r--r-- | xbmc/utils/JobManager.cpp | 38 | ||||
-rw-r--r-- | xbmc/utils/JobManager.h | 8 |
2 files changed, 38 insertions, 8 deletions
diff --git a/xbmc/utils/JobManager.cpp b/xbmc/utils/JobManager.cpp index da3e17b635..bebf80bea9 100644 --- a/xbmc/utils/JobManager.cpp +++ b/xbmc/utils/JobManager.cpp @@ -258,17 +258,14 @@ CJob *CJobManager::PopJob() { if (m_jobQueue[priority].size() && m_processing.size() < GetMaxWorkers(CJob::PRIORITY(priority))) { - CWorkItem job = m_jobQueue[priority].front(); - // skip adding any paused types - if (priority <= CJob::PRIORITY_LOW) - { - std::vector<std::string>::iterator i = find(m_pausedTypes.begin(), m_pausedTypes.end(), job.m_job->GetType()); - if (i != m_pausedTypes.end()) - return NULL; - } + if (!SkipPausedJobs((CJob::PRIORITY)priority)) + return NULL; + // pop the job off the queue + CWorkItem job = m_jobQueue[priority].front(); m_jobQueue[priority].pop_front(); + // add to the processing vector m_processing.push_back(job); job.m_job->m_callback = this; @@ -302,6 +299,31 @@ bool CJobManager::IsPaused(const std::string &pausedType) return (i != m_pausedTypes.end()); } +bool CJobManager::SkipPausedJobs(CJob::PRIORITY priority) +{ + if (priority > CJob::PRIORITY_LOW) + return true; + + // find the first unpaused job + JobQueue::iterator first_job = m_jobQueue[priority].begin(); + for (; first_job != m_jobQueue[priority].end(); ++first_job) + { + std::vector<std::string>::iterator i = find(m_pausedTypes.begin(), m_pausedTypes.end(), first_job->m_job->GetType()); + if (i == m_pausedTypes.end()) + break; // found a job that can be performed + } + if (first_job == m_jobQueue[priority].end()) + return false; // no jobs ready to go + + // shunt all the paused ones to the back of the queue + for (JobQueue::iterator i = m_jobQueue[priority].begin(); i != first_job; i++) + { + m_jobQueue[priority].push_back(*i); + m_jobQueue[priority].pop_front(); + } + return true; +} + int CJobManager::IsProcessing(const std::string &pausedType) { int jobsMatched = 0; diff --git a/xbmc/utils/JobManager.h b/xbmc/utils/JobManager.h index ad0fb6b2d8..dff1ab94bb 100644 --- a/xbmc/utils/JobManager.h +++ b/xbmc/utils/JobManager.h @@ -304,6 +304,14 @@ private: void RemoveWorker(const CJobWorker *worker); unsigned int GetMaxWorkers(CJob::PRIORITY priority) const; + /*! \brief skips over any paused jobs of given priority. + Moves any paused jobs at the front of the queue to the back of the + queue, allowing unpaused jobs to continue processing. + \param priority the priority queue to consider. + \return true if an unpaused job is available, false if no unpaused jobs are available. + */ + bool SkipPausedJobs(CJob::PRIORITY priority); + unsigned int m_jobCounter; typedef std::deque<CWorkItem> JobQueue; |