GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/mrouted/callout.c Lines: 0 71 0.0 %
Date: 2017-11-13 Branches: 0 36 0.0 %

Line Branch Exec Source
1
/*	$NetBSD: callout.c,v 1.3 1995/12/10 10:06:56 mycroft Exp $	*/
2
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.
7
 *
8
 * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
9
 * Leland Stanford Junior University.
10
 */
11
12
#include "defs.h"
13
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 */
17
18
static int in_callout = 0;
19
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*/
26
};
27
28
#ifdef IGMP_DEBUG
29
static void print_Q(void);
30
#else
31
#define	print_Q()
32
#endif
33
34
void
35
callout_init(void)
36
{
37
    Q = (struct timeout_q *) 0;
38
}
39
40
41
/*
42
 * signal handler for SIGALARM that is called once every second
43
 */
44
void
45
age_callout_queue(void)
46
{
47
    struct timeout_q *ptr;
48
49
    if (in_callout)
50
	return;
51
52
    in_callout = 1;
53
    ptr = Q;
54
55
    while (ptr) {
56
	if (!ptr->time) {
57
	    /* timeout has happened */
58
	    Q = Q->next;
59
60
	    in_callout = 0;
61
	    if (ptr->func)
62
		ptr->func(ptr->data);
63
	    in_callout = 1;
64
65
	    free(ptr);
66
	    ptr = Q;
67
	}
68
	else {
69
	    ptr->time --;
70
#ifdef IGMP_DEBUG
71
	    logit(LOG_DEBUG,0,"[callout, age_callout_queue] -- time (%d)", ptr->time);
72
#endif /* IGMP_DEBUG */
73
	    in_callout = 0; return;
74
	}
75
    }
76
    in_callout = 0;
77
    return;
78
}
79
80
81
/*
82
 * sets the timer
83
 * delay	number of units for timeout
84
 * action	function to be called on timeout
85
 * data		what to call the timeout function with
86
 */
87
int
88
timer_setTimer(int delay, cfunc_t action, char *data)
89
{
90
    struct     timeout_q  *ptr, *node, *prev;
91
92
    if (in_callout)
93
	return -1;
94
95
    in_callout = 1;
96
97
    /* create a node */
98
    node = malloc(sizeof(struct timeout_q));
99
    if (node == 0) {
100
	logit(LOG_WARNING, 0, "Malloc Failed in timer_settimer\n");
101
	in_callout = 0;
102
	return -1;
103
    }
104
    node->func = action;
105
    node->data = data;
106
    node->time = delay;
107
    node->next = 0;
108
    node->id   = ++id;
109
110
    prev = ptr = Q;
111
112
    /* insert node in the queue */
113
114
    /* if the queue is empty, insert the node and return */
115
    if (!Q)
116
	Q = node;
117
    else {
118
	/* chase the pointer looking for the right place */
119
	while (ptr) {
120
121
	    if (delay < ptr->time) {
122
		/* right place */
123
124
		node->next = ptr;
125
		if (ptr == Q)
126
		    Q = node;
127
		else
128
		    prev->next = node;
129
		ptr->time -= node->time;
130
		print_Q();
131
		in_callout = 0;
132
		return node->id;
133
	    } else  {
134
		/* keep moving */
135
136
		delay -= ptr->time; node->time = delay;
137
		prev = ptr;
138
		ptr = ptr->next;
139
	    }
140
	}
141
	prev->next = node;
142
    }
143
    print_Q();
144
    in_callout = 0;
145
    return node->id;
146
}
147
148
149
/* clears the associated timer */
150
void
151
timer_clearTimer(int timer_id)
152
{
153
    struct timeout_q  *ptr, *prev;
154
155
    if (in_callout)
156
        return;
157
    if (!timer_id)
158
	return;
159
160
    in_callout = 1;
161
162
    prev = ptr = Q;
163
164
    /*
165
     * find the right node, delete it. the subsequent node's time
166
     * gets bumped up
167
     */
168
169
    print_Q();
170
    while (ptr) {
171
	if (ptr->id == timer_id) {
172
	    /* got the right node */
173
174
	    /* unlink it from the queue */
175
	    if (ptr == Q)
176
		Q = Q->next;
177
	    else
178
		prev->next = ptr->next;
179
180
	    /* increment next node if any */
181
	    if (ptr->next != 0)
182
		(ptr->next)->time += ptr->time;
183
184
	    free(ptr->data);
185
	    free(ptr);
186
	    print_Q();
187
	    in_callout = 0;
188
	    return;
189
	}
190
	prev = ptr;
191
	ptr = ptr->next;
192
    }
193
    print_Q();
194
    in_callout = 0;
195
}
196
197
#ifdef IGMP_DEBUG
198
/*
199
 * debugging utility
200
 */
201
static void
202
print_Q(void)
203
{
204
    struct timeout_q  *ptr;
205
206
    for(ptr = Q; ptr; ptr = ptr->next)
207
	logit(LOG_DEBUG,0,"(%d,%d) ", ptr->id, ptr->time);
208
}
209
#endif /* IGMP_DEBUG */
210
211
int
212
secs_remaining(int timer_id)
213
{
214
    struct timeout_q  *ptr;
215
    int left=0;
216
217
    for (ptr = Q; ptr && ptr->id != timer_id; ptr = ptr->next)
218
       left += ptr->time;
219
220
    if (!ptr) /* not found */
221
       return 0;
222
223
    return left + ptr->time;
224
}