#include "common/dispatcher.h" #include #if (USE_XF_COMMON_TIMEOUTMANAGER_CLASS != 0) #include #include "xf/interface/behavior.h" #include "xf/interface/mutex.h" #include "timeoutmanager.h" #if defined(XF_TRACE_EVENT_PUSH_POP) && (XF_TRACE_EVENT_PUSH_POP != 0) #include "trace/trace.h" #endif // XF_TRACE_EVENT_PUSH_POP using Mutex = interface::XFMutex; // Rename XFMutex interface class to Mutex for easier use. // Implementation of the getInstance() method of the 'interface::XFTimeoutManager' class. // // Note: The implementation is done here because only in this file the real XFTimeoutManager // class is known (port specific class). An instance of the XFTimeoutManager class is // returned by the 'interface::XFTimeoutManager' class. interface::XFTimeoutManager * interface::XFTimeoutManager::getInstance() { static ::XFTimeoutManager timeoutManager; return &timeoutManager; } XFTimeoutManager::XFTimeoutManager() { this->pMutex_ = interface::XFMutex::create(); } XFTimeoutManager::~XFTimeoutManager() { } void XFTimeoutManager::addTimeout(XFTimeout *pNewTimeout) { const int dTime = pNewTimeout->getInterval(); int rTime = 0; int relInterval = 0; bool isEnd = true; int interval = dTime; this->pMutex_->lock(); TimeoutList::iterator it = this->timeouts_.begin(); isEnd = (it == this->timeouts_.end()); if(!isEnd){ relInterval = (*it)->getInterval(); rTime += relInterval; } while(!isEnd && ( relInterval <= 0 || (rTime > dTime) )) { isEnd = (++it == this->timeouts_.end()); interval = rTime - dTime; if(!isEnd) { relInterval = (*it)->getRelTicks(); rTime += relInterval; } } if(it == this->timeouts_.begin()) if(!isEnd) (*it)->substractFromRelTicks(interval); it--; pNewTimeout->setRelTicks(interval); this->timeouts_.insert(it, pNewTimeout); this->pMutex_->unlock(); return; } void XFTimeoutManager::returnTimeout(XFTimeout *pTimeout) { this->pMutex_->lock(); XFDispatcher::getInstance()->pushEvent(pTimeout); this->timeouts_.remove(pTimeout); this->pMutex_->unlock(); } void XFTimeoutManager::start(std::function startTimeoutManagerTimer) { startTimeoutManagerTimer(this->tickInterval_); } void XFTimeoutManager::scheduleTimeout(int32_t timeoutId, int32_t interval, interface::XFBehavior *pBehavior) { ::XFTimeout* timeout = new XFTimeout(timeoutId, interval, pBehavior); addTimeout(timeout); } void XFTimeoutManager::unscheduleTimeout(int32_t timeoutId, interface::XFBehavior *pBehavior) { this->pMutex_->lock(); TimeoutList::iterator it; for(it = this->timeouts_.begin(); it != this->timeouts_.end(); it++){ if((*it)->getId()==timeoutId && (*it)->getBehavior() == pBehavior) { it = this->timeouts_.erase(it); } } this->pMutex_->unlock(); } void XFTimeoutManager::tick() { bool isEmpty = this->timeouts_.empty(); int rTime; if(!isEmpty) { this->pMutex_->lock(); XFTimeout* timeout = this->timeouts_.front(); timeout->substractFromRelTicks(tickInterval_); rTime = timeout->getRelTicks(); while (!isEmpty && (rTime <= 0) ) { rTime = timeout->getRelTicks(); XFDispatcher::getInstance()->pushEvent(timeout); this->timeouts_.pop_front(); timeout = this->timeouts_.front(); isEmpty = this->timeouts_.empty(); } this->pMutex_->unlock(); } } #endif // USE_XF_COMMON_TIMEOUTMANAGER_CLASS