diff options
Diffstat (limited to 'usr.sbin/mrouted/callout.c')
-rw-r--r-- | usr.sbin/mrouted/callout.c | 156 |
1 files changed, 90 insertions, 66 deletions
diff --git a/usr.sbin/mrouted/callout.c b/usr.sbin/mrouted/callout.c index 358c7ae86a210..fe23170b06756 100644 --- a/usr.sbin/mrouted/callout.c +++ b/usr.sbin/mrouted/callout.c @@ -7,22 +7,25 @@ * Leland Stanford Junior University. * * - * $Id: callout.c,v 3.8 1995/11/29 22:36:57 fenner Rel $ + * callout.c,v 3.8.4.8 1998/01/06 01:58:45 fenner Exp */ #include "defs.h" +#ifndef lint +static char rcsid[] = "@(#) $Id: \ +callout.c,v 3.8.4.8 1998/01/06 01:58:45 fenner Exp $"; +#endif + /* the code below implements a callout queue */ static int id = 0; static struct timeout_q *Q = 0; /* pointer to the beginning of timeout queue */ -static int in_callout = 0; - struct timeout_q { struct timeout_q *next; /* next event */ int id; cfunc_t func; /* function to call */ - char *data; /* func's data */ + void *data; /* func's data */ int time; /* time offset to next event*/ }; @@ -38,46 +41,63 @@ callout_init() Q = (struct timeout_q *) 0; } +void +free_all_callouts() +{ + struct timeout_q *p; + + while (Q) { + p = Q; + Q = Q->next; + free(p); + } +} + /* - * signal handler for SIGALARM that is called once every second + * elapsed_time seconds have passed; perform all the events that should + * happen. */ void -age_callout_queue() +age_callout_queue(elapsed_time) + int elapsed_time; { struct timeout_q *ptr; - - if (in_callout) - return; + int i = 0; - in_callout = 1; - ptr = Q; - - while (ptr) { - if (!ptr->time) { - /* timeout has happened */ + for (ptr = Q; ptr; ptr = Q, i++) { + if (ptr->time > elapsed_time) { + ptr->time -= elapsed_time; + return; + } else { + elapsed_time -= ptr->time; Q = Q->next; - - in_callout = 0; + IF_DEBUG(DEBUG_TIMEOUT) + log(LOG_DEBUG, 0, "about to call timeout %d (#%d)", ptr->id, i); if (ptr->func) ptr->func(ptr->data); - in_callout = 1; - free(ptr); - ptr = Q; - } - else { - ptr->time --; -#ifdef IGMP_DEBUG - log(LOG_DEBUG,0,"[callout, age_callout_queue] -- time (%d)", ptr->time); -#endif /* IGMP_DEBUG */ - in_callout = 0; return; } } - in_callout = 0; - return; } +/* + * Return in how many seconds age_callout_queue() would like to be called. + * Return -1 if there are no events pending. + */ +int +timer_nextTimer() +{ + if (Q) { + if (Q->time < 0) { + log(LOG_WARNING, 0, "timer_nextTimer top of queue says %d", + Q->time); + return 0; + } + return Q->time; + } + return -1; +} /* * sets the timer @@ -86,20 +106,15 @@ int timer_setTimer(delay, action, data) int delay; /* number of units for timeout */ cfunc_t action; /* function to be called on timeout */ - char *data; /* what to call the timeout function with */ + void *data; /* what to call the timeout function with */ { struct timeout_q *ptr, *node, *prev; - - if (in_callout) - return -1; - - in_callout = 1; + int i = 0; /* create a node */ node = (struct timeout_q *)malloc(sizeof(struct timeout_q)); if (node == 0) { log(LOG_WARNING, 0, "Malloc Failed in timer_settimer\n"); - in_callout = 0; return -1; } node->func = action; @@ -129,7 +144,8 @@ timer_setTimer(delay, action, data) prev->next = node; ptr->time -= node->time; print_Q(); - in_callout = 0; + IF_DEBUG(DEBUG_TIMEOUT) + log(LOG_DEBUG, 0, "created timeout %d (#%d)", node->id, i); return node->id; } else { /* keep moving */ @@ -138,29 +154,46 @@ timer_setTimer(delay, action, data) prev = ptr; ptr = ptr->next; } + i++; } prev->next = node; } print_Q(); - in_callout = 0; + IF_DEBUG(DEBUG_TIMEOUT) + log(LOG_DEBUG, 0, "created timeout %d (#%d)", node->id, i); return node->id; } +/* returns the time until the timer is scheduled */ +int +timer_leftTimer(timer_id) + int timer_id; +{ + struct timeout_q *ptr; + int left = 0; + + if (!timer_id) + return -1; -/* clears the associated timer */ -void + for (ptr = Q; ptr; ptr = ptr->next) { + left += ptr->time; + if (ptr->id == timer_id) + return left; + } + return -1; +} + +/* clears the associated timer. Returns 1 if succeeded. */ +int timer_clearTimer(timer_id) int timer_id; { struct timeout_q *ptr, *prev; + int i = 0; - if (in_callout) - return; if (!timer_id) - return; + return 0; - in_callout = 1; - prev = ptr = Q; /* @@ -183,17 +216,22 @@ timer_clearTimer(timer_id) if (ptr->next != 0) (ptr->next)->time += ptr->time; - free(ptr->data); + if (ptr->data) + free(ptr->data); + IF_DEBUG(DEBUG_TIMEOUT) + log(LOG_DEBUG, 0, "deleted timer %d (#%d)", ptr->id, i); free(ptr); print_Q(); - in_callout = 0; - return; + return 1; } prev = ptr; ptr = ptr->next; + i++; } + IF_DEBUG(DEBUG_TIMEOUT) + log(LOG_DEBUG, 0, "failed to delete timer %d (#%d)", timer_id, i); print_Q(); - in_callout = 0; + return 0; } #ifdef IGMP_DEBUG @@ -205,22 +243,8 @@ print_Q() { struct timeout_q *ptr; - for(ptr = Q; ptr; ptr = ptr->next) - log(LOG_DEBUG,0,"(%d,%d) ", ptr->id, ptr->time); + IF_DEBUG(DEBUG_TIMEOUT) + for (ptr = Q; ptr; ptr = ptr->next) + log(LOG_DEBUG, 0, "(%d,%d) ", ptr->id, ptr->time); } #endif /* IGMP_DEBUG */ -int -secs_remaining( timer_id) - int timer_id; -{ - struct timeout_q *ptr; - int left=0; - - for (ptr = Q; ptr && ptr->id != timer_id; ptr = ptr->next) - left += ptr->time; - - if (!ptr) /* not found */ - return 0; - - return left + ptr->time; -} |