| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #include <stdio.h> /* For NULL */
- #include <sys/time.h> /* For gettimeofday() */
- #include "common.h"
- #include "egg_timer.h"
- /* Internal use only. */
- typedef struct egg_timer_b {
- struct egg_timer_b *next;
- int id;
- Function callback;
- void *client_data;
- egg_timeval_t howlong;
- egg_timeval_t trigger_time;
- int flags;
- } egg_timer_t;
- /* We keep a sorted list of active timers. */
- static egg_timer_t *timer_list_head = NULL;
- static unsigned int timer_next_id = 1;
- /* Based on TclpGetTime from Tcl 8.3.3 */
- int timer_get_time(egg_timeval_t *curtime)
- {
- struct timeval tv;
- struct timezone tz;
- (void) gettimeofday(&tv, &tz);
- curtime->sec = tv.tv_sec;
- curtime->usec = tv.tv_usec;
- return(0);
- }
- int timer_create_complex(egg_timeval_t *howlong, Function callback, void *client_data, int flags)
- {
- egg_timer_t *timer, *prev;
- egg_timeval_t trigger_time;
- timer_get_time(&trigger_time);
- trigger_time.sec += howlong->sec;
- trigger_time.usec += howlong->usec;
- /* Find out where this should go in the list. */
- prev = NULL;
- for (timer = timer_list_head; timer; timer = timer->next) {
- if (trigger_time.sec < timer->trigger_time.sec) break;
- if (trigger_time.sec == timer->trigger_time.sec && trigger_time.usec < timer->trigger_time.usec) break;
- prev = timer;
- }
- /* Fill out a new timer. */
- timer = (egg_timer_t *)malloc(sizeof(*timer));
- timer->callback = callback;
- timer->client_data = client_data;
- timer->flags = flags;
- egg_memcpy(&timer->howlong, howlong, sizeof(*howlong));
- egg_memcpy(&timer->trigger_time, &trigger_time, sizeof(trigger_time));
- timer->id = timer_next_id++;
- /* Insert into timer list. */
- if (prev) {
- timer->next = prev->next;
- prev->next = timer;
- }
- else {
- timer->next = timer_list_head;
- timer_list_head = timer;
- }
- if (timer_next_id == 0) timer_next_id++;
- return(timer->id);
- }
- /* Destroy a timer, given an id. */
- int timer_destroy(int timer_id)
- {
- egg_timer_t *prev, *timer;
- prev = NULL;
- for (timer = timer_list_head; timer; timer = timer->next) {
- if (timer->id == timer_id) break;
- }
- if (!timer) return(1); /* Not found! */
- /* Unlink it. */
- if (prev) prev->next = timer->next;
- else timer_list_head = timer->next;
- free(timer);
- return(0);
- }
- int timer_destroy_all()
- {
- egg_timer_t *timer;
- for (timer = timer_list_head; timer; timer = timer->next) {
- free(timer);
- }
- timer_list_head = NULL;
- return(0);
- }
- int timer_get_shortest(egg_timeval_t *howlong)
- {
- egg_timeval_t curtime;
- egg_timer_t *timer = timer_list_head;
- /* No timers? Boo. */
- if (!timer) return(1);
- timer_get_time(&curtime);
- if (timer->trigger_time.sec <= curtime.sec) howlong->sec = 0;
- else howlong->sec = timer->trigger_time.sec - curtime.sec;
- if (timer->trigger_time.usec <= curtime.usec) howlong->usec = 0;
- else howlong->usec = timer->trigger_time.usec - curtime.usec;
- return(0);
- }
- int timer_run()
- {
- egg_timeval_t curtime;
- egg_timer_t *timer;
- Function callback;
- void *client_data;
- while ((timer = timer_list_head)) {
- timer_get_time(&curtime);
- if (timer->trigger_time.sec > curtime.sec || (timer->trigger_time.sec == curtime.sec && timer->trigger_time.usec > curtime.usec)) break;
- timer_list_head = timer_list_head->next;
- callback = timer->callback;
- client_data = timer->client_data;
- if (timer->flags & TIMER_REPEAT) {
- egg_timer_t *prev, *tptr;
- /* Update timer. */
- timer->trigger_time.sec += timer->howlong.sec;
- timer->trigger_time.usec += timer->howlong.usec;
- prev = NULL;
- for (tptr = timer_list_head; tptr; tptr = tptr->next) {
- if (tptr->trigger_time.sec > timer->trigger_time.sec || (tptr->trigger_time.sec == timer->trigger_time.sec && tptr->trigger_time.usec > timer->trigger_time.usec)) break;
- prev = tptr;
- }
- if (prev) {
- timer->next = prev->next;
- prev->next = timer;
- }
- else {
- timer->next = timer_list_head;
- timer_list_head = timer;
- }
- }
- else {
- free(timer);
- }
- callback(client_data);
- }
- return(0);
- }
|