📄 timer_manager.cpp
字号:
#include "timer_manager.h"
#include <stdio.h>
#include <sys/select.h>
#include <errno.h>
pthread_mutex_t CTimerManager::m_mutex= PTHREAD_MUTEX_INITIALIZER;
CTimerManager * CTimerManager::m_instance=NULL;
unsigned int CTimerManager::mark=0;
CTimerManager::CTimerManager():m_state(TIMER_MANAGER_STOP)
{
TAILQ_INIT(&list_);
}
CTimerManager * CTimerManager::instance()
{
if(m_instance==NULL)
{
pthread_mutex_lock(&m_mutex);
if(m_instance==NULL)
{
m_instance=new CTimerManager();
}
pthread_mutex_unlock(&m_mutex);
}
return m_instance;
}
void CTimerManager::add_timer_(CTimer * vtimer)
{
if(vtimer->m_state==CTimer::TIMER_ALIVE)
return;
CTimer *item;
struct timeval now,interval;
vtimer->m_state=CTimer::TIMER_ALIVE;
interval.tv_sec=vtimer->m_interval/1000;
interval.tv_usec=(vtimer->m_interval%1000)*1000;
gettimeofday(&now,0);
timeradd(&now,&interval,&vtimer->m_endtime);
TAILQ_FOREACH(item, &list_, entry_)
{
if(timercmp(&item->m_endtime,&vtimer->m_endtime,>=))
{
TAILQ_INSERT_BEFORE(item, vtimer, entry_);
break;
}
}
if(item==TAILQ_END(&list_))
{
TAILQ_INSERT_TAIL(&list_, vtimer,entry_);
}
}
void CTimerManager::remove_timer_(CTimer * vtimer)
{
if(vtimer->m_state!=CTimer::TIMER_ALIVE)
return;
TAILQ_REMOVE(&list_,vtimer,entry_);
vtimer->m_state=CTimer::TIMER_IDLE;
}
void CTimerManager::add_timer(CTimer * vtimer)
{
pthread_mutex_lock(&m_mutex);
add_timer_(vtimer);
vtimer->id_=++mark;
pthread_mutex_unlock(&m_mutex);
}
void CTimerManager::remove_timer(CTimer * vtimer)
{
pthread_mutex_lock(&m_mutex);
remove_timer_(vtimer);
vtimer->m_state=CTimer::TIMER_IDLE;
pthread_mutex_unlock(&m_mutex);
}
void CTimerManager:: start(unsigned long interval,unsigned long repair)
{
m_interval.tv_sec=interval/1000;
m_interval.tv_usec=(interval%1000)*1000;
m_repair.tv_sec=repair/1000;
m_repair.tv_usec=(repair%1000)*1000;
if(m_state==TIMER_MANAGER_STOP)
{
m_state=TIMER_MANAGER_START;
pthread_t pid;
pthread_create(&pid,0,process,this);
}
}
void CTimerManager:: stop()
{
m_state=TIMER_MANAGER_STOP;
}
void CTimerManager::dump()
{
CTimer *item;
struct timeval now;
pthread_mutex_lock(&m_mutex);
gettimeofday(&now,0);
struct timeval subTimer;
unsigned int nTimeToEnd;
printf("----id--interval--endtime--type--state----\n");
TAILQ_FOREACH(item, &list_, entry_)
{
timersub(&item->m_endtime,&now,&subTimer);
nTimeToEnd=subTimer.tv_sec*1000+subTimer.tv_usec/1000;
printf(" %d %d %d %d %d\n",
item->id_,item->m_interval,nTimeToEnd,item->m_type,item->m_state);
}
pthread_mutex_unlock(&m_mutex);
}
void * CTimerManager:: process(void * arg)
{
pthread_detach(pthread_self());
CTimerManager *manager=(CTimerManager *)arg;
CTimer *item;
struct timeval now,stand;
unsigned int delay;
struct timeval tm;
CTimer tmpTimer;
while(manager->m_state==TIMER_MANAGER_START)
{
tm.tv_sec=manager->m_interval.tv_sec;
tm.tv_usec=manager->m_interval.tv_usec;
while(select(0,0,0,0,&tm)<0&&errno==EINTR);
gettimeofday(&now,0);
timeradd(&now,&manager->m_repair,&stand);
pthread_mutex_lock(&manager->m_mutex);
TAILQ_FOREACH(item, &(manager->list_), entry_)
{
if(timercmp(&item->m_endtime,&stand,<))
{
if(item->m_func)
{
item->m_func(item,item->m_data);
}
if(item->m_type==CTimer::TIMER_ONCE)
{
manager->remove_timer_(item);
item->m_state=CTimer::TIMER_TIMEOUT;
}
else if(item->m_type==CTimer::TIMER_CIRCLE)
{
tmpTimer.entry_=item->entry_;
manager->remove_timer_(item);
manager->add_timer_(item);
item=&tmpTimer;
}
}
else
{
break;
}
}
pthread_mutex_unlock(&manager->m_mutex);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -