2 * The mrouted program is covered by the license in the accompanying file
3 * named "LICENSE". Use of the mrouted program represents acceptance of
4 * the terms and conditions listed in that file.
6 * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
7 * Leland Stanford Junior University.
10 * callout.c,v 3.8.4.8 1998/01/06 01:58:45 fenner Exp
12 * $FreeBSD: src/usr.sbin/mrouted/callout.c,v 1.12 1999/08/28 01:17:03 peter Exp $
13 * $DragonFly: src/usr.sbin/mrouted/callout.c,v 1.4 2003/11/22 11:38:13 eirikn Exp $
18 /* the code below implements a callout queue */
20 static struct timeout_q *Q = 0; /* pointer to the beginning of timeout queue */
23 struct timeout_q *next; /* next event */
25 cfunc_t func; /* function to call */
26 void *data; /* func's data */
27 int time; /* time offset to next event*/
31 static void print_Q(void);
39 Q = (struct timeout_q *) 0;
43 free_all_callouts(void)
56 * elapsed_time seconds have passed; perform all the events that should
60 age_callout_queue(int elapsed_time)
62 struct timeout_q *ptr;
65 for (ptr = Q; ptr; ptr = Q, i++) {
66 if (ptr->time > elapsed_time) {
67 ptr->time -= elapsed_time;
70 elapsed_time -= ptr->time;
72 IF_DEBUG(DEBUG_TIMEOUT)
73 log(LOG_DEBUG, 0, "about to call timeout %d (#%d)", ptr->id, i);
82 * Return in how many seconds age_callout_queue() would like to be called.
83 * Return -1 if there are no events pending.
90 log(LOG_WARNING, 0, "timer_nextTimer top of queue says %d",
103 timer_setTimer(delay, action, data)
104 int delay; /* number of units for timeout */
105 cfunc_t action; /* function to be called on timeout */
106 void *data; /* what to call the timeout function with */
108 struct timeout_q *ptr, *node, *prev;
112 node = (struct timeout_q *)malloc(sizeof(struct timeout_q));
114 log(LOG_WARNING, 0, "Malloc Failed in timer_settimer\n");
125 /* insert node in the queue */
127 /* if the queue is empty, insert the node and return */
131 /* chase the pointer looking for the right place */
134 if (delay < ptr->time) {
142 ptr->time -= node->time;
144 IF_DEBUG(DEBUG_TIMEOUT)
145 log(LOG_DEBUG, 0, "created timeout %d (#%d)", node->id, i);
150 delay -= ptr->time; node->time = delay;
159 IF_DEBUG(DEBUG_TIMEOUT)
160 log(LOG_DEBUG, 0, "created timeout %d (#%d)", node->id, i);
164 /* returns the time until the timer is scheduled */
166 timer_leftTimer(timer_id)
169 struct timeout_q *ptr;
175 for (ptr = Q; ptr; ptr = ptr->next) {
177 if (ptr->id == timer_id)
183 /* clears the associated timer. Returns 1 if succeeded. */
185 timer_clearTimer(timer_id)
188 struct timeout_q *ptr, *prev;
197 * find the right node, delete it. the subsequent node's time
203 if (ptr->id == timer_id) {
204 /* got the right node */
206 /* unlink it from the queue */
210 prev->next = ptr->next;
212 /* increment next node if any */
214 (ptr->next)->time += ptr->time;
218 IF_DEBUG(DEBUG_TIMEOUT)
219 log(LOG_DEBUG, 0, "deleted timer %d (#%d)", ptr->id, i);
228 IF_DEBUG(DEBUG_TIMEOUT)
229 log(LOG_DEBUG, 0, "failed to delete timer %d (#%d)", timer_id, i);
241 struct timeout_q *ptr;
243 IF_DEBUG(DEBUG_TIMEOUT)
244 for (ptr = Q; ptr; ptr = ptr->next)
245 log(LOG_DEBUG, 0, "(%d,%d) ", ptr->id, ptr->time);
247 #endif /* IGMP_DEBUG */