Permalink
Browse files

ensure that paused jobs don't get stuck on the top of the jobqueue, t…

…hus 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
  • Loading branch information...
1 parent 8f38d64 commit d53406a32bc5cddeb7d8af44ef77714ea80ab1da Jonathan Marshall committed Nov 29, 2012
Showing with 38 additions and 8 deletions.
  1. +30 −8 xbmc/utils/JobManager.cpp
  2. +8 −0 xbmc/utils/JobManager.h
View
@@ -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;
View
@@ -304,6 +304,14 @@ class CJobManager
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;

0 comments on commit d53406a

Please sign in to comment.