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.6 2008/04/20 19:26:53 swildner 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",
102 * delay - number of units for timeout
103 * action - function to be called on timeout
104 * data - what to call the timeout function with
107 timer_setTimer(int delay
, cfunc_t action
, void *data
)
109 struct timeout_q
*ptr
, *node
, *prev
;
113 node
= (struct timeout_q
*)malloc(sizeof(struct timeout_q
));
115 log(LOG_WARNING
, 0, "Malloc Failed in timer_setTimer\n");
126 /* insert node in the queue */
128 /* if the queue is empty, insert the node and return */
132 /* chase the pointer looking for the right place */
135 if (delay
< ptr
->time
) {
143 ptr
->time
-= node
->time
;
145 IF_DEBUG(DEBUG_TIMEOUT
)
146 log(LOG_DEBUG
, 0, "created timeout %d (#%d)", node
->id
, i
);
151 delay
-= ptr
->time
; node
->time
= delay
;
160 IF_DEBUG(DEBUG_TIMEOUT
)
161 log(LOG_DEBUG
, 0, "created timeout %d (#%d)", node
->id
, i
);
165 /* returns the time until the timer is scheduled */
167 timer_leftTimer(int 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(int timer_id
)
187 struct timeout_q
*ptr
, *prev
;
196 * find the right node, delete it. the subsequent node's time
202 if (ptr
->id
== timer_id
) {
203 /* got the right node */
205 /* unlink it from the queue */
209 prev
->next
= ptr
->next
;
211 /* increment next node if any */
213 (ptr
->next
)->time
+= ptr
->time
;
217 IF_DEBUG(DEBUG_TIMEOUT
)
218 log(LOG_DEBUG
, 0, "deleted timer %d (#%d)", ptr
->id
, i
);
227 IF_DEBUG(DEBUG_TIMEOUT
)
228 log(LOG_DEBUG
, 0, "failed to delete timer %d (#%d)", timer_id
, i
);
240 struct timeout_q
*ptr
;
242 IF_DEBUG(DEBUG_TIMEOUT
)
243 for (ptr
= Q
; ptr
; ptr
= ptr
->next
)
244 log(LOG_DEBUG
, 0, "(%d,%d) ", ptr
->id
, ptr
->time
);
246 #endif /* IGMP_DEBUG */