summaryrefslogtreecommitdiff
path: root/usr.sbin/mrouted/callout.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/mrouted/callout.c')
-rw-r--r--usr.sbin/mrouted/callout.c156
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;
-}