39
|
1 #include <stdio.h>
|
|
2 #include <stdint.h>
|
|
3 #include <stdlib.h>
|
41
|
4 #include <string.h>
|
39
|
5 #include "mb_timer.h"
|
|
6 #include "tools.h"
|
|
7
|
|
8
|
|
9 #define OK 0
|
|
10 #define ERR -1
|
|
11
|
|
12 struct _mb_timer {
|
41
|
13 mb_timeval_t tmo;
|
39
|
14 mb_tmo_hdlr hdlr;
|
|
15 void *arg;
|
|
16 mb_timer_t *next;
|
|
17 };
|
|
18
|
|
19 struct _mb_tman {
|
|
20 STAILQ(mb_timer_t) timers;
|
|
21 elmpool_t *timer_pool;
|
|
22 };
|
|
23
|
|
24 mb_tman_t *mb_tman_new(void) {
|
|
25 mb_tman_t *tman;
|
|
26
|
|
27 tman = (mb_tman_t *)malloc(sizeof(mb_tman_t));
|
|
28 if(tman == NULL)
|
|
29 return NULL;
|
|
30
|
|
31 tman->timer_pool = elmpool_new(sizeof(mb_timer_t), 32);
|
|
32 if(tman->timer_pool == NULL) {
|
|
33 free(tman);
|
|
34 return NULL;
|
|
35 }
|
|
36
|
|
37 STAILQ_INIT(tman->timers);
|
|
38
|
|
39 return tman;
|
|
40 }
|
|
41
|
|
42 void mb_tman_free(mb_tman_t *tman) {
|
|
43 elmpool_free(tman->timer_pool);
|
|
44 free(tman);
|
|
45 }
|
|
46
|
|
47 mb_timer_t *mb_tman_timeout(mb_tman_t *tman,
|
41
|
48 const mb_timeval_t *tmo,
|
39
|
49 mb_tmo_hdlr hdlr, void *arg) {
|
|
50 mb_timer_t *timer, *visit, *last;
|
|
51
|
|
52 timer = elmpool_elm_alloc(tman->timer_pool);
|
|
53 if(timer == NULL)
|
|
54 return NULL;
|
|
55
|
41
|
56 memcpy(&timer->tmo, tmo, sizeof(mb_timeval_t));
|
39
|
57 timer->hdlr = hdlr;
|
|
58 timer->arg = arg;
|
|
59
|
|
60 last = NULL;
|
|
61 for(visit = STAILQ_HEAD(tman->timers);
|
|
62 visit != NULL;
|
|
63 visit = STAILQ_NEXT(mb_timer_t, next, visit)) {
|
41
|
64 if(MB_TIMEVAL_LATER(&visit->tmo, tmo))
|
39
|
65 break;
|
|
66 last = visit;
|
|
67 }
|
|
68
|
|
69 if(last == NULL)
|
|
70 STAILQ_INS(tman->timers, mb_timer_t, next, timer);
|
|
71 else if(visit == NULL)
|
|
72 STAILQ_INS_TAIL(tman->timers, mb_timer_t, next, timer);
|
|
73 else
|
|
74 STAILQ_INS_AFTER(mb_timer_t, next, timer, last);
|
|
75
|
|
76 return timer;
|
|
77 }
|
|
78
|
|
79 int mb_tman_remove(mb_tman_t *tman, mb_timer_t *timer) {
|
|
80 STAILQ_REMOVE(tman->timers, mb_timer_t, next, timer);
|
|
81 elmpool_elm_free(tman->timer_pool, timer);
|
|
82
|
|
83 return OK;
|
|
84 }
|
|
85
|
|
86 int mb_tman_next_timeout(mb_tman_t *tman,
|
41
|
87 const mb_timeval_t *now, mb_timeval_t *tmo_after) {
|
39
|
88 mb_timer_t *timer;
|
|
89
|
|
90 timer = STAILQ_HEAD(tman->timers);
|
|
91 if(timer == NULL)
|
|
92 return ERR;
|
|
93
|
41
|
94 if(!MB_TIMEVAL_LATER(&timer->tmo, now)) {
|
|
95 memset(tmo_after, 0, sizeof(mb_timeval_t));
|
39
|
96 return OK;
|
|
97 }
|
|
98
|
41
|
99 memcpy(tmo_after, &timer->tmo, sizeof(mb_timeval_t));
|
|
100 MB_TIMEVAL_DIFF(tmo_after, now);
|
39
|
101
|
|
102 return OK;
|
|
103 }
|
|
104
|
41
|
105 int mb_tman_handle_timeout(mb_tman_t *tman, mb_timeval_t *now) {
|
39
|
106 mb_timer_t *timer;
|
|
107
|
|
108 while((timer = STAILQ_HEAD(tman->timers)) != NULL){
|
41
|
109 if(MB_TIMEVAL_LATER(&timer->tmo, now))
|
39
|
110 break;
|
41
|
111 timer->hdlr(&timer->tmo, now, timer->arg);
|
39
|
112 STAILQ_REMOVE(tman->timers, mb_timer_t, next, timer);
|
|
113 elmpool_elm_free(tman->timer_pool, timer);
|
|
114 }
|
|
115
|
|
116 return OK;
|
|
117 }
|