]>
git.saurik.com Git - apple/network_cmds.git/blob - rtadvd.tproj/timer.c
b03b4bf2012cb4a3e329d0f18d05dc2ace46d436
1 /* $KAME: timer.c,v 1.9 2002/06/10 19:59:47 itojun Exp $ */
4 * Copyright (C) 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 static struct rtadvd_timer timer_head
;
43 #define MILLION 1000000
44 #define TIMEVAL_EQUAL(t1,t2) ((t1)->tv_sec == (t2)->tv_sec &&\
45 (t1)->tv_usec == (t2)->tv_usec)
47 static struct timeval tm_max
= {0x7fffffff, 0x7fffffff};
52 memset(&timer_head
, 0, sizeof(timer_head
));
54 timer_head
.next
= timer_head
.prev
= &timer_head
;
55 timer_head
.tm
= tm_max
;
59 rtadvd_add_timer(struct rtadvd_timer
*(*timeout
)(void *),
60 void (*update
)(void *, struct timeval
*),
61 void *timeodata
, void *updatedata
)
63 struct rtadvd_timer
*newtimer
;
65 if ((newtimer
= malloc(sizeof(*newtimer
))) == NULL
) {
67 "<%s> can't allocate memory", __func__
);
71 memset(newtimer
, 0, sizeof(*newtimer
));
73 if (timeout
== NULL
) {
75 "<%s> timeout function unspecified", __func__
);
78 newtimer
->expire
= timeout
;
79 newtimer
->update
= update
;
80 newtimer
->expire_data
= timeodata
;
81 newtimer
->update_data
= updatedata
;
82 newtimer
->tm
= tm_max
;
85 insque(newtimer
, &timer_head
);
91 rtadvd_remove_timer(struct rtadvd_timer
**timer
)
99 rtadvd_set_timer(struct timeval
*tm
, struct rtadvd_timer
*timer
)
103 /* reset the timer */
104 gettimeofday(&now
, NULL
);
106 TIMEVAL_ADD(&now
, tm
, &timer
->tm
);
108 /* update the next expiration time */
109 if (TIMEVAL_LT(timer
->tm
, timer_head
.tm
))
110 timer_head
.tm
= timer
->tm
;
116 * Check expiration for each timer. If a timer expires,
117 * call the expire function for the timer and update the timer.
118 * Return the next interval for select() call.
123 static struct timeval returnval
;
125 struct rtadvd_timer
*tm
= timer_head
.next
, *tm_next
;
127 gettimeofday(&now
, NULL
);
129 timer_head
.tm
= tm_max
;
131 for (tm
= timer_head
.next
; tm
!= &timer_head
; tm
= tm_next
) {
134 if (TIMEVAL_LEQ(tm
->tm
, now
)) {
135 if (((*tm
->expire
)(tm
->expire_data
) == NULL
))
136 continue; /* the timer was removed */
138 (*tm
->update
)(tm
->update_data
, &tm
->tm
);
139 TIMEVAL_ADD(&tm
->tm
, &now
, &tm
->tm
);
142 if (TIMEVAL_LT(tm
->tm
, timer_head
.tm
))
143 timer_head
.tm
= tm
->tm
;
146 if (TIMEVAL_EQUAL(&tm_max
, &timer_head
.tm
)) {
147 /* no need to timeout */
149 } else if (TIMEVAL_LT(timer_head
.tm
, now
)) {
150 /* this may occur when the interval is too small */
151 returnval
.tv_sec
= returnval
.tv_usec
= 0;
153 TIMEVAL_SUB(&timer_head
.tm
, &now
, &returnval
);
158 rtadvd_timer_rest(struct rtadvd_timer
*timer
)
160 static struct timeval returnval
, now
;
162 gettimeofday(&now
, NULL
);
163 if (TIMEVAL_LEQ(timer
->tm
, now
)) {
165 "<%s> a timer must be expired, but not yet",
167 returnval
.tv_sec
= returnval
.tv_usec
= 0;
170 TIMEVAL_SUB(&timer
->tm
, &now
, &returnval
);
177 TIMEVAL_ADD(struct timeval
*a
, struct timeval
*b
, struct timeval
*result
)
181 if ((l
= a
->tv_usec
+ b
->tv_usec
) < MILLION
) {
183 result
->tv_sec
= a
->tv_sec
+ b
->tv_sec
;
186 result
->tv_usec
= l
- MILLION
;
187 result
->tv_sec
= a
->tv_sec
+ b
->tv_sec
+ 1;
193 * XXX: this function assumes that a >= b.
196 TIMEVAL_SUB(struct timeval
*a
, struct timeval
*b
, struct timeval
*result
)
200 if ((l
= a
->tv_usec
- b
->tv_usec
) >= 0) {
202 result
->tv_sec
= a
->tv_sec
- b
->tv_sec
;
205 result
->tv_usec
= MILLION
+ l
;
206 result
->tv_sec
= a
->tv_sec
- b
->tv_sec
- 1;