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); } }
// Check for the stopped condition // Caller must hold the mutex void check_stopped () { // To be stopped, child Stoppable objects must be stopped // and the count of dependent objects must be zero if (areChildrenStopped () && m_child_count == 0) { m_cond.notify_all (); m_journal.info << "Stopped."; stopped (); } }
// Signals the service stopped if the stopped condition is met. // void checkStopped (ScopedLock const& lock) { // We are stopped when all of the following are true: // // 1. A stop notification was received // 2. All Stoppable children have stopped // 3. There are no executing calls to processTask // 4. There are no remaining Jobs in the job set // if (isStopping() && areChildrenStopped() && (m_processCount == 0) && m_jobSet.empty()) { stopped(); } }
// Caller must hold the mutex void OverlayImpl::checkStopped () { if (isStopping() && areChildrenStopped () && list_.empty()) stopped(); }