使用方法:
1.在进程中先调用
ah_pmpt_timer_init,创建一个定时器线程
2.在另一个使用定时器的线程调用ah_pmpt_timer_create创建定时器
3.调用ah_pmpt_timer_start,将定时器挂接到定时器链表中,设置定时时间以开启定时器
4.调用ah_pmpt_timer_continue重新赋值时间,重新开启定时器 (因为该定时器超时后,定时器默认就删除了,如果要循环使用,必须重新调用ah_pmpt_timer_continue
-
#define AP_PTIMER_STOPPED 0x01 /* timer already stopped */
-
#define AP_PTIMER_CALLING 0x02 /* timer is calling */
-
struct ah_ptimer_ {
-
struct ah_ptimer_ *ap_prev; /* double link list */
-
struct ah_ptimer_ *ap_next;
-
uint8 ap_flag;
-
int16 ap_count;
-
uint32 ap_fire; /* when to fire the timer, sec since this instance is started */
-
ah_ptimer_callback_t ap_func;
-
void *ap_data;
-
};
-
typedef struct ah_ptimer_ ah_ptimer_t;
-
typedef void (*ah_ptimer_callback_t)(ah_ptimer_t*, void *);
-
-
#define is_ah_ptimer_stopped(t) ( (t)->ap_flag & AP_PTIMER_STOPPED)
-
#define is_ah_ptimer_calling(t) ( (t)->ap_flag & AP_PTIMER_CALLING)
-
#define set_ah_ptimer_stopped(t) do{ (t)->ap_flag |= AP_PTIMER_STOPPED; } while(0)
-
#define unset_ah_ptimer_stopped(t) do{ (t)->ap_flag &= ~AP_PTIMER_STOPPED; } while(0)
-
#define set_ah_ptimer_calling(t) do{ (t)->ap_flag |= AP_PTIMER_CALLING; } while(0)
-
#define unset_ah_ptimer_calling(t) do{ (t)->ap_flag &= ~AP_PTIMER_CALLING; } while(0)
-
-
-
#define PTIME_TIC_SEC 1 /* tic every 1 second */
-
#define PTIMER_TIC_SYS 128 /* every how many <tic> to make sys call to get current time */
-
-
static boolean timer_thread_running = FALSE;
-
/* timer-queue-lock */
-
static pthread_mutex_t pmpt_timer_lock = PTHREAD_MUTEX_INITIALIZER;
-
static ah_ptimer_t *pmpt_timer_head; /* all timers in double link-list */
-
static ah_ptimer_t *pmpt_timer_tail;
-
-
struct itimerval {
-
struct timeval it_interval; /* next value */
-
struct timeval it_value; /* current value */
-
};
-
-
struct timeval {
-
long tv_sec; /* seconds */
-
long tv_usec; /* microseconds */
-
};
-
-
/*
-
* sys alarm sig handler
-
*每128s去重新通过_ah_sys_up_sec()获取当前系统时间,128s内直接通过加法实现时间的增加
-
*/
-
static void ptimer_tic (int sig)
-
{
-
static uint32 tic_count=PTIMER_TIC_SYS;
-
int time_now;
-
-
/* not do sys call each sec */
-
if ( ! (--tic_count) ) {
-
/* try the sys call get time */
-
time_now = _ah_sys_up_sec();
-
-
/* sys call fail */
-
if (time_now < 0) {
-
ap_sys_up_sec += PTIME_TIC_SEC;
-
tic_count = 1;
-
}else {/* sys call ok */
-
ap_sys_up_sec = time_now;
-
tic_count = PTIMER_TIC_SYS;
-
}
-
}
-
else {
-
ap_sys_up_sec += PTIME_TIC_SEC;
-
}
-
-
/* linux follow System V semantics, reset signal handler to dflt.
-
* so no same alarm would prempt this handler. we set the tic handler again
-
* after poll all the timer, so we are non-prempt at process level
-
*/
-
#if 0
-
if( signal(SIGALRM, ptimer_tic) == SIG_ERR ) {
-
ah_err("proc %d fail install SIGALRM handler\n",getpid());
-
ah_assert(FALSE);
-
}
-
#endif
-
return;
-
}
-
-
/* init preempt timer */
-
static int ah_pmpt_timer_setup(void)
-
{
-
struct itimerval alarm_tic;
-
-
if (timer_thread_running) { /*如果定时器线程已经启动,直接返回*/
-
return 0;
-
}
-
-
pmpt_timer_head = pmpt_timer_tail = NULL;/*初始化定时器链表*/
-
ap_sys_up_sec = _ah_sys_up_sec(); /*获取系统启动时间*/
-
-
if (ap_sys_up_sec < 0) { /*系统启动时间小于0,出错,返回*/
-
return -1;
-
}
-
-
/* sys timer will send SIGALRM */
-
if( signal(SIGALRM, ptimer_tic) == SIG_ERR ) { /*定义信号SIGALRM的信号处理函数*/
-
return -1;
-
}
-
-
/* setup sys tic */
-
memset((void*)&alarm_tic, 0, sizeof(alarm_tic));
-
alarm_tic.it_interval.tv_sec = PTIME_TIC_SEC;/*1s*/
-
alarm_tic.it_value.tv_sec = PTIME_TIC_SEC;
-
/*ITIMER_REAL decrements in real time, and delivers SIGALRM upon expiration.*/
-
setitimer(ITIMER_REAL, &alarm_tic, NULL); /*设置1s定时器,1s后发送SIGALRM信号*/
-
-
return 0;
-
}
-
-
void ah_signal_mask(int block, int signum)
-
{
-
sigset_t mask; /*定义信号集mask*/
-
-
sigemptyset(&mask); /*初始化清空信号集mask*/
-
sigaddset(&mask, signum);/*将信号signum加入到信号集mask*/
-
-
if (block)
-
pthread_sigmask(SIG_BLOCK, &mask, NULL);/*将信号集mask加入到信号屏蔽字中*/
-
else
-
pthread_sigmask(SIG_UNBLOCK, &mask, NULL);/*将信号集mask从信号屏蔽字中清除*/
-
}
-
/* must call it when pmpt_timer_lock is locked */
-
static void ah_pmpt_timer_dec_ref(ah_ptimer_t *t)
-
{
-
--t->ap_count;
-
if (t->ap_count < 0) {
-
ah_log(LOG_CRIT, "preempt timer: double free.");
-
}
-
if (0 == t->ap_count) {
-
ah_assert(is_ah_ptimer_stopped(t));
-
free(t);
-
}
-
-
return;
-
}
-
/*
-
* poll the timer queue, call any expired timer's callback.
-
*/
-
void ah_pmpt_timer_poll(void)
-
{
-
ah_ptimer_t *t=NULL;
-
-
for ( ; ; ) {
-
if (pthread_mutex_lock(&pmpt_timer_lock) != 0) {
-
ah_assert(FALSE);
-
return;
-
}
-
-
if ( (NULL == pmpt_timer_head) /*定时器连边为空,直接返回*/
-
|| (pmpt_timer_head->ap_fire > ap_sys_up_sec) ) { /*头结点的定时时间没有到,直接返回*/
-
pthread_mutex_unlock(&pmpt_timer_lock);
-
break;
-
}
-
/*。。。。。。。。。。。。头结点的定时时间到了。。。。。。。。。*/
-
t = pmpt_timer_head; /*获取定时器链表头结点*/
-
pmpt_timer_head = t->ap_next;/*更新pmpt_timer_head为下一个节点*/
-
-
if( NULL == pmpt_timer_head ) {
-
pmpt_timer_tail = NULL;
-
} else {
-
pmpt_timer_head->ap_prev = NULL;
-
}
-
/*将节点t从链表中摘除*/
-
/* clean up t's forw/back ptr */
-
t->ap_prev = NULL;
-
t->ap_next = NULL;
-
-
/* prevent it be deleted when calling timer's callback */
-
++t->ap_count;/*防止定时器被删除,删除的判断是ap_count==0*/
-
-
set_ah_ptimer_calling(t);/*设置标记,表明定时器正在被调用*/
-
pthread_mutex_unlock(&pmpt_timer_lock);
-
-
/* NOTE: it's the callback's responsibility to free/reset/etc.
-
to handle the timer ptr correctly */
-
ah_assert(NULL != t->ap_func);
-
t->ap_func(t, t->ap_data);/*调用定时器的回调函数*/
-
if (pthread_mutex_lock(&pmpt_timer_lock) != 0) {
-
ah_assert(FALSE);
-
return;
-
}
-
unset_ah_ptimer_calling(t);/*将被调用的标记删除*/
-
ah_pmpt_timer_dec_ref(t);/*将技术值ap_count减1,如果减法后变为0,则删除定时器*/
-
pthread_mutex_unlock(&pmpt_timer_lock);
-
}
-
-
return;
-
}
-
-
static void *ah_pmpt_timer_thread(void *arg)
-
{
-
ah_signal_mask(FALSE, SIGALRM);
-
if (ah_pmpt_timer_setup() < 0) {
-
return NULL;
-
}
-
-
timer_thread_running = TRUE;
-
for ( ; ; ) {
-
/* select(0, NULL, NULL, NULL, NULL); */
-
ah_sleep(1);
-
ah_pmpt_timer_poll();
-
}
-
return NULL;
-
}
-
-
-
/* should call it in main function firstly */
-
int ah_pmpt_timer_init(pthread_t *timer_id)
-
{
-
int count = 0;
-
-
ah_signal_mask(TRUE, SIGALRM);
-
/* Create event sub-thread *//*起一个线程进程定时器计算*/
-
if (ah_pthread_create(timer_id, ah_pmpt_timer_thread,
-
NULL, SCHED_RR,
-
AH_PRIORITY_CTRL, 0) != 0) {
-
ah_err("ah_pthread_create failed");
-
return -1;
-
}
-
/* Check if sub-thread is actually succeeded */
-
while ( (!timer_thread_running) && ((count++) < 10)) {
-
ah_sleep(1);
-
}
-
-
if (!timer_thread_running) {
-
ah_err("Can not run timer thread");
-
if (NULL != timer_id) {
-
*timer_id = -1;
-
}
-
return -1;
-
}
-
-
return 0;
-
}
-
-
-
ah_ptimer_t* ah_pmpt_timer_create(ah_ptimer_callback_t callback, void *arg)
-
{
-
ah_ptimer_t *t;
-
-
if (NULL == callback) { /*定时器没有回调函数,直接退出*/
-
return NULL;
-
}
-
-
t = (ah_ptimer_t*)ah_calloc(1,sizeof(ah_ptimer_t)); /*分配定时器*/
-
if (NULL == t) {
-
return NULL;
-
}
-
-
t->ap_func = callback;
-
t->ap_data = arg;
-
t->ap_count = 1;
-
-
return t;
-
}
-
-
-
/* must call it when pmpt_timer_lock is locked */
-
static void ah_pmpt_timer_stop_internal(ah_ptimer_t *t)
-
{
-
set_ah_ptimer_stopped(t); /*设置定时器t的标记位为STOPPED*/
-
if ((NULL == t->ap_prev) && (NULL == t->ap_next) && (t != pmpt_timer_head)){
-
return;
-
}
-
if( t->ap_prev ) {
-
t->ap_prev->ap_next = t->ap_next;
-
} else {
-
pmpt_timer_head = t->ap_next;
-
}
-
-
if(NULL != t
阅读(991) | 评论(0) | 转发(0) |