diff --git a/src/mm_clock.c b/src/mm_clock.c index e6066bbe..2c6400d1 100644 --- a/src/mm_clock.c +++ b/src/mm_clock.c @@ -48,6 +48,8 @@ int mm_clock_timer_add(mm_clock_t *clock, mm_timer_t *timer) list[count - 1] = timer; mm_buf_advance(&clock->timers, sizeof(mm_timer_t*)); timer->seq = clock->timers_seq++; + timer->timeout = clock->time + timer->timeout; + timer->active = 1; qsort(list, count, sizeof(mm_timer_t*), mm_timers_cmp); clock->timers_count = count; @@ -56,6 +58,8 @@ int mm_clock_timer_add(mm_clock_t *clock, mm_timer_t *timer) int mm_clock_timer_del(mm_clock_t *clock, mm_timer_t *timer) { + if (! timer->active) + return -1; assert(clock->timers_count >= 1); mm_timer_t **list = (mm_timer_t**)clock->timers.start; int i = 0; @@ -66,6 +70,7 @@ int mm_clock_timer_del(mm_clock_t *clock, mm_timer_t *timer) list[j] = list[i]; j++; } + timer->active = 0; clock->timers.pos -= sizeof(mm_timer_t*); clock->timers_count -= 1; qsort(list, clock->timers_count, sizeof(mm_timer_t*), @@ -81,3 +86,35 @@ mm_clock_timer_min(mm_clock_t *clock) mm_timer_t **list = (mm_timer_t**)clock->timers.start; return list[0]; } + +int mm_clock_step(mm_clock_t *clock) +{ + if (clock->timers_count == 0) + return 0; + mm_timer_t **list = (mm_timer_t**)clock->timers.start; + int timers_hit = 0; + int i = 0; + for (; i < clock->timers_count; i++) { + mm_timer_t *timer = list[i]; + if (clock->time < timer->timeout) + break; + timer->callback(timer); + timer->active = 0; + timers_hit++; + list[i] = NULL; + } + if (! timers_hit) + return 0; + int timers_left = clock->timers_count - timers_hit; + if (timers_left == 0) { + mm_buf_reset(&clock->timers); + clock->timers_count = 0; + return timers_hit; + } + memmove(clock->timers.start, + clock->timers.start + sizeof(mm_timer_t*) * timers_hit, + timers_left); + clock->timers.pos -= sizeof(mm_timer_t*) * timers_hit; + clock->timers_count -= timers_hit; + return timers_hit; +} diff --git a/src/mm_clock.h b/src/mm_clock.h index 55710b68..36e4be01 100644 --- a/src/mm_clock.h +++ b/src/mm_clock.h @@ -18,6 +18,7 @@ struct mm_clock_t { void mm_clock_init(mm_clock_t*); void mm_clock_free(mm_clock_t*); +int mm_clock_step(mm_clock_t*); int mm_clock_timer_add(mm_clock_t*, mm_timer_t*); int mm_clock_timer_del(mm_clock_t*, mm_timer_t*); mm_timer_t* diff --git a/src/mm_loop.c b/src/mm_loop.c index 1e7c0f83..9057066b 100644 --- a/src/mm_loop.c +++ b/src/mm_loop.c @@ -39,6 +39,7 @@ int mm_loop_step(mm_loop_t *loop) rc = loop->poll->iface->step(loop->poll, timeout); if (rc == -1) return -1; + mm_clock_step(&loop->clock); return 0; } diff --git a/src/mm_timer.h b/src/mm_timer.h index c29a512c..b54b62bc 100644 --- a/src/mm_timer.h +++ b/src/mm_timer.h @@ -9,13 +9,24 @@ typedef struct mm_timer_t mm_timer_t; -typedef int (*mm_timer_callback_t)(mm_timer_t*); +typedef void (*mm_timer_callback_t)(mm_timer_t*); struct mm_timer_t { + int active; int timeout; int seq; mm_timer_callback_t callback; void *arg; }; +static inline void +mm_timer_init(mm_timer_t *timer, mm_timer_callback_t cb, int interval) +{ + timer->active = 0; + timer->timeout = interval; + timer->seq = 0; + timer->callback = cb; + timer->arg = NULL; +} + #endif