00001 #include <stdio.h>
00002 #include <stdint.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include "mb_timer.h"
00006 #include "mb_tools.h"
00007
00008
00009 #define OK 0
00010 #define ERR -1
00011
00012 struct _mb_timer {
00013 mb_timeval_t tmo;
00014 mb_tmo_hdlr hdlr;
00015 void *arg;
00016 mb_timer_t *next;
00017 };
00018
00019 struct _mb_tman {
00020 STAILQ(mb_timer_t) timers;
00021 elmpool_t *timer_pool;
00022 };
00023
00024 mb_tman_t *mb_tman_new(void) {
00025 mb_tman_t *tman;
00026
00027 tman = (mb_tman_t *)malloc(sizeof(mb_tman_t));
00028 if(tman == NULL)
00029 return NULL;
00030
00031 tman->timer_pool = elmpool_new(sizeof(mb_timer_t), 32);
00032 if(tman->timer_pool == NULL) {
00033 free(tman);
00034 return NULL;
00035 }
00036
00037 STAILQ_INIT(tman->timers);
00038
00039 return tman;
00040 }
00041
00042 void mb_tman_free(mb_tman_t *tman) {
00043 elmpool_free(tman->timer_pool);
00044 free(tman);
00045 }
00046
00047 mb_timer_t *mb_tman_timeout(mb_tman_t *tman,
00048 const mb_timeval_t *tmo,
00049 mb_tmo_hdlr hdlr, void *arg) {
00050 mb_timer_t *timer, *visit, *last;
00051
00052 timer = elmpool_elm_alloc(tman->timer_pool);
00053 if(timer == NULL)
00054 return NULL;
00055
00056 MB_TIMEVAL_CP(&timer->tmo, tmo);
00057 timer->hdlr = hdlr;
00058 timer->arg = arg;
00059
00060 last = NULL;
00061 for(visit = STAILQ_HEAD(tman->timers);
00062 visit != NULL;
00063 visit = STAILQ_NEXT(mb_timer_t, next, visit)) {
00064 if(MB_TIMEVAL_LATER(&visit->tmo, tmo) ||
00065 MB_TIMEVAL_EQ(&visit->tmo, tmo))
00066 break;
00067 last = visit;
00068 }
00069
00070 if(last == NULL)
00071 STAILQ_INS(tman->timers, mb_timer_t, next, timer);
00072 else if(visit == NULL)
00073 STAILQ_INS_TAIL(tman->timers, mb_timer_t, next, timer);
00074 else
00075 STAILQ_INS_AFTER(mb_timer_t, next, timer, last);
00076
00077 return timer;
00078 }
00079
00080 int mb_tman_remove(mb_tman_t *tman, mb_timer_t *timer) {
00081 STAILQ_REMOVE(tman->timers, mb_timer_t, next, timer);
00082 elmpool_elm_free(tman->timer_pool, timer);
00083
00084 return OK;
00085 }
00086
00087
00088
00089
00090
00091 int mb_tman_next_timeout(mb_tman_t *tman,
00092 const mb_timeval_t *now, mb_timeval_t *tmo_after) {
00093 mb_timer_t *timer;
00094
00095 timer = STAILQ_HEAD(tman->timers);
00096 if(timer == NULL)
00097 return ERR;
00098
00099 if(!MB_TIMEVAL_LATER(&timer->tmo, now)) {
00100 memset(tmo_after, 0, sizeof(mb_timeval_t));
00101 return OK;
00102 }
00103
00104 MB_TIMEVAL_CP(tmo_after, &timer->tmo);
00105 MB_TIMEVAL_DIFF(tmo_after, now);
00106
00107 return OK;
00108 }
00109
00110 int mb_tman_handle_timeout(mb_tman_t *tman, mb_timeval_t *now) {
00111 mb_timer_t *timer;
00112
00113 while((timer = STAILQ_HEAD(tman->timers)) != NULL){
00114 if(MB_TIMEVAL_LATER(&timer->tmo, now))
00115 break;
00116 timer->hdlr(&timer->tmo, now, timer->arg);
00117 STAILQ_REMOVE(tman->timers, mb_timer_t, next, timer);
00118 elmpool_elm_free(tman->timer_pool, timer);
00119 }
00120
00121 return OK;
00122 }