39
|
1 #include <stdio.h>
|
|
2 #include <stdint.h>
|
|
3 #include <stdlib.h>
|
|
4 #include "mb_timer.h"
|
|
5 #include "tools.h"
|
|
6
|
|
7
|
|
8 #define OK 0
|
|
9 #define ERR -1
|
|
10
|
|
11 struct _mb_timer {
|
|
12 mbsec_t sec;
|
|
13 mbusec_t usec;
|
|
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,
|
|
48 mbsec_t sec, mbusec_t usec,
|
|
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
|
|
56 timer->sec = sec;
|
|
57 timer->usec = usec;
|
|
58 timer->hdlr = hdlr;
|
|
59 timer->arg = arg;
|
|
60
|
|
61 last = NULL;
|
|
62 for(visit = STAILQ_HEAD(tman->timers);
|
|
63 visit != NULL;
|
|
64 visit = STAILQ_NEXT(mb_timer_t, next, visit)) {
|
|
65 if(sec < visit->sec)
|
|
66 break;
|
|
67 if(sec == visit->sec && usec < visit->usec)
|
|
68 break;
|
|
69 last = visit;
|
|
70 }
|
|
71
|
|
72 if(last == NULL)
|
|
73 STAILQ_INS(tman->timers, mb_timer_t, next, timer);
|
|
74 else if(visit == NULL)
|
|
75 STAILQ_INS_TAIL(tman->timers, mb_timer_t, next, timer);
|
|
76 else
|
|
77 STAILQ_INS_AFTER(mb_timer_t, next, timer, last);
|
|
78
|
|
79 return timer;
|
|
80 }
|
|
81
|
|
82 int mb_tman_remove(mb_tman_t *tman, mb_timer_t *timer) {
|
|
83 STAILQ_REMOVE(tman->timers, mb_timer_t, next, timer);
|
|
84 elmpool_elm_free(tman->timer_pool, timer);
|
|
85
|
|
86 return OK;
|
|
87 }
|
|
88
|
|
89 int mb_tman_next_timeout(mb_tman_t *tman,
|
|
90 mbsec_t now_sec, mbusec_t now_usec,
|
|
91 mbsec_t *after_sec, mbusec_t *after_usec) {
|
|
92 mb_timer_t *timer;
|
|
93
|
|
94 timer = STAILQ_HEAD(tman->timers);
|
|
95 if(timer == NULL)
|
|
96 return ERR;
|
|
97
|
|
98 if(now_sec > timer->sec ||
|
|
99 (now_sec == timer->usec && now_usec >= timer->usec)) {
|
|
100 *after_sec = 0;
|
|
101 *after_usec = 0;
|
|
102 return OK;
|
|
103 }
|
|
104
|
|
105 *after_sec = timer->sec - now_sec;
|
|
106 if(now_usec > timer->usec) {
|
|
107 --*after_sec;
|
|
108 *after_usec = 1000000 + timer->usec - now_usec;
|
|
109 } else
|
|
110 *after_usec = timer->usec - now_usec;
|
|
111
|
|
112 return OK;
|
|
113 }
|
|
114
|
|
115 int mb_tman_handle_timeout(mb_tman_t *tman,
|
|
116 mbsec_t now_sec, mbusec_t now_usec) {
|
|
117 mb_timer_t *timer;
|
|
118
|
|
119 while((timer = STAILQ_HEAD(tman->timers)) != NULL){
|
|
120 if(now_sec < timer->sec ||
|
|
121 (now_sec == timer->sec && now_usec < timer->usec))
|
|
122 break;
|
|
123 timer->hdlr(timer->sec, timer->usec,
|
|
124 now_sec, now_usec,
|
|
125 timer->arg);
|
|
126 STAILQ_REMOVE(tman->timers, mb_timer_t, next, timer);
|
|
127 elmpool_elm_free(tman->timer_pool, timer);
|
|
128 }
|
|
129
|
|
130 return OK;
|
|
131 }
|