#include "mul_timer.h" #include <stdio.h> #include <stdlib.h> #include <time.h> void CALLBACK traverse_mul_timer(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2); static int print_mul_timer(struct _mul_timer_manage *ptimer); struct _mul_timer_manage *init_mul_timer(unsigned int time_unit) { struct _mul_timer_manage *p; if( (p = malloc(sizeof(struct _mul_timer_manage))) == NULL) { return (NULL); } p->etr_head = NULL; p->timer_cnt = 0; p->time_unit = time_unit; p->entry_id = 0; p->timer_id = timeSetEvent(time_unit, 0, (LPTIMECALLBACK )traverse_mul_timer, (DWORD)p, TIME_PERIODIC); return(p); } timer_handle_t set_timer(struct _mul_timer_manage *ptimer, unsigned int time_out, int (* timer_proc) (void *arg, unsigned int *arg_len), void *arg, unsigned int *arg_len) { struct _mul_timer_entry *p, *prev, *pnew; if(ptimer == NULL || time_out == 0) { return (NULL); } if( (pnew = malloc(sizeof(struct _mul_timer_entry))) == NULL) { return (NULL); } pnew->is_use = 0; pnew->arg = arg; pnew->arg_len = arg_len; pnew->elapse = 0; pnew->timer_proc = timer_proc; p = ptimer->etr_head; prev = NULL; while(p != NULL) { if(p->timeout < time_out) /* assume the latest time_proc has higher priority */ { time_out = time_out-p->timeout; prev = p; p = p->etr_next; } else { p->timeout -= time_out; break; } } pnew->timeout = time_out; pnew->etr_next = p; pnew->handle.ptr = (unsigned long )pnew; pnew->handle.entry_id = ptimer->entry_id; ptimer->entry_id++; if(prev == NULL) { ptimer->etr_head = pnew; } else { prev->etr_next = pnew; } ptimer->timer_cnt++; return (&pnew->handle); } int kill_timer(struct _mul_timer_manage *ptimer, timer_handle_t hdl) { struct _mul_timer_entry *p, *prev; if(ptimer == NULL) { return (0); } p = ptimer->etr_head; prev = NULL; while(p != NULL) { if(p->handle.ptr == hdl->ptr && p->handle.entry_id == hdl->entry_id) { break; } prev = p; p = p->etr_next; } /* no such timer or timer is in use, return 0 */ if(p == NULL || (p != NULL && p->is_use == 1)) { return (0); } /* has found the timer */ if(prev == NULL) { ptimer->etr_head = p->etr_next; } else { prev->etr_next = p->etr_next; } /* revise timeout */ if(p->etr_next != NULL) { p->etr_next->timeout += p->timeout; } /* delete the timer */ free(p); p = NULL; ptimer->timer_cnt--; return (1); } int get_timeout_byhdl(struct _mul_timer_manage *ptimer, timer_handle_t hdl) { struct _mul_timer_entry *p; unsigned int timeout; if(ptimer == NULL || (struct _mul_timer_entry *)(hdl) == NULL) { return (-1); } timeout = 0; p = ptimer->etr_head; while(p != NULL) { if(p->handle.ptr == hdl->ptr && p->handle.entry_id == hdl->entry_id) { break; } timeout += p->timeout; p = p->etr_next; } if(p == NULL) { return (-1); } else { return ((int)timeout+p->timeout); } } int get_timeout_bytimeproc(struct _mul_timer_manage *ptimer, int (* timer_proc) (void *arg, unsigned int *arg_len)) { struct _mul_timer_entry *p; unsigned int timeout; if(ptimer == NULL || timer_proc == NULL) { return (-1); } p = ptimer->etr_head; while((p != NULL) && (p->timer_proc != timer_proc)) { timeout += p->timeout; p = p->etr_next; } if(p == NULL) { return (-1); } else { return (timeout+p->timeout); } } int release_mul_timer(struct _mul_timer_manage *ptimer) { struct _mul_timer_entry *p, *ptmp; if(ptimer == NULL) { return (0); } timeKillEvent(ptimer->timer_id); /* delete all timers */ p = ptimer->etr_head; while(p != NULL) { ptmp = p; p = p->etr_next; free(ptmp); } /* delete timer_manage */ free(ptimer); ptimer = NULL; return (1); } int is_valid_time_hdl(timer_handle_t hdl) { if(hdl == NULL) { return (0); } else { return (1); } } void CALLBACK traverse_mul_timer(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { struct _mul_timer_manage *ptimer; struct _mul_timer_entry *p, *ptmp; unsigned int timeout; ptimer = (struct _mul_timer_manage *)dwUser; if(ptimer == NULL) { return; } timeout = ptimer->time_unit; p = ptimer->etr_head; while(p != NULL) { if(p->timeout <= timeout) { p->is_use = 1; p->timer_proc(p->arg, p->arg_len); ptmp = p; timeout -= p->timeout; p = p->etr_next; free(ptmp); ptimer->etr_head = p; } else { p->timeout -= timeout; p->elapse += timeout; ptimer->etr_head = p; break; } } if(p == NULL) { ptimer->etr_head = NULL; } return; } static int print_mul_timer(struct _mul_timer_manage *ptimer) { struct _mul_timer_entry *p; int i; if(ptimer == NULL) { return (0); } printf("***************************mul_timer statistics start************************/n"); printf("this mul_timer's time_unit=%u, etr_head=%p and has %d timers:/n", ptimer->time_unit, ptimer->etr_head, ptimer->timer_cnt); p = ptimer->etr_head; i = 0; while(p != NULL) { printf("the %d timer: timeout=%u, elapse=%u, timer_proc=%p, arg=%p, arg_len=%p, etr_next=%p/n" , i+1, p->timeout, p->elapse, p->timer_proc, p->arg, p->arg_len, p->etr_next); p = p->etr_next; i++; } printf("***************************mul_timer statistics end************************/n"); return (1); } #define _MUL_TIMER_MAIN #ifdef _MUL_TIMER_MAIN static void get_format_time(char *tstr) { time_t t; t = time(NULL); strcpy(tstr, ctime(&t)); tstr[strlen(tstr)-1] = '/0'; return; } timer_handle_t hdl[100]; int call_cnt = 0; struct _mul_timer_manage *ptimer; int timer_proc1(void *arg, unsigned int *len) { char tstr[200]; static int i, ret; get_format_time(tstr); printf("call_cnt=%d, hello %s: timer_proc1 is here./n", call_cnt, tstr); i++; call_cnt++; return (1); } int timer_proc2(void * arg, unsigned int *len) { char tstr[200]; static int i, ret; get_format_time(tstr); printf("call_cnt=%d, hello %s: timer_proc2 is here: arg = %s, len = %d./n", call_cnt, tstr, arg, *len); i++; call_cnt++; return (1); } int main(void) { char arg[50] = "hello, multiple timers"; char tstr[200]; int ret; int len = 50, i; ptimer = init_mul_timer(1000); for(i = 0; i < 10; i++) { hdl[i<<1] = set_timer(ptimer, 1000*(i+1), timer_proc1, NULL, NULL); printf("hdl[0i<<1=%d, is_valid_hdl=%d/n", hdl[i<<1], is_valid_time_hdl(hdl[i<<1])); hdl[(i<<1)+1] = set_timer(ptimer, 3000*(i+1), timer_proc2, arg, &len); printf("hdl[i<<1+1]=%d, is_valid_hdl=%d/n", hdl[(i<<1)+1], is_valid_time_hdl(hdl[(i<<1)+1])); print_mul_timer(ptimer); } ret = kill_timer(ptimer, hdl[17]); printf("ret=kill_timer=%d/n", ret); print_mul_timer(ptimer); printf("hd[19]->timout=%d/n", get_timeout_byhdl(ptimer, hdl[19])); while(1) { if(call_cnt == 15) { get_format_time(tstr); ret = release_mul_timer(ptimer); printf("call_cnt=%d, main: %s destroy_mul_timer, ret=%d/n", call_cnt, tstr, ret); call_cnt++; } } return 0; } #endif |