9 #include "main/select.h"
10 #include "main/timer.h"
11 #include "util/error.h"
12 #include "util/lists.h"
13 #include "util/memory.h"
14 #include "util/time.h"
18 LIST_HEAD(struct timer
);
25 /* @timers.next points to the timer with the smallest interval,
26 * @timers.next->next to the second smallest, and so on. */
27 static INIT_LIST_OF(struct timer
, timers
);
30 get_timers_count(void)
32 return list_size(&timers
);
37 check_timers(timeval_T
*last_time
)
44 timeval_sub(&interval
, last_time
, &now
);
46 foreach (timer
, timers
) {
47 timeval_sub_interval(&timer
->interval
, &interval
);
50 while (!list_empty(timers
)) {
53 if (timeval_is_positive(&timer
->interval
))
57 /* At this point, *@timer is to be considered invalid
58 * outside timers.c; if anything e.g. passes it to
59 * @kill_timer, that's a bug. However, @timer->func
60 * and @check_bottom_halves can still call @kill_timer
61 * on other timers, so this loop must be careful not to
62 * keep pointers to them. (bug 868) */
63 timer
->func(timer
->data
);
65 check_bottom_halves();
68 timeval_copy(last_time
, &now
);
71 /* Install a timer that calls @func(@data) after @delay milliseconds.
72 * Store to *@id either the ID of the new timer, or TIMER_ID_UNDEF if
73 * the timer cannot be installed. (This function ignores the previous
74 * value of *@id in any case.)
76 * When @func is called, the timer ID has become invalid. @func
77 * should erase the expired timer ID from all variables, so that
78 * there's no chance it will be given to @kill_timer later. */
80 install_timer(timer_id_T
*id
, milliseconds_T delay
, void (*func
)(void *), void *data
)
82 struct timer
*new_timer
, *timer
;
84 assert(id
&& delay
> 0);
86 new_timer
= mem_alloc(sizeof(*new_timer
));
87 *id
= (timer_id_T
) new_timer
; /* TIMER_ID_UNDEF is NULL */
88 if (!new_timer
) return;
90 timeval_from_milliseconds(&new_timer
->interval
, delay
);
91 new_timer
->func
= func
;
92 new_timer
->data
= data
;
94 foreach (timer
, timers
) {
95 if (timeval_cmp(&timer
->interval
, &new_timer
->interval
) >= 0)
99 add_at_pos(timer
->prev
, new_timer
);
103 kill_timer(timer_id_T
*id
)
108 if (*id
== TIMER_ID_UNDEF
) return;
111 del_from_list(timer
);
114 *id
= TIMER_ID_UNDEF
;
118 get_next_timer_time(timeval_T
*t
)
120 if (!list_empty(timers
)) {
121 timeval_copy(t
, &((struct timer
*) &timers
)->next
->interval
);