2 ** igmpproxy - IGMP proxy based multicast router
3 ** Copyright (C) 2005 Johnny Egeland <johnny@rlo.org>
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 **----------------------------------------------------------------------------
21 ** This software is derived work from the following software. The original
22 ** source code has been modified from it's original state by the author
25 ** smcroute 0.92 - Copyright (C) 2001 Carsten Schill <carsten@cschill.de>
26 ** - Licensed under the GNU General Public License, version 2
28 ** mrouted 3.9-beta3 - COPYRIGHT 1989 by The Board of Trustees of
29 ** Leland Stanford Junior University.
30 ** - Original license can be found in the Stanford.txt file.
35 #include "igmpproxy.h"
37 /* the code below implements a callout queue */
39 static struct timeOutQueue
*queue
= 0; /* pointer to the beginning of timeout queue */
42 struct timeOutQueue
*next
; // Next event in queue
44 timer_f func
; // function to call
45 void *data
; // Data for function
46 int time
; // Time offset for next event
49 // Method for dumping the Queue to the log.
50 static void debugQueue(void);
53 * Initializes the callout queue
60 * Clears all scheduled timeouts...
62 void free_all_callouts() {
63 struct timeOutQueue
*p
;
74 * elapsed_time seconds have passed; perform all the events that should
77 void age_callout_queue(int elapsed_time
) {
78 struct timeOutQueue
*ptr
;
79 struct timeOutQueue
*_queue
= NULL
;
80 struct timeOutQueue
*last
= NULL
;
83 for (ptr
= queue
; ptr
; ptr
= ptr
->next
) {
84 if (ptr
->time
> elapsed_time
) {
85 ptr
->time
-= elapsed_time
;
88 elapsed_time
-= ptr
->time
;
100 /* process existing events */
101 for (ptr
= _queue
; ptr
; ptr
= _queue
, i
++) {
102 _queue
= _queue
->next
;
103 my_log(LOG_DEBUG
, 0, "About to call timeout %d (#%d)", ptr
->id
, i
);
105 ptr
->func(ptr
->data
);
111 * Return in how many seconds age_callout_queue() would like to be called.
112 * Return -1 if there are no events pending.
114 int timer_nextTimer() {
116 if (queue
->time
< 0) {
117 my_log(LOG_WARNING
, 0, "timer_nextTimer top of queue says %d",
127 * Inserts a timer in queue.
128 * @param delay - Number of seconds the timeout should happen in.
129 * @param action - The function to call on timeout.
130 * @param data - Pointer to the function data to supply...
132 int timer_setTimer(int delay
, timer_f action
, void *data
) {
133 struct timeOutQueue
*ptr
, *node
, *prev
;
137 node
= (struct timeOutQueue
*)malloc(sizeof(struct timeOutQueue
));
139 my_log(LOG_WARNING
, 0, "Malloc Failed in timer_settimer\n");
150 /* insert node in the queue */
152 /* if the queue is empty, insert the node and return */
157 /* chase the pointer looking for the right place */
159 if (delay
< ptr
->time
) {
160 // We found the correct node
168 ptr
->time
-= node
->time
;
170 "Created timeout %d (#%d) - delay %d secs",
171 node
->id
, i
, node
->time
);
175 // Continur to check nodes.
176 delay
-= ptr
->time
; node
->time
= delay
;
184 my_log(LOG_DEBUG
, 0, "Created timeout %d (#%d) - delay %d secs",
185 node
->id
, i
, node
->time
);
192 * returns the time until the timer is scheduled
194 int timer_leftTimer(int timer_id
) {
195 struct timeOutQueue
*ptr
;
201 for (ptr
= queue
; ptr
; ptr
= ptr
->next
) {
203 if (ptr
->id
== timer_id
) {
211 * clears the associated timer. Returns 1 if succeeded.
213 int timer_clearTimer(int timer_id
) {
214 struct timeOutQueue
*ptr
, *prev
;
223 * find the right node, delete it. the subsequent node's time
229 if (ptr
->id
== timer_id
) {
230 /* got the right node */
232 /* unlink it from the queue */
236 prev
->next
= ptr
->next
;
238 /* increment next node if any */
240 (ptr
->next
)->time
+= ptr
->time
;
244 my_log(LOG_DEBUG
, 0, "deleted timer %d (#%d)", ptr
->id
, i
);
253 // If we get here, the timer was not deleted.
254 my_log(LOG_DEBUG
, 0, "failed to delete timer %d (#%d)", timer_id
, i
);
262 static void debugQueue() {
263 struct timeOutQueue
*ptr
;
265 for (ptr
= queue
; ptr
; ptr
= ptr
->next
) {
266 my_log(LOG_DEBUG
, 0, "(Id:%d, Time:%d) ", ptr
->id
, ptr
->time
);