aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Marshall <jmarshall@never.you.mind>2012-11-29 16:32:52 +1300
committerJonathan Marshall <jmarshall@never.you.mind>2012-11-29 20:38:49 +1300
commitd53406a32bc5cddeb7d8af44ef77714ea80ab1da (patch)
treefe7ae0e49b1393f036f48cf0ae80a532793090bd
parent8f38d64e3a2e0070812bef7689ca3879009a6e9d (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.cpp38
-rw-r--r--xbmc/utils/JobManager.h8
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;