Mercurial > MadButterfly
annotate src/timer.c @ 64:c668c5c3ceae
M4 macro for C binding.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 13 Aug 2008 02:07:40 +0800 |
parents | c986e45c1e91 |
children | 6749f6639924 |
rev | line source |
---|---|
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 | |
43
6270230b9248
Use MB_TIMEVAL_CP() instead of memcpy
Thinker K.F. Li <thinker@branda.to>
parents:
41
diff
changeset
|
56 MB_TIMEVAL_CP(&timer->tmo, tmo); |
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 | |
50 | 86 /*! \brief Get how long to next timeout from this monent. |
87 * | |
88 * \return 0 for having next timeout, -1 for not more timeout. | |
89 */ | |
39 | 90 int mb_tman_next_timeout(mb_tman_t *tman, |
41 | 91 const mb_timeval_t *now, mb_timeval_t *tmo_after) { |
39 | 92 mb_timer_t *timer; |
93 | |
94 timer = STAILQ_HEAD(tman->timers); | |
95 if(timer == NULL) | |
96 return ERR; | |
97 | |
41 | 98 if(!MB_TIMEVAL_LATER(&timer->tmo, now)) { |
99 memset(tmo_after, 0, sizeof(mb_timeval_t)); | |
39 | 100 return OK; |
101 } | |
102 | |
43
6270230b9248
Use MB_TIMEVAL_CP() instead of memcpy
Thinker K.F. Li <thinker@branda.to>
parents:
41
diff
changeset
|
103 MB_TIMEVAL_CP(tmo_after, &timer->tmo); |
41 | 104 MB_TIMEVAL_DIFF(tmo_after, now); |
39 | 105 |
106 return OK; | |
107 } | |
108 | |
41 | 109 int mb_tman_handle_timeout(mb_tman_t *tman, mb_timeval_t *now) { |
39 | 110 mb_timer_t *timer; |
111 | |
112 while((timer = STAILQ_HEAD(tman->timers)) != NULL){ | |
41 | 113 if(MB_TIMEVAL_LATER(&timer->tmo, now)) |
39 | 114 break; |
41 | 115 timer->hdlr(&timer->tmo, now, timer->arg); |
39 | 116 STAILQ_REMOVE(tman->timers, mb_timer_t, next, timer); |
117 elmpool_elm_free(tman->timer_pool, timer); | |
118 } | |
119 | |
120 return OK; | |
121 } |