void addJob (JobType type, std::string const& name, boost::function <void (Job&)> const& jobFunc) { assert (type != jtINVALID); JobDataMap::iterator iter (m_jobData.find (type)); assert (iter != m_jobData.end ()); if (iter == m_jobData.end ()) return; JobTypeData& data (iter->second); // FIXME: Workaround incorrect client shutdown ordering // do not add jobs to a queue with no threads assert (type == jtCLIENT || m_workers.getNumberOfThreads () > 0); { // If this goes off it means that a child didn't follow // the Stoppable API rules. A job may only be added if: // // - The JobQueue has NOT stopped // AND // * We are currently processing jobs // OR // * We have have pending jobs // OR // * Not all children are stopped // ScopedLock lock (m_mutex); assert (! isStopped() && ( m_processCount>0 || ! m_jobSet.empty () || ! areChildrenStopped())); } // Don't even add it to the queue if we're stopping // and the job type is marked for skipOnStop. // if (isStopping() && skipOnStop (type)) { m_journal.debug << "Skipping addJob ('" << name << "')"; return; } { ScopedLock lock (m_mutex); std::pair <std::set <Job>::iterator, bool> result ( m_jobSet.insert (Job (type, name, ++m_lastJob, data.load (), jobFunc, m_cancelCallback))); queueJob (*result.first, lock); } }
void Process::runJob(void) { Job * nextJob = 0; _queueJobCount = DebugQueueJobCount; while(true) { while (_queueJobCount > -1 || _localJobs.size() < DebugQueueJobCount) { // _queueJobCount will be > -1 while the JobManager hasn't returned false for job-needed. _DebugProcessUsage[_debugId]++; nextJob = _job->run(this); if(!nextJob){ break; } queueJob(nextJob); // Send it back to the JobManager, or add it to the local queue. } if(_localJobs.empty()){ break; } Job * job = _localJobs.top(); _localJobs.pop(); assert(!job->parent()); do { // Perform a DFS until all paths have been exhausted. _DebugProcessUsage[_debugId]++; nextJob = job->run(this); if(!nextJob) { // Job has no more children, return to the parent. nextJob = job->parent(); delete job; } job = nextJob; } while(job); } _completedJob = _job; _job = 0; // Return this process to the JobManager. _jobManager->sendProcessMessage(this); }