summaryrefslogtreecommitdiff
path: root/usr.sbin/mrouted/callout.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /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.c201
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
+}
+