void Scheduler::schedulerThread(void* p) { Scheduler* scheduler = (Scheduler*)p; #if defined __EXCEPTION_TRACER__ ExceptionHandler schedulerExceptionHandler; schedulerExceptionHandler.InstallHandler(); #endif srand((uint32_t)OTSYS_TIME()); boost::unique_lock<boost::mutex> eventLockUnique(scheduler->m_eventLock, boost::defer_lock); while(Scheduler::m_threadState != Scheduler::STATE_TERMINATED) { SchedulerTask* task = NULL; bool run = false, ret = false; // check if there are events waiting... eventLockUnique.lock(); if(scheduler->m_eventList.empty()) // unlock mutex and wait for signal scheduler->m_eventSignal.wait(eventLockUnique); else // unlock mutex and wait for signal or timeout ret = scheduler->m_eventSignal.timed_wait(eventLockUnique, scheduler->m_eventList.top()->getCycle()); // the mutex is locked again now... if(!ret && Scheduler::m_threadState != Scheduler::STATE_TERMINATED) { // ok we had a timeout, so there has to be an event we have to execute... task = scheduler->m_eventList.top(); scheduler->m_eventList.pop(); // check if the event was stopped EventIds::iterator it = scheduler->m_eventIds.find(task->getEventId()); if(it != scheduler->m_eventIds.end()) { // was not stopped so we should run it run = true; scheduler->m_eventIds.erase(it); } } eventLockUnique.unlock(); // add task to dispatcher if(task) { // if it was not stopped if(run) { task->unsetExpiration(); Dispatcher::getInstance().addTask(task); } else delete task; // was stopped, have to be deleted here } } #if defined __EXCEPTION_TRACER__ schedulerExceptionHandler.RemoveHandler(); #endif }
void Scheduler::schedulerThread(void* p) { Scheduler* scheduler = (Scheduler*)p; // NOTE: second argument defer_lock is to prevent from immediate locking boost::unique_lock<boost::mutex> eventLockUnique(scheduler->m_eventLock, boost::defer_lock); while (scheduler->m_threadState != STATE_TERMINATED) { SchedulerTask* task = NULL; bool runTask = false; bool ret = true; // check if there are events waiting... eventLockUnique.lock(); if (scheduler->m_eventList.empty()) { scheduler->m_eventSignal.wait(eventLockUnique); } else { ret = scheduler->m_eventSignal.timed_wait(eventLockUnique, scheduler->m_eventList.top()->getCycle()); } // the mutex is locked again now... if (!ret && (scheduler->m_threadState != STATE_TERMINATED)) { // ok we had a timeout, so there has to be an event we have to execute... task = scheduler->m_eventList.top(); scheduler->m_eventList.pop(); // check if the event was stopped EventIdSet::iterator it = scheduler->m_eventIds.find(task->getEventId()); if (it != scheduler->m_eventIds.end()) { // was not stopped so we should run it runTask = true; scheduler->m_eventIds.erase(it); } } eventLockUnique.unlock(); // add task to dispatcher if (task) { // if it was not stopped if (runTask) { // Expiration has another meaning for dispatcher tasks, reset it task->setDontExpire(); g_dispatcher.addTask(task); } else { // was stopped, have to be deleted here delete task; } } } }
void Scheduler::schedulerThread() { std::unique_lock<std::mutex> eventLockUnique(m_eventLock, std::defer_lock); while (m_threadState != STATE_TERMINATED) { SchedulerTask* task = nullptr; std::cv_status ret = std::cv_status::no_timeout; bool runTask = false; eventLockUnique.lock(); if (m_eventList.empty()) { m_eventSignal.wait(eventLockUnique); } else { ret = m_eventSignal.wait_until(eventLockUnique, m_eventList.top()->getCycle()); } // the mutex is locked again now... if (ret == std::cv_status::timeout && m_threadState != STATE_TERMINATED) { // ok we had a timeout, so there has to be an event we have to execute... task = m_eventList.top(); m_eventList.pop(); // check if the event was stopped auto it = m_eventIds.find(task->getEventId()); if (it != m_eventIds.end()) { // was not stopped so we should run it runTask = true; m_eventIds.erase(it); } } eventLockUnique.unlock(); // add task to dispatcher if (task) { // if it was not stopped if (runTask) { // Expiration has another meaning for dispatcher tasks, reset it task->setDontExpire(); g_dispatcher.addTask(task); } else { // was stopped, have to be deleted here delete task; } } } }
void Scheduler::schedulerThread() { srand(time(NULL)); Dispatcher *dispatcher = Dispatcher::instance(); boost::unique_lock<boost::mutex> eventLockUnique(m_eventLock, boost::defer_lock); while(m_threadState != STATE_TERMINATED) { SchedulerTask* task = NULL; bool runTask = false; bool ret = true; eventLockUnique.lock(); if(m_eventList.empty()) { m_eventSignal.wait(eventLockUnique); } else { ret = m_eventSignal.timed_wait(eventLockUnique, m_eventList.top()->getCycle()); } if(ret == false && (m_threadState != STATE_TERMINATED)) { task = m_eventList.top(); m_eventList.pop(); EventIdSet::iterator it = m_eventIds.find(task->getEventId()); if(it != m_eventIds.end()) { runTask = true; m_eventIds.erase(it); } } eventLockUnique.unlock(); if(task) { if(runTask) { task->setDontExpire(); dispatcher->addTask(task); } else { delete task; } } } }
void Scheduler::threadMain() { std::unique_lock<std::mutex> eventLockUnique(eventLock, std::defer_lock); while (getState() != THREAD_STATE_TERMINATED) { std::cv_status ret = std::cv_status::no_timeout; eventLockUnique.lock(); if (eventList.empty()) { eventSignal.wait(eventLockUnique); } else { ret = eventSignal.wait_until(eventLockUnique, eventList.top()->getCycle()); } // the mutex is locked again now... if (ret == std::cv_status::timeout) { // ok we had a timeout, so there has to be an event we have to execute... SchedulerTask* task = eventList.top(); eventList.pop(); // check if the event was stopped auto it = eventIds.find(task->getEventId()); if (it == eventIds.end()) { eventLockUnique.unlock(); delete task; continue; } eventIds.erase(it); eventLockUnique.unlock(); task->setDontExpire(); g_dispatcher.addTask(task, true); } else { eventLockUnique.unlock(); } } }
SchedulerTask* makeTask(int64_t ticks, boost::function1<void, Game*> f) { SchedulerTask* ret = new TSchedulerTask(f); //ret->setEventId(0); ret->setTicks(ticks); return ret; }