diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /usr.sbin/mrouted/callout.c |
initial import of NetBSD tree
Diffstat (limited to 'usr.sbin/mrouted/callout.c')
-rw-r--r-- | usr.sbin/mrouted/callout.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/usr.sbin/mrouted/callout.c b/usr.sbin/mrouted/callout.c new file mode 100644 index 00000000000..943ace50507 --- /dev/null +++ b/usr.sbin/mrouted/callout.c @@ -0,0 +1,201 @@ +/* $NetBSD: callout.c,v 1.2 1995/10/09 03:51:34 thorpej Exp $ */ + +/* + * The mrouted program is covered by the license in the accompanying file + * named "LICENSE". Use of the mrouted program represents acceptance of + * the terms and conditions listed in that file. + * + * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of + * Leland Stanford Junior University. + */ + +#include "defs.h" + +/* 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; + +typedef void (* cfunc_t)(); + +struct timeout_q { + struct timeout_q *next; /* next event */ + int id; + cfunc_t func ; /* function to call */ + char *data; /* func's data */ + int time; /* time offset to next event*/ +}; + +static void print_Q(); + +void callout_init() +{ + Q = (struct timeout_q *) 0; +} + + +/* + * signal handler for SIGALARM that is called once every second + */ +void age_callout_queue() +{ + struct timeout_q *ptr; + + if (in_callout) + return; + + in_callout = 1; + ptr = Q; + + while (ptr){ + if (!ptr->time ) { + /* timeout has happened */ + if(ptr->func) + ptr->func(ptr->data); + Q = Q->next; + + 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; +} + + +/* + * sets the timer + */ +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 */ +{ + struct timeout_q *ptr, *node, *prev; + + if (in_callout) + return -1; + + in_callout = 1; + + /* 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; + node->data = data; + node->time = delay; + node->next = 0; + node->id = ++id; + + prev = ptr = Q; + + /* insert node in the queue */ + + /* if the queue is empty, insert the node and return */ + if (!Q) + Q = node; + else { + /* chase the pointer looking for the right place */ + while (ptr){ + + if (delay < ptr->time){ + /* right place */ + + node->next = ptr; + if (ptr == Q) + Q = node; + else + prev->next = node; + ptr->time -= node->time; + print_Q(); + in_callout = 0; + return node->id; + } + else { + /* keep moving */ + + delay -= ptr->time; node->time = delay; + prev = ptr; + ptr = ptr->next; + } + } + prev->next = node; + } + print_Q(); + in_callout = 0; + return node->id; +} + + +/* clears the associated timer */ +void timer_clearTimer( timer_id) + int timer_id; +{ + struct timeout_q *ptr, *prev; + + if (in_callout) return; + in_callout = 1; + + + if ( !timer_id ) {in_callout = 0; return;} + + prev = ptr = Q; + + /* + * find the right node, delete it. the subsequent node's time + * gets bumped up + */ + + print_Q(); + while (ptr){ + if (ptr->id == timer_id){ + /* got the right node */ + + /* unlink it from the queue */ + if ( ptr == Q) + Q = Q->next; + else + prev->next = ptr->next; + + /* increment next node if any */ + if (ptr->next != 0) + (ptr->next)->time += ptr->time; + + free(ptr->data); + free(ptr); + print_Q(); + in_callout = 0; + return; + } + prev = ptr; + ptr = ptr->next; + } + print_Q(); + in_callout = 0; +} + +/* + * debugging utility + */ +static void print_Q() +{ +#ifdef IGMP_DEBUG + struct timeout_q *ptr; + + for(ptr = Q; ptr; ptr = ptr->next) + log(LOG_DEBUG,0,"(%d,%d) ", ptr->id, ptr->time); +#endif IGMP_DEBUG +} + |