|
|
@@ -44,7 +44,7 @@ typedef struct egg_timer_b {
|
|
|
} egg_timer_t;
|
|
|
|
|
|
/* We keep a sorted list of active timers. */
|
|
|
-static egg_timer_t *timer_list_head = NULL;
|
|
|
+static egg_timer_t *timer_repeat_head = NULL, *timer_once_head = NULL;
|
|
|
static int timer_next_id = 1;
|
|
|
|
|
|
/* Based on TclpGetTime from Tcl 8.3.3 */
|
|
|
@@ -116,12 +116,12 @@ long timeval_diff(const egg_timeval_t *tv1, const egg_timeval_t *tv2)
|
|
|
return usecs;
|
|
|
}
|
|
|
|
|
|
-static int timer_add_to_list(egg_timer_t *timer)
|
|
|
+static int timer_add_to_list(egg_timer_t* &timer_list, egg_timer_t *timer)
|
|
|
{
|
|
|
egg_timer_t *prev = NULL, *ptr = NULL;
|
|
|
|
|
|
/* Find out where this should go in the list. */
|
|
|
- for (ptr = timer_list_head; ptr; ptr = ptr->next) {
|
|
|
+ for (ptr = timer_list; ptr; ptr = ptr->next) {
|
|
|
if (timer->trigger_time.sec < ptr->trigger_time.sec) break;
|
|
|
if (timer->trigger_time.sec == ptr->trigger_time.sec && timer->trigger_time.usec < ptr->trigger_time.usec) break;
|
|
|
prev = ptr;
|
|
|
@@ -133,8 +133,8 @@ static int timer_add_to_list(egg_timer_t *timer)
|
|
|
prev->next = timer;
|
|
|
}
|
|
|
else {
|
|
|
- timer->next = timer_list_head;
|
|
|
- timer_list_head = timer;
|
|
|
+ timer->next = timer_list;
|
|
|
+ timer_list = timer;
|
|
|
}
|
|
|
return(0);
|
|
|
}
|
|
|
@@ -167,18 +167,20 @@ int timer_create_complex(egg_timeval_t *howlong, const char *name, Function call
|
|
|
timer->trigger_time.usec = now.usec + howlong->usec;
|
|
|
timer->called = 0;
|
|
|
|
|
|
- timer_add_to_list(timer);
|
|
|
+ if (timer->flags & TIMER_REPEAT)
|
|
|
+ timer_add_to_list(timer_repeat_head, timer);
|
|
|
+ else
|
|
|
+ timer_add_to_list(timer_once_head, timer);
|
|
|
|
|
|
return(timer->id);
|
|
|
}
|
|
|
|
|
|
-/* Destroy a timer, given an id. */
|
|
|
-int timer_destroy(int timer_id)
|
|
|
+static int timer_destroy_list(egg_timer_t* &timer_list, int timer_id)
|
|
|
{
|
|
|
egg_timer_t *prev = NULL, *timer = NULL;
|
|
|
|
|
|
prev = NULL;
|
|
|
- for (timer = timer_list_head; timer; timer = timer->next) {
|
|
|
+ for (timer = timer_list; timer; timer = timer->next) {
|
|
|
if (timer->id == timer_id) break;
|
|
|
prev = timer;
|
|
|
}
|
|
|
@@ -187,13 +189,24 @@ int timer_destroy(int timer_id)
|
|
|
|
|
|
/* Unlink it. */
|
|
|
if (prev) prev->next = timer->next;
|
|
|
- else timer_list_head = timer->next;
|
|
|
+ else timer_list = timer->next;
|
|
|
|
|
|
- if (timer->name) free(timer->name);
|
|
|
+ if (timer->name)
|
|
|
+ free(timer->name);
|
|
|
free(timer);
|
|
|
return(0);
|
|
|
}
|
|
|
|
|
|
+/* Destroy a timer, given an id. */
|
|
|
+int timer_destroy(int timer_id)
|
|
|
+{
|
|
|
+ if (timer_destroy_list(timer_repeat_head, timer_id))
|
|
|
+ if (timer_destroy_list(timer_once_head, timer_id))
|
|
|
+ return 1;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef not_used
|
|
|
int timer_destroy_all()
|
|
|
{
|
|
|
egg_timer_t *timer = NULL, *next = NULL;
|
|
|
@@ -204,10 +217,11 @@ int timer_destroy_all()
|
|
|
timer_list_head = NULL;
|
|
|
return(0);
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
int timer_get_shortest(egg_timeval_t *howlong)
|
|
|
{
|
|
|
- egg_timer_t *timer = timer_list_head;
|
|
|
+ egg_timer_t *timer = timer_repeat_head;
|
|
|
|
|
|
/* No timers? Boo. */
|
|
|
if (!timer) return(1);
|
|
|
@@ -216,49 +230,49 @@ int timer_get_shortest(egg_timeval_t *howlong)
|
|
|
return(0);
|
|
|
}
|
|
|
|
|
|
-int timer_run()
|
|
|
-{
|
|
|
- egg_timer_t *timer = NULL;
|
|
|
- TimerFunc callback;
|
|
|
- void *client_data = NULL;
|
|
|
-
|
|
|
- while (timer_list_head) {
|
|
|
- timer = timer_list_head;
|
|
|
-
|
|
|
- if (timer->trigger_time.sec > now.sec ||
|
|
|
- (timer->trigger_time.sec == now.sec && timer->trigger_time.usec > now.usec)) break;
|
|
|
-
|
|
|
- timer_list_head = timer_list_head->next;
|
|
|
-
|
|
|
- callback = timer->callback;
|
|
|
- client_data = timer->client_data;
|
|
|
-
|
|
|
- if (timer->flags & TIMER_REPEAT) {
|
|
|
- /* Update timer. */
|
|
|
- /* This used to be '+= howlong.sec' but, if the time changed say 3 years (happened), this function
|
|
|
- * would end up executing all timers for 3 years until it is caught up.
|
|
|
- */
|
|
|
- timer->trigger_time.sec = now.sec + timer->howlong.sec;
|
|
|
- timer->trigger_time.usec = now.usec + timer->howlong.usec;
|
|
|
-
|
|
|
- if (timer->trigger_time.usec >= 1000000) {
|
|
|
- timer->trigger_time.usec -= 1000000;
|
|
|
- ++(timer->trigger_time.sec);
|
|
|
- }
|
|
|
+static void process_timer(egg_timer_t* timer) {
|
|
|
+ TimerFunc callback = timer->callback;
|
|
|
+ void *client_data = timer->client_data;
|
|
|
+
|
|
|
+ if (timer->flags & TIMER_REPEAT) {
|
|
|
+ /* Update timer. */
|
|
|
+ /* This used to be '+= howlong.sec' but, if the time changed say 3 years (happened), this function
|
|
|
+ * would end up executing all timers for 3 years until it is caught up.
|
|
|
+ */
|
|
|
+ timer->trigger_time.sec = now.sec + timer->howlong.sec;
|
|
|
+ timer->trigger_time.usec = now.usec + timer->howlong.usec;
|
|
|
+
|
|
|
+ if (timer->trigger_time.usec >= 1000000) {
|
|
|
+ timer->trigger_time.usec -= 1000000;
|
|
|
+ ++(timer->trigger_time.sec);
|
|
|
+ }
|
|
|
|
|
|
- /* Add it back into the list. */
|
|
|
- timer_add_to_list(timer);
|
|
|
+ ++(timer->called);
|
|
|
+ } else {
|
|
|
+ if (timer->name)
|
|
|
+ free(timer->name);
|
|
|
+ free(timer);
|
|
|
+ }
|
|
|
|
|
|
- ++(timer->called);
|
|
|
- }
|
|
|
- else {
|
|
|
- if (timer->name) free(timer->name);
|
|
|
- free(timer);
|
|
|
- }
|
|
|
+ callback(client_data);
|
|
|
+}
|
|
|
|
|
|
- callback(client_data);
|
|
|
+static void process_timer_list(egg_timer_t *timer_list) {
|
|
|
+ egg_timer_t *timer = NULL, *next = timer_list;
|
|
|
+ while (next) {
|
|
|
+ timer = next;
|
|
|
+ // Timers are sorted by lowest->highest, so if the current one isn't ready to trigger, the rest are not either
|
|
|
+ if (timer->trigger_time.sec > now.sec || (timer->trigger_time.sec == now.sec && timer->trigger_time.usec > now.usec))
|
|
|
+ break;
|
|
|
+ next = timer->next;
|
|
|
+ process_timer(timer);
|
|
|
}
|
|
|
- return(0);
|
|
|
+}
|
|
|
+
|
|
|
+void timer_run()
|
|
|
+{
|
|
|
+ process_timer_list(timer_once_head);
|
|
|
+ process_timer_list(timer_repeat_head);
|
|
|
}
|
|
|
|
|
|
int timer_list(int **ids)
|
|
|
@@ -267,12 +281,12 @@ int timer_list(int **ids)
|
|
|
int ntimers = 0;
|
|
|
|
|
|
/* Count timers. */
|
|
|
- for (timer = timer_list_head; timer; timer = timer->next) ntimers++;
|
|
|
+ for (timer = timer_repeat_head; timer; timer = timer->next) ntimers++;
|
|
|
|
|
|
/* Fill in array. */
|
|
|
*ids = (int *) my_calloc(1, sizeof(int) * (ntimers+1));
|
|
|
ntimers = 0;
|
|
|
- for (timer = timer_list_head; timer; timer = timer->next) {
|
|
|
+ for (timer = timer_repeat_head; timer; timer = timer->next) {
|
|
|
(*ids)[ntimers++] = timer->id;
|
|
|
}
|
|
|
return(ntimers);
|
|
|
@@ -282,7 +296,7 @@ int timer_info(int id, char **name, egg_timeval_t *initial_len, egg_timeval_t *t
|
|
|
{
|
|
|
egg_timer_t *timer = NULL;
|
|
|
|
|
|
- for (timer = timer_list_head; timer; timer = timer->next) {
|
|
|
+ for (timer = timer_repeat_head; timer; timer = timer->next) {
|
|
|
if (timer->id == id) break;
|
|
|
}
|
|
|
if (!timer) return(-1);
|