This repository has been archived on 2024-01-25. You can view files and clone it, but cannot push or open issues or pull requests.
XF/src/simplified/xf/port/common/timeoutmanager.cpp

155 lines
4.5 KiB
C++
Raw Normal View History

2023-09-19 15:59:49 +02:00
2023-10-05 11:50:03 +02:00
#include "common/dispatcher.h"
2023-09-19 15:59:49 +02:00
#include <config/xf-config.h>
#if (USE_XF_COMMON_TIMEOUTMANAGER_CLASS != 0)
#include <cassert>
#include "xf/interface/behavior.h"
#include "xf/interface/mutex.h"
#include "timeoutmanager.h"
2023-10-17 14:18:38 +02:00
#if defined(XF_TRACE_EVENT_PUSH_POP) && (XF_TRACE_EVENT_PUSH_POP != 0)
#include "trace/trace.h"
#endif // XF_TRACE_EVENT_PUSH_POP
2023-09-19 15:59:49 +02:00
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.
2023-09-26 14:26:07 +02:00
interface::XFTimeoutManager * interface::XFTimeoutManager::getInstance() {
2023-09-19 15:59:49 +02:00
static ::XFTimeoutManager timeoutManager;
return &timeoutManager;
}
2023-09-26 14:26:07 +02:00
XFTimeoutManager::XFTimeoutManager() {
2023-10-17 14:18:38 +02:00
this->pMutex_ = interface::XFMutex::create();
}
2023-10-05 11:50:03 +02:00
XFTimeoutManager::~XFTimeoutManager() {
}
void XFTimeoutManager::addTimeout(XFTimeout *pNewTimeout) {
2023-10-17 17:10:20 +02:00
2023-10-19 11:46:19 +02:00
const int desireInterval = pNewTimeout->getInterval();
int intervalOfTimeout = 0;
int ticks;
2023-10-17 14:18:38 +02:00
this->pMutex_->lock();
2023-10-19 11:46:19 +02:00
if(this->timeouts_.empty()) {
ticks = (desireInterval-intervalOfTimeout);
if(ticks<=0) ticks = 0;
pNewTimeout->setRelTicks(ticks);
this->timeouts_.push_back(pNewTimeout);
this->pMutex_->unlock();
return;
}
TimeoutList::iterator it = this->timeouts_.begin();
while(intervalOfTimeout < desireInterval) {
if(++it == this->timeouts_.end()){
ticks = (desireInterval-intervalOfTimeout);
if(ticks<=0) ticks = 0;
pNewTimeout->setRelTicks(ticks);
this->timeouts_.push_back(pNewTimeout);
this->pMutex_->unlock();
return;
} else {
intervalOfTimeout += (*it)->getRelTicks();
}
}
if(intervalOfTimeout == desireInterval) {
if(++it == this->timeouts_.end()) {
ticks = (desireInterval-intervalOfTimeout);
if(ticks<=0) ticks = 0;
pNewTimeout->setRelTicks(ticks);
this->timeouts_.push_back(pNewTimeout);
this->pMutex_->unlock();
return;
} else {
while((*it)->getRelTicks() == 0) {
if(++it == this->timeouts_.end()) {
ticks = (desireInterval-intervalOfTimeout);
if(ticks<=0) ticks = 0;
pNewTimeout->setRelTicks(ticks);
this->timeouts_.push_back(pNewTimeout);
this->pMutex_->unlock();
return;
}
it++;
}
}
}
// TODO change for take care of 10ms ecart of timeout
ticks = (desireInterval-intervalOfTimeout);
ticks = ticks > 0 ? ticks/this->tickInterval_ : 0;
(*it)->substractFromRelTicks(ticks);
pNewTimeout->setRelTicks(ticks);
this->timeouts_.insert(--it, pNewTimeout);
2023-10-17 14:18:38 +02:00
this->pMutex_->unlock();
2023-10-19 11:46:19 +02:00
return;
2023-10-05 11:50:03 +02:00
}
2023-09-26 14:26:07 +02:00
void XFTimeoutManager::returnTimeout(XFTimeout *pTimeout) {
2023-10-17 14:18:38 +02:00
this->pMutex_->lock();
2023-10-05 11:50:03 +02:00
XFDispatcher::getInstance()->pushEvent(pTimeout);
2023-10-17 14:18:38 +02:00
this->timeouts_.remove(pTimeout);
this->pMutex_->unlock();
2023-09-26 14:26:07 +02:00
}
void XFTimeoutManager::start(std::function<void (uint32_t)> startTimeoutManagerTimer) {
2023-10-17 14:18:38 +02:00
startTimeoutManagerTimer(this->tickInterval_);
2023-09-26 14:26:07 +02:00
}
void XFTimeoutManager::scheduleTimeout(int32_t timeoutId, int32_t interval, interface::XFBehavior *pBehavior) {
::XFTimeout* timeout = new XFTimeout(timeoutId, interval, pBehavior);
addTimeout(timeout);
2023-09-26 14:26:07 +02:00
}
void XFTimeoutManager::unscheduleTimeout(int32_t timeoutId, interface::XFBehavior *pBehavior) {
2023-10-17 14:18:38 +02:00
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);
}
2023-10-17 14:18:38 +02:00
}
2023-10-17 14:18:38 +02:00
this->pMutex_->unlock();
}
void XFTimeoutManager::tick() {
2023-10-19 11:46:19 +02:00
2023-10-17 14:18:38 +02:00
if(!this->timeouts_.empty()) {
this->pMutex_->lock();
2023-10-19 11:46:19 +02:00
XFTimeout* timeout = this->timeouts_.front();
timeout->substractFromRelTicks(tickInterval_);
while (timeout->getRelTicks() <= 0 ) {
XFDispatcher::getInstance()->pushEvent(timeout);
this->timeouts_.pop_front();
timeout = this->timeouts_.front();
2023-10-17 14:18:38 +02:00
}
2023-10-19 11:46:19 +02:00
2023-10-17 14:18:38 +02:00
this->pMutex_->unlock();
2023-10-19 11:46:19 +02:00
}
2023-09-26 14:26:07 +02:00
}
2023-09-19 15:59:49 +02:00
#endif // USE_XF_COMMON_TIMEOUTMANAGER_CLASS