#include #include // for std::nullptr ossimJobThreadQueue::ossimJobThreadQueue(std::shared_ptr jqueue) :m_doneFlag(false) { setJobQueue(jqueue); } void ossimJobThreadQueue::setJobQueue(std::shared_ptr jqueue) { std::lock_guard lock(m_threadMutex); if (m_jobQueue == jqueue) return; pause(); while(isRunning()&&!isPaused()) { m_jobQueue->releaseBlock(); } m_jobQueue = jqueue; resume(); if(m_jobQueue) startThreadForQueue(); } std::shared_ptr ossimJobThreadQueue::getJobQueue() { std::lock_guard lock(m_threadMutex); return m_jobQueue; } const std::shared_ptr ossimJobThreadQueue::getJobQueue() const { std::lock_guard lock(m_threadMutex); return m_jobQueue; } std::shared_ptr ossimJobThreadQueue::currentJob() { std::lock_guard lock(m_threadMutex); return m_currentJob; } void ossimJobThreadQueue::cancelCurrentJob() { std::lock_guard lock(m_threadMutex); if(m_currentJob) { m_currentJob->cancel(); } } bool ossimJobThreadQueue::isValidQueue()const { std::lock_guard lock(m_threadMutex); return (m_jobQueue!=nullptr); } void ossimJobThreadQueue::run() { bool firstTime = true; bool validQueue = true; std::shared_ptr job; do { interrupt(); // osg::notify(osg::NOTICE)<<"In thread loop "< lock(m_threadMutex); m_currentJob = job; } // if the job is ready to execute if(job->isReady()) { job->start(); } { std::lock_guard lock(m_threadMutex); m_currentJob = 0; } job.reset(); } if (firstTime) { ossim::Thread::yieldCurrentThread(); firstTime = false; } } while (!m_doneFlag&&validQueue); { std::lock_guard lock(m_threadMutex); m_currentJob = 0; } if(job&&m_doneFlag&&job->isReady()) { job->cancel(); } job = 0; } void ossimJobThreadQueue::setDone(bool done) { m_threadMutex.lock(); if (m_doneFlag==done) { m_threadMutex.unlock(); return; } m_doneFlag = done; m_threadMutex.unlock(); if(done) { { std::lock_guard lock(m_threadMutex); if (m_currentJob) m_currentJob->release(); } if (m_jobQueue) m_jobQueue->releaseBlock(); } } bool ossimJobThreadQueue::isDone() const { std::lock_guard lock(m_threadMutex); return m_doneFlag; } bool ossimJobThreadQueue::isProcessingJob()const { std::lock_guard lock(m_threadMutex); return (m_currentJob!=nullptr); } void ossimJobThreadQueue::cancel() { if( isRunning() ) { { std::lock_guard lock(m_threadMutex); m_doneFlag = true; if (m_currentJob) { m_currentJob->cancel(); } if (m_jobQueue) { m_jobQueue->releaseBlock(); } } // then wait for the the thread to stop running. while(isRunning()) { #if 1 { std::lock_guard lock(m_threadMutex); if (m_jobQueue) { m_jobQueue->releaseBlock(); } } #endif ossim::Thread::yieldCurrentThread(); } } } bool ossimJobThreadQueue::isEmpty()const { std::lock_guard lock(m_threadMutex); return m_jobQueue->isEmpty(); } ossimJobThreadQueue::~ossimJobThreadQueue() { cancel(); } void ossimJobThreadQueue::startThreadForQueue() { if(m_jobQueue) { if(!isRunning()) { start(); } } } bool ossimJobThreadQueue::hasJobsToProcess()const { bool result = false; { std::lock_guard lock(m_threadMutex); result = (!m_jobQueue->isEmpty()||m_currentJob); } return result; } std::shared_ptr ossimJobThreadQueue::nextJob() { std::shared_ptr job; m_threadMutex.lock(); std::shared_ptr jobQueue = m_jobQueue; bool checkIfValid = !m_doneFlag&&jobQueue; m_threadMutex.unlock(); if(checkIfValid) { job = jobQueue->nextJob(true); } return job; }