打印

发布一个超时检查的timer

发布一个超时检查的timer

使用方法: gcc -o evtimer evtimer.c -D_DEBUG_EVTIMER && ./evtimer

使用:
初始添加超时时间的时候可以使用EVTIMER_ADD 会获得一个EVID, 这个需要保存起来
如果你想更新超时时间需要根据EVID做EVTIMER_UPDATE,操作.
删除超时事件用EVTIMER_DEL
检查超时执行EVTIMER_CHECK 就可以了

基本原理是放入一个时间我会使用 超时点 = (当前时间+超时时间)
每次check的时候计算当时时间, 弹出所有在list头里的低于当前时间的所有事件.....
因为check是循环的,所以基本上所有的事件都能检查出来.
修改一个超时事件的时间的时候会自动冒泡排序整个列表.....




evtimer.h

[Copy to clipboard] [ - ]CODE:
#include <unistd.h>
#include "mutex.h"
#ifndef _EVTIMER_H
#define _EVTIMER_H
typedef void (EVTCALLBACK)(void *);
typedef struct _EVTNODE
{
    int id;
    EVTCALLBACK *handler;
    void *arg;
    long long evusec;
    int ison;
    struct _EVTNODE *prev;
    struct _EVTNODE *next;
}EVTNODE;
typedef struct _EVTIMER
{
   struct timeval tv;
   EVTNODE **evlist;
   int nlist;
   EVTNODE *head;
   EVTNODE *tail;
   EVTNODE *node;
   int nq;
   int left;
   long long now;
   int n ;
   void *mutex;
}EVTIMER;
#define PEVT(ptr) ((EVTIMER *)ptr)
#define PEVT_NQ(ptr) (((EVTIMER *)ptr)->nq)
#define PEVT_LEFT(ptr) (((EVTIMER *)ptr)->left)
#define PEVT_NOW(ptr) (((EVTIMER *)ptr)->now)
#define PEVT_N(ptr) (((EVTIMER *)ptr)->n)
#define PEVT_NLIST(ptr) (((EVTIMER *)ptr)->nlist)
#define PEVT_NODE(ptr) (((EVTIMER *)ptr)->node)
#define PEVT_HEAD(ptr) (((EVTIMER *)ptr)->head)
#define PEVT_TAIL(ptr) (((EVTIMER *)ptr)->tail)
#define PEVT_EVLIST(ptr) (((EVTIMER *)ptr)->evlist)
#define PEVT_EVN(ptr, n) (((EVTIMER *)ptr)->evlist[n])
#define EVTIMER_NOW(ptr) ((ptr && gettimeofday(&(PEVT(ptr)->tv), NULL) == 0)?                   \
    (PEVT_NOW(ptr) = PEVT(ptr)->tv.tv_sec * 1000000ll + PEVT(ptr)->tv.tv_usec * 1ll) : -1)

/* evtimer initialize */
#define EVTIMER_INIT(ptr)                                                                       \
do{                                                                                             \
    if((ptr = calloc(1, sizeof(EVTIMER))))                                                      \
    {                                                                                           \
        MUTEX_INIT(PEVT(ptr)->mutex);                                                           \
    }                                                                                           \
}while(0)

/* evtimer resort */
#define EVTIMER_RESORT(ptr, evnode)                                                             \
{                                                                                               \
    if(ptr && evnode)                                                                           \
    {                                                                                           \
        while(evnode->next && evnode->evusec > evnode->next->evusec)                            \
        {                                                                                       \
            if(evnode->prev) evnode->prev->next = evnode->next;                                 \
            evnode->next->prev = evnode->prev;                                                  \
            evnode->prev = evnode->next;                                                        \
            evnode->next = evnode->prev->next;                                                  \
            evnode->prev->next = evnode;                                                        \
            if(evnode->next)evnode->next->prev = evnode;                                        \
        }                                                                                       \
        while(evnode->prev && evnode->evusec < evnode->prev->evusec)                            \
        {                                                                                       \
            if(evnode->next) evnode->next->prev = evnode->prev;                                 \
            evnode->prev->next = evnode->next;                                                  \
            evnode->next = evnode->prev;                                                        \
            evnode->prev = evnode->next->prev;                                                  \
            evnode->next->prev = evnode;                                                        \
            if(evnode->prev)evnode->prev->next = evnode;                                        \
        }                                                                                       \
        if(evnode->next == NULL) PEVT_TAIL(ptr) = evnode;                                       \
        if(evnode->prev == NULL) PEVT_HEAD(ptr) = evnode;                                       \
    }                                                                                           \
}

/* evtimer push */
#define EVTIMER_PUSH(ptr, evnode)                                                               \
do{                                                                                             \
    if(ptr && evnode)                                                                           \
    {                                                                                           \
        if(PEVT_HEAD(ptr) == NULL || PEVT_TAIL(ptr) == NULL)                                    \
        {                                                                                       \
            PEVT_HEAD(ptr) = evnode;                                                            \
            PEVT_TAIL(ptr) = evnode;                                                            \
        }                                                                                       \
        else if(PEVT_HEAD(ptr) && evnode->evusec <= PEVT_HEAD(ptr)->evusec)                     \
        {                                                                                       \
            evnode->next = PEVT_HEAD(ptr);                                                      \
            PEVT_HEAD(ptr)->prev = evnode;                                                      \
            PEVT_HEAD(ptr) = evnode;                                                            \
        }                                                                                       \
        else if(PEVT_TAIL(ptr) && evnode->evusec >= PEVT_TAIL(ptr)->evusec)                     \
        {                                                                                       \
            evnode->prev = PEVT_TAIL(ptr);                                                      \
            PEVT_TAIL(ptr)->next = evnode;                                                      \
            PEVT_TAIL(ptr) = evnode;                                                            \
        }                                                                                       \
        else                                                                                    \
        {                                                                                       \
            PEVT_NODE(ptr) = PEVT_TAIL(ptr);                                                    \
            do                                                                                  \
            {                                                                                   \
                PEVT_NODE(ptr) = PEVT_NODE(ptr)->prev;                                          \
            }while(PEVT_NODE(ptr) && PEVT_NODE(ptr)->evusec > evnode->evusec);                  \
            if(PEVT_NODE(ptr))                                                                  \
            {                                                                                   \
                PEVT_NODE(ptr)->next->prev = evnode;                                            \
                evnode->next = PEVT_NODE(ptr)->next;                                            \
                evnode->prev = PEVT_NODE(ptr);                                                  \
                PEVT_NODE(ptr)->next = evnode;                                                  \
            }                                                                                   \
        }                                                                                       \
        evnode->ison = 1;                                                                       \
        PEVT_NQ(ptr)++;                                                                         \
    }                                                                                           \
}while(0)

/* evtimer add */
#define EVTIMER_ADD(ptr, evtime, evhandler, evarg, evid)                                        \
do{                                                                                             \
    evid = -1;                                                                                  \
    MUTEX_LOCK(PEVT(ptr)->mutex);                                                               \
    if(PEVT_LEFT(ptr) == 0)                                                                     \
    {                                                                                           \
        if((PEVT_EVLIST(ptr) = (EVTNODE **)realloc(PEVT_EVLIST(ptr),                            \
                        (PEVT_NLIST(ptr) + 1) * sizeof(EVTNODE *))))                            \
        {                                                                                       \
            evid = PEVT_NLIST(ptr)++;                                                           \
            PEVT_EVN(ptr, evid) = (EVTNODE *)calloc(1, sizeof(EVTNODE));                        \
        }                                                                                       \
    }                                                                                           \
    else                                                                                        \
    {                                                                                           \
        for(PEVT_N(ptr) = 0; PEVT_N(ptr) < PEVT_NLIST(ptr); PEVT_N(ptr)++)                      \
        {                                                                                       \
            if(PEVT_EVN(ptr, PEVT_N(ptr))->id == -1)                                            \
            {                                                                                   \
                evid = PEVT_N(ptr);                                                             \
                break;                                                                          \
            }                                                                                   \
        }                                                                                       \
    }                                                                                           \
    if(evid >= 0 && PEVT_EVLIST(ptr))                                                           \
    {                                                                                           \
        PEVT_EVN(ptr, evid)->id      = evid;                                                    \
        PEVT_EVN(ptr, evid)->handler = evhandler;                                               \
        PEVT_EVN(ptr, evid)->arg     = evarg;                                                   \
        PEVT_EVN(ptr, evid)->evusec  = EVTIMER_NOW(ptr) + evtime;                               \
        EVTIMER_PUSH(ptr, PEVT_EVN(ptr, evid));                                                 \
    }                                                                                           \
    MUTEX_UNLOCK(PEVT(ptr)->mutex);                                                             \
}while(0)

/* evtimer update */
#define EVTIMER_UPDATE(ptr, evid, evtime, evhandler, evarg)                                     \
do{                                                                                             \
    MUTEX_LOCK(PEVT(ptr)->mutex);                                                               \
    if(ptr && evid >= 0 && evid < PEVT_NLIST(ptr) && PEVT_EVLIST(ptr))                          \
    {                                                                                           \
        PEVT_EVN(ptr, evid)->id      = evid;                                                    \
        PEVT_EVN(ptr, evid)->handler = evhandler;                                               \
        PEVT_EVN(ptr, evid)->arg     = evarg;                                                   \
        PEVT_EVN(ptr, evid)->evusec  = EVTIMER_NOW(ptr) + evtime;                               \
        if(PEVT_EVN(ptr, evid)->ison)                                                           \
        {                                                                                       \
            EVTIMER_RESORT(ptr, PEVT_EVN(ptr, evid));                                           \
        }                                                                                       \
        else                                                                                    \
        {                                                                                       \
            PEVT_EVN(ptr, evid)->next = NULL;                                                   \
            PEVT_EVN(ptr, evid)->prev = NULL;                                                   \
            EVTIMER_PUSH(ptr, PEVT_EVN(ptr, evid));                                             \
        }                                                                                       \
    }                                                                                           \
    MUTEX_UNLOCK(PEVT(ptr)->mutex);                                                             \
}while(0)

/* evtimer delete */
#define EVTIMER_DEL(ptr, evid)                                                                  \
do{                                                                                             \
    MUTEX_LOCK(PEVT(ptr)->mutex);                                                               \
    if(ptr && evid >= 0 && evid < PEVT_NLIST(ptr) && PEVT_EVLIST(ptr) && PEVT_EVN(ptr, evid))   \
    {                                                                                           \
        PEVT_EVN(ptr, evid)->id      = -1;                                                      \
    }                                                                                           \
    MUTEX_UNLOCK(PEVT(ptr)->mutex);                                                             \
}while(0)

/* evtimer list */
#define EVTIMER_LIST(ptr, fp)                                                                   \
do{                                                                                             \
    MUTEX_LOCK(PEVT(ptr)->mutex);                                                               \
    if(ptr && (PEVT_NODE(ptr) = PEVT_HEAD(ptr)))                                                \
    {                                                                                           \
        do{                                                                                     \
            fprintf(fp, "prev:%08x id:%d ison:%d handler:%08x arg:%08x next:%08x\n",            \
                    PEVT_NODE(ptr)->prev, PEVT_NODE(ptr)->id, PEVT_NODE(ptr)->ison,             \
                    PEVT_NODE(ptr)->handler, PEVT_NODE(ptr)->arg, PEVT_NODE(ptr)->next);        \
        }while((PEVT_NODE(ptr) = PEVT_NODE(ptr)->next));                                        \
    }                                                                                           \
    MUTEX_UNLOCK(PEVT(ptr)->mutex);                                                             \
}while(0)

/* evtimer check */
#define EVTIMER_CHECK(ptr)                                                                      \
do{                                                                                             \
    MUTEX_LOCK(PEVT(ptr)->mutex);                                                               \
    if(ptr && PEVT_HEAD(ptr) && PEVT_NQ(ptr) > 0)                                               \
    {                                                                                           \
        EVTIMER_NOW(ptr);                                                                       \
        while((PEVT_NODE(ptr) = PEVT_HEAD(ptr))  && PEVT_NODE(ptr)->evusec <= PEVT_NOW(ptr))    \
        {                                                                                       \
            if(PEVT_NODE(ptr)->id >= 0 && PEVT_NODE(ptr)->handler)                              \
            {                                                                                   \
                PEVT_NODE(ptr)->handler(PEVT_NODE(ptr)->arg);                                   \
            }                                                                                   \
            PEVT_NQ(ptr)--;                                                                     \
            PEVT_HEAD(ptr) = PEVT_NODE(ptr)->next;                                              \
            PEVT_NODE(ptr)->ison = 0;                                                           \
            PEVT_NODE(ptr)->prev = NULL;                                                        \
            PEVT_NODE(ptr)->next = NULL;                                                        \
            if(PEVT_HEAD(ptr) == NULL) PEVT_TAIL(ptr) = NULL;                                   \
        }                                                                                       \
    }                                                                                           \
    MUTEX_UNLOCK(PEVT(ptr)->mutex);                                                             \
}while(0)
/* evtimer reset */
#define EVTIMER_RESET(ptr)                                                                      \
do{                                                                                             \
    if(ptr)                                                                                     \
    {                                                                                           \
        if(PEVT_EVLIST(ptr))                                                                    \
        {                                                                                       \
            for(PEVT_N(ptr) = 0; PEVT_N(ptr) < PEVT_NLIST(ptr); PEVT_N(ptr)++)                  \
            {                                                                                   \
                if(PEVT_EVN(ptr, PEVT_N(ptr)))                                                  \
                {                                                                               \
                    memset(PEVT_EVN(ptr, PEVT_N(ptr)), 0, sizeof(EVTNODE));                     \
                    PEVT_EVN(ptr, PEVT_N(ptr))->id = -1;                                        \
                }                                                                               \
            }                                                                                   \
            PEVT_LEFT(ptr) = PEVT_NLIST(ptr);                                                   \
        }                                                                                       \
        PEVT_NQ(ptr) = 0;                                                                       \
        PEVT_HEAD(ptr) = NULL;                                                                  \
        PEVT_TAIL(ptr) = NULL;                                                                  \
    }                                                                                           \
}while(0)

/* evtimer clean */
#define EVTIMER_CLEAN(ptr)                                                                      \
{                                                                                               \
    if(ptr)                                                                                     \
    {                                                                                           \
        if(PEVT_EVLIST(ptr))                                                                    \
        {                                                                                       \
            for(PEVT_N(ptr) = 0; PEVT_N(ptr) < PEVT_NLIST(ptr); PEVT_N(ptr)++)                  \
            {                                                                                   \
                if(PEVT_EVN(ptr, PEVT_N(ptr))) free(PEVT_EVN(ptr, PEVT_N(ptr)));                \
            }                                                                                   \
            free(PEVT_EVLIST(ptr));                                                             \
        }                                                                                       \
        free(ptr);                                                                              \
        ptr = NULL;                                                                             \
    }                                                                                           \
}
#endif

TOP


感谢一直以来您对我们的支持!
当前时区 GMT+8, 现在时间是 2008-11-22 21:01 京ICP证060528 号

Designed By 17DST