linux下一个计时器的实现(使用了list_head)

 c文件=====================================================

关于list_head请看另一篇文章http://blog.csdn.net/lvhongya/article/details/6609565

/* 
 * This file provides an interface of timers with signal and list
 */
#include "pub_time.h"

#define MAX_TIMER_NUM		1000	/**< max timer number	*/
#define TIMER_START 		10	/**< timer start(m second)*/
#define TIMER_TICK 		    10	/**< timer tick(m second)	*/
#define INVALID_TIMER_ID 	(-1)	/**< invalid timer ID	*/




static pub_timer_list_t timer_list;

static void signal_func(int signo);

/**
 * Create a timer list.
 *
 * @param count    The maximum number of timer entries to be supported 
 *			initially.  
 *
 * @return         0 means ok, the other means fail.
 */
int pub_timer_init(int count)
{
	int ret = 0;
	
	if(count <=0 || count > MAX_TIMER_NUM) {
		printf("the timer max number MUST less than %d.\n", MAX_TIMER_NUM);
		return -1;
	}
	
	memset(&timer_list, 0, sizeof(pub_timer_list_t));
	INIT_LIST_HEAD(&timer_list.header);
	timer_list.max_num = count;	

	/* Register our internal signal handler and store old signal handler */
	if ((timer_list.old_sigfunc = signal(SIGALRM, signal_func)) == SIG_ERR) {
		return -1;
	}
	timer_list.new_sigfunc = signal_func;

	/* Setting our interval timer for driver our mutil-timer and store old timer value */
	timer_list.value.it_value.tv_sec = 0;
	timer_list.value.it_value.tv_usec = TIMER_START*1000;
	timer_list.value.it_interval.tv_sec = 0;
	timer_list.value.it_interval.tv_usec = TIMER_TICK*1000;
	ret = setitimer(ITIMER_REAL, &timer_list.value, &timer_list.ovalue);

	return ret;
}

/**
 * Destroy the timer list.
 *
 * @return          0 means ok, the other means fail.
 */
int pub_timer_destroy(void)
{
	pub_timer_t *node = NULL;
	
	if ((signal(SIGALRM, timer_list.old_sigfunc)) == SIG_ERR) {
		return -1;
	}

	if((setitimer(ITIMER_REAL, &timer_list.ovalue, &timer_list.value)) < 0) {
		return -1;
	}

	while (!list_empty(&timer_list.header)) 
    {/* Delete. */
        
		node = list_first_entry(&timer_list.header, pub_timer_t , list);
	    list_del(timer_list.header.next);
		/* Free node */
		printf("Remove id %d\n", node->id);
		free(node->user_data);
		free(node);
	}
	
	memset(&timer_list, 0, sizeof(pub_timer_list_t));
	return 0;
}

//获得绝对超时时间
void time_to_absolute(struct timeval *time,struct timeval *interval)
{
    struct timeval time_now;
    gettimeofday(&time_now,NULL);
    if(time_now.tv_usec+interval->tv_usec>=1000000)
    {
        time->tv_sec=time_now.tv_sec+interval->tv_sec+1;
        time->tv_usec=time_now.tv_usec+interval->tv_usec-1000000;
    }
    else
    {
        time->tv_sec=time_now.tv_sec+interval->tv_sec;
        time->tv_usec=time_now.tv_usec+interval->tv_usec;
    }
}

//将新的计时器插入队列
int static pub_timer_insert(pub_timer_t *timer)
{
    if(list_empty(&timer_list.header))
    {
        list_add(&timer->list, &timer_list.header);
    }
    else
    {
        pub_timer_t *timer_tmp;
        struct list_head *pos;
        
        list_for_each(pos, &timer_list.header)
        {
            timer_tmp=list_entry(pos, pub_timer_t, list);
            if(timercmp(&timer->overtime,&timer_tmp->overtime,<))
            {
                list_add(pos,&timer->list);
                return timer->id;
            }
        }
        list_add_tail(&timer->list, &timer_list.header);
    }
    return timer->id;
}
/**
 * Add a timer to timer list.
 *
 * @param interval  The timer interval(second).  
 * @param cb  	    When cb!= NULL and timer expiry, call it.  
 * @param user_data Callback's param.  
 * @param len  	    The length of the user_data.  
 *
 * @return          The timer ID, if == INVALID_TIMER_ID, add timer fail.
 */
timer_id pub_timer_add(struct timeval *interval, timer_expiry *cb, void *user_data, int len)
{
	pub_timer_t *node = NULL;	
	if (cb == NULL || interval <= 0) 
    {
		return INVALID_TIMER_ID;
	}

	if(timer_list.num < timer_list.max_num) 
    {
		timer_list.num++;
	} 
    else 
	{
		return INVALID_TIMER_ID;
	} 
	
	if((node = malloc(sizeof(pub_timer_t))) == NULL)
    {
		return INVALID_TIMER_ID;
	}
    
	if(user_data != NULL || len != 0) 
    {
		node->user_data = malloc(len);
		memcpy(node->user_data, user_data, len);
		node->len = len;
	}
	node->cb = cb;
    memcpy(&node->interval,interval,sizeof(struct timeval));
    time_to_absolute(&node->overtime,interval);
    node->id = timer_list.num;

	return pub_timer_insert(node);
}

/**
 * Delete a timer from timer list.
 *
 * @param id  	    The timer ID.  
 *
 * @return          0 means ok, the other fail.
 */
int pub_timer_del(timer_id id)
{
	if (id <0 || id > timer_list.max_num) {
		return -1;
	}
    pub_timer_t *timer_tmp;
    struct list_head *pos;
    
    list_for_each(pos, &timer_list.header)
    {
        timer_tmp=list_entry(pos, pub_timer_t, list);
        if(timer_tmp->id==id)
        {
		    printf("Total timer num %d/timer id %d.\n", timer_list.num, id);
            list_del(pos);
			timer_list.num--;
			free(timer_tmp->user_data);
			free(timer_tmp);
			return 0;
        }
    }
			
	/* Can't find the timer */
	return -1;
}

/* Tick Bookkeeping */
static void signal_func(int signo)
{
    pub_timer_t *timer_tmp;
    struct list_head *pos;
    struct timeval time_now;
    gettimeofday(&time_now,NULL);
    //printf("here\n");
    list_for_each(pos, &timer_list.header)
    {
        timer_tmp=list_entry(pos, pub_timer_t, list);
		if(timercmp(&timer_tmp->overtime, &time_now, >)) 
        {
            break;
		}
        time_to_absolute(&timer_tmp->overtime, &timer_tmp->interval);
		timer_tmp->cb(timer_tmp->id, timer_tmp->user_data, timer_tmp->len);
        list_del(pos);
        pub_timer_insert(timer_tmp);
	}
}


=====h文件========================================================

#ifndef _PUB_TIME_H
#define _PUB_TIME_H

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include "pub_list.h"

#ifndef TRUE
#define TRUE 	1
#endif

#ifndef FALSE
#define FALSE	0
#endif

typedef int timer_id;
/**
 * The type of callback function to be called by timer scheduler when a timer
 * has expired.
 *
 * @param id		The timer id.
 * @param user_data     The user data.
 * $param len		The length of user data.
 */
typedef int timer_expiry(timer_id id, void *user_data, int len);

/**
 * The type of the timer
 */
typedef struct _put_timer 
{
	struct list_head list;	/**< list list		*/	
	timer_id id;			/**< timer id		*/

    
    struct timeval interval;/**< timer interval*/
    struct timeval overtime; /**< 0 -> interval 	*/
	timer_expiry *cb;		/**< call if expiry 	*/
	void *user_data;		/**< callback arg	*/
	int len;			/**< user_data length	*/
}pub_timer_t;

/**
 * The timer list
 */
typedef struct _timer_list {
	struct list_head header;	/**< list header 	*/
	int num;				/**< timer entry number */
	int max_num;				/**< max entry number	*/

	void (*old_sigfunc)(int);		/**< save previous signal handler */
	void (*new_sigfunc)(int);		/**< our signal handler	*/

	struct itimerval ovalue;		/**< old timer value */
	struct itimerval value;			/**< our internal timer value */
}pub_timer_list_t;

#ifndef timercmp 
#define timercmp(tvp, uvp, cmp) \
        ((tvp)->tv_sec cmp (uvp)->tv_sec || \
         (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
#endif

int pub_timer_init(int count);

int pub_timer_destroy(void);

timer_id pub_timer_add(struct timeval *interval, timer_expiry *cb, void *user_data, int len);

int pub_timer_del(timer_id id);


#endif /* _PUB_TIME_H */


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值