Expand PMF_FN_* macros.
[netbsd-mini2440.git] / usr.sbin / mrouted / callout.c
blob4b76d29a8ec0b3be86ba8cc26b52b4fa2a82a8ac
1 /* $NetBSD: callout.c,v 1.2 2002/12/06 16:02:55 thorpej Exp $ */
3 /*
4 * The mrouted program is covered by the license in the accompanying file
5 * named "LICENSE". Use of the mrouted program represents acceptance of
6 * the terms and conditions listed in that file.
8 * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
9 * Leland Stanford Junior University.
12 #include "defs.h"
14 /* the code below implements a callout queue */
15 static int id = 0;
16 static struct timeout_q *Q = 0; /* pointer to the beginning of timeout queue */
18 static int in_callout = 0;
20 struct timeout_q {
21 struct timeout_q *next; /* next event */
22 int id;
23 cfunc_t func; /* function to call */
24 char *data; /* func's data */
25 int time; /* time offset to next event*/
28 #ifdef IGMP_DEBUG
29 static void print_Q(void);
30 #else
31 #define print_Q()
32 #endif
34 int secs_remaining(int);
36 void
37 callout_init(void)
39 Q = (struct timeout_q *) 0;
44 * signal handler for SIGALARM that is called once every second
46 void
47 age_callout_queue(void)
49 struct timeout_q *ptr;
51 if (in_callout)
52 return;
54 in_callout = 1;
55 ptr = Q;
57 while (ptr) {
58 if (!ptr->time) {
59 /* timeout has happened */
60 Q = Q->next;
62 in_callout = 0;
63 if (ptr->func)
64 ptr->func(ptr->data);
65 in_callout = 1;
67 free(ptr);
68 ptr = Q;
70 else {
71 ptr->time --;
72 #ifdef IGMP_DEBUG
73 logit(LOG_DEBUG,0,"[callout, age_callout_queue] -- time (%d)", ptr->time);
74 #endif /* IGMP_DEBUG */
75 in_callout = 0; return;
78 in_callout = 0;
79 return;
83 /*
84 * sets the timer
86 * delay: number of units for timeout
87 * action: function to be called on timeout
88 * data: what to call the timeout function with
90 int
91 timer_setTimer(int delay, cfunc_t action, char *data)
93 struct timeout_q *ptr, *node, *prev;
95 if (in_callout)
96 return -1;
98 in_callout = 1;
100 /* create a node */
101 node = (struct timeout_q *)malloc(sizeof(struct timeout_q));
102 if (node == 0) {
103 logit(LOG_WARNING, 0, "Malloc Failed in timer_settimer\n");
104 in_callout = 0;
105 return -1;
107 node->func = action;
108 node->data = data;
109 node->time = delay;
110 node->next = 0;
111 node->id = ++id;
113 prev = ptr = Q;
115 /* insert node in the queue */
117 /* if the queue is empty, insert the node and return */
118 if (!Q)
119 Q = node;
120 else {
121 /* chase the pointer looking for the right place */
122 while (ptr) {
124 if (delay < ptr->time) {
125 /* right place */
127 node->next = ptr;
128 if (ptr == Q)
129 Q = node;
130 else
131 prev->next = node;
132 ptr->time -= node->time;
133 print_Q();
134 in_callout = 0;
135 return node->id;
136 } else {
137 /* keep moving */
139 delay -= ptr->time; node->time = delay;
140 prev = ptr;
141 ptr = ptr->next;
144 prev->next = node;
146 print_Q();
147 in_callout = 0;
148 return node->id;
152 /* clears the associated timer */
153 void
154 timer_clearTimer(int timer_id)
156 struct timeout_q *ptr, *prev;
158 if (in_callout)
159 return;
160 if (!timer_id)
161 return;
163 in_callout = 1;
165 prev = ptr = Q;
168 * find the right node, delete it. the subsequent node's time
169 * gets bumped up
172 print_Q();
173 while (ptr) {
174 if (ptr->id == timer_id) {
175 /* got the right node */
177 /* unlink it from the queue */
178 if (ptr == Q)
179 Q = Q->next;
180 else
181 prev->next = ptr->next;
183 /* increment next node if any */
184 if (ptr->next != 0)
185 (ptr->next)->time += ptr->time;
187 free(ptr->data);
188 free(ptr);
189 print_Q();
190 in_callout = 0;
191 return;
193 prev = ptr;
194 ptr = ptr->next;
196 print_Q();
197 in_callout = 0;
200 #ifdef IGMP_DEBUG
202 * debugging utility
204 static void
205 print_Q(void)
207 struct timeout_q *ptr;
209 for(ptr = Q; ptr; ptr = ptr->next)
210 logit(LOG_DEBUG,0,"(%d,%d) ", ptr->id, ptr->time);
212 #endif /* IGMP_DEBUG */
215 secs_remaining(int timer_id)
217 struct timeout_q *ptr;
218 int left=0;
220 for (ptr = Q; ptr && ptr->id != timer_id; ptr = ptr->next)
221 left += ptr->time;
223 if (!ptr) /* not found */
224 return 0;
226 return left + ptr->time;