Пример #1
0
HouseKeeper::~HouseKeeper(void)
{
    gCoreContext->removeListener(this);

    if (m_timer)
    {
        m_timer->stop();
        disconnect(m_timer);
        delete m_timer;
        m_timer = NULL;
    }

    {
        // remove anything from the queue first, so it does not start
        QMutexLocker queueLock(&m_queueLock);
        while (!m_taskQueue.isEmpty())
            m_taskQueue.takeFirst()->DecrRef();
    }

    {
        // issue a terminate call to any long-running tasks
        // this is just a noop unless overwritten by a subclass
        QMutexLocker mapLock(&m_mapLock);
        QMap<QString,HouseKeeperTask*>::iterator it = m_taskMap.begin();
        for (; it != m_taskMap.end(); ++it)
            (*it)->Terminate();
    }

    if (!m_threadList.isEmpty())
    {
        QMutexLocker threadLock(&m_threadLock);
        // tell primary thread to self-terminate and wake it
        m_threadList.first()->Discard();
        m_threadList.first()->Wake();
        // wait for any remaining threads to self-terminate and close
        while (!m_threadList.isEmpty())
        {
            HouseKeepingThread *thread = m_threadList.takeFirst();
            thread->wait();
            delete thread;
        }
    }

    {
        // unload any registered tasks
        QMutexLocker mapLock(&m_mapLock);
        QMap<QString,HouseKeeperTask*>::iterator it = m_taskMap.begin();
        while (it != m_taskMap.end())
        {
            (*it)->DecrRef();
            it = m_taskMap.erase(it);
        }
    }
}
Пример #2
0
void HouseKeeper::customEvent(QEvent *e)
{
    if ((MythEvent::Type)(e->type()) == MythEvent::MythEventMessage)
    {
        MythEvent *me = (MythEvent*)e;
        if (me->Message().left(20) == "HOUSE_KEEPER_RUNNING")
        {
            QStringList tokens = me->Message()
                                 .split(" ", QString::SkipEmptyParts);
            if (tokens.size() != 4)
                return;

            QString hostname = tokens[1];
            QString tag = tokens[2];
            QDateTime last = MythDate::fromString(tokens[3]);

            QMutexLocker mapLock(&m_mapLock);
            if (m_taskMap.contains(tag))
            {
                if ((m_taskMap[tag]->GetScope() == kHKGlobal) ||
                        ((m_taskMap[tag]->GetScope() == kHKLocal) &&
                         (gCoreContext->GetHostName() == hostname)))
                    // task being run in the same scope as us.
                    // update the run time so we don't attempt to run
                    //      it ourselves
                    m_taskMap[tag]->SetLastRun(last);
            }
        }
    }
}
Пример #3
0
void HouseKeeper::Start(void)
{
    // no need to be fine grained, nothing else should be accessing this map
    QMutexLocker mapLock(&m_mapLock);

    if (m_timer->isActive())
        // Start() should only be called once
        return;

    MSqlQuery query(MSqlQuery::InitCon());
    query.prepare("SELECT tag,lastrun"
                  "  FROM housekeeping"
                  " WHERE hostname = :HOST"
                  "    OR hostname IS NULL");
    query.bindValue(":HOST", gCoreContext->GetHostName());

    if (!query.exec())
        MythDB::DBError("HouseKeeper::Run", query);
    else
    {
        while (query.next())
        {
            // loop through housekeeping table and load last run timestamps
            QString tag = query.value(0).toString();
            QDateTime lastrun = MythDate::as_utc(query.value(1).toDateTime());

            if (m_taskMap.contains(tag))
                m_taskMap[tag]->SetLastRun(lastrun);
        }
    }

    gCoreContext->addListener(this);

    QMap<QString,HouseKeeperTask*>::const_iterator it;
    for (it = m_taskMap.begin(); it != m_taskMap.end(); ++it)
    {
        if ((*it)->CheckImmediate())
        {
            // run any tasks marked for immediate operation in-thread
            (*it)->UpdateLastRun();
            (*it)->Run();
        }
        else if ((*it)->CheckStartup())
        {
            // queue any tasks marked for startup
            LOG(VB_GENERAL, LOG_INFO,
                QString("Queueing HouseKeeperTask '%1'.").arg(it.key()));
            QMutexLocker queueLock(&m_queueLock);
            (*it)->IncrRef();
            m_taskQueue.enqueue(*it);
        }
    }

    LOG(VB_GENERAL, LOG_INFO, "Starting HouseKeeper.");

    if (!m_taskQueue.isEmpty())
        StartThread();

    m_timer->start();
}
Пример #4
0
void Cold::clip(
        const Id& chunkId,
        const std::size_t chunkNum,
        const std::size_t id)
{
    if (chunkNum < m_chunkVec.size())
    {
        FastSlot& slot(m_chunkVec[chunkNum]);
        CountedChunk& countedChunk(*slot.chunk);

        m_pool->add([this, &countedChunk, id]()
        {
            unrefChunk(countedChunk, id, true);
        });
    }
    else
    {
        std::unique_lock<std::mutex> mapLock(m_mapMutex);
        CountedChunk& countedChunk(*m_chunkMap.at(chunkId));
        mapLock.unlock();

        m_pool->add([this, &countedChunk, id]()
        {
            unrefChunk(countedChunk, id, false);
        });
    }
}
Пример #5
0
void Cold::growSlow(const Climber& climber, Clipper& clipper)
{
    const Id& chunkId(climber.chunkId());

    if (clipper.insert(chunkId, climber.chunkNum()))
    {
        std::unique_lock<std::mutex> mapLock(m_mapMutex);

        const bool exists(m_chunkMap.count(chunkId));
        auto& countedChunk(m_chunkMap[chunkId]);

        if (!exists) countedChunk.reset(new CountedChunk());

        std::lock_guard<std::mutex> chunkLock(countedChunk->mutex);
        mapLock.unlock();

        if (!countedChunk->refs.count(clipper.id()))
        {
            countedChunk->refs[clipper.id()] = 1;
        }
        else
        {
            ++countedChunk->refs[clipper.id()];
        }

        ensureChunk(climber, countedChunk->chunk, exists);
    }
}
Пример #6
0
Cell& Cold::getCell(const Climber& climber, Clipper& clipper)
{
    CountedChunk* countedChunk(nullptr);

    const std::size_t chunkNum(climber.chunkNum());
    const Id& chunkId(climber.chunkId());

    if (chunkNum < m_chunkVec.size())
    {
        growFast(climber, clipper);
        countedChunk = m_chunkVec[chunkNum].chunk.get();
    }
    else
    {
        growSlow(climber, clipper);

        std::lock_guard<std::mutex> mapLock(m_mapMutex);
        countedChunk = m_chunkMap.at(chunkId).get();
    }

    if (!countedChunk)
    {
        throw std::runtime_error("CountedChunk has missing contents.");
    }

    return countedChunk->chunk->getCell(climber);
}
Пример #7
0
bool framework::registerComponent(COMPONENT_ID id, Sdf_cl_commonMessageQueue *pQueue)
{
	mapLock();
	bool result = false;
	std::map<int , Sdf_cl_commonMessageQueue*> :: iterator it = componentMap.find(id);
	if ( it == componentMap.end() )		
	{
		componentMap[id] = pQueue;
		result = true;
	}
	mapUnlock();
	return result;
}
Пример #8
0
void HouseKeeper::Run(void)
{
    LOG(VB_GENERAL, LOG_DEBUG, "Running HouseKeeper.");

    QDateTime now = MythDate::current();

    QMutexLocker mapLock(&m_mapLock);
    QMap<QString,HouseKeeperTask*>::const_iterator it;
    for (it = m_taskMap.begin(); it != m_taskMap.end(); ++it)
    {
        if ((*it)->CheckRun(now))
        {
            // check if any tasks are ready to run, and add to queue
            LOG(VB_GENERAL, LOG_INFO,
                QString("Queueing HouseKeeperTask '%1'.").arg(it.key()));
            QMutexLocker queueLock(&m_queueLock);
            (*it)->IncrRef();
            m_taskQueue.enqueue(*it);
        }
    }

    if (!m_taskQueue.isEmpty())
        StartThread();

    if (m_threadList.size() > 1)
    {
        // spent threads exist in the thread list
        // check to see if any have finished up their task and terminated
        QMutexLocker threadLock(&m_threadLock);
        int count1 = m_threadList.size();

        QList<HouseKeepingThread*>::iterator it = m_threadList.begin();
        ++it; // skip the primary thread
        while (it != m_threadList.end())
        {
            if ((*it)->isRunning())
                ++it;
            else
                it = m_threadList.erase(it);
        }

        int count2 = m_threadList.size();
        if (count1 > count2)
            LOG(VB_GENERAL, LOG_DEBUG,
                QString("Discarded HouseKeepingThreads have completed and "
                        "been deleted. Current count %1 -> %2.")
                .arg(count1).arg(count2));
    }
}
Пример #9
0
bool framework::post(COMPONENT_ID id, dtmf_msgFormat* pMsg)
{
	mapLock();
       // printf("post msgType:%d\n",pMsg->msgType);
        bool result = false;
        std::map<int , Sdf_cl_commonMessageQueue*> :: iterator it = componentMap.find(id);
        if ( it != componentMap.end() )
        {
                //printf("post msgType22222222222:%d\n",pMsg->msgType);
                it->second->post(pMsg);
                result = true;
        }
        mapUnlock();
        return result;

}
Пример #10
0
void HouseKeeper::RegisterTask(HouseKeeperTask *task)
{
    QMutexLocker mapLock(&m_mapLock);
    QString tag = task->GetTag();
    if (m_taskMap.contains(tag))
    {
        task->DecrRef();
        LOG(VB_GENERAL, LOG_ERR,
            QString("HouseKeeperTask '%1' already registered. "
                    "Rejecting duplicate.").arg(tag));
    }
    else
    {
        LOG(VB_GENERAL, LOG_INFO,
            QString("Registering HouseKeeperTask '%1'.").arg(tag));
        m_taskMap.insert(tag, task);
    }
}