]>
git.saurik.com Git - apple/network_cmds.git/blob - rtadvd.tproj/timer.c
3134fc03fc0a78b8811ac8bfc8536d4b3976812a
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
39 #include "rtadvd_logging.h"
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
) {
66 errorlog("<%s> can't allocate memory", __func__
);
70 memset(newtimer
, 0, sizeof(*newtimer
));
72 if (timeout
== NULL
) {
73 errorlog("<%s> timeout function unspecified", __func__
);
76 newtimer
->expire
= timeout
;
77 newtimer
->update
= update
;
78 newtimer
->expire_data
= timeodata
;
79 newtimer
->update_data
= updatedata
;
80 newtimer
->tm
= tm_max
;
83 insque(newtimer
, &timer_head
);
89 rtadvd_remove_timer(struct rtadvd_timer
**timer
)
97 rtadvd_set_timer(struct timeval
*tm
, struct rtadvd_timer
*timer
)
101 /* reset the timer */
102 gettimeofday(&now
, NULL
);
104 TIMEVAL_ADD(&now
, tm
, &timer
->tm
);
106 /* update the next expiration time */
107 if (TIMEVAL_LT(timer
->tm
, timer_head
.tm
))
108 timer_head
.tm
= timer
->tm
;
114 * Check expiration for each timer. If a timer expires,
115 * call the expire function for the timer and update the timer.
116 * Return the next interval for select() call.
121 static struct timeval returnval
;
123 struct rtadvd_timer
*tm
= timer_head
.next
, *tm_next
;
125 gettimeofday(&now
, NULL
);
127 timer_head
.tm
= tm_max
;
129 for (tm
= timer_head
.next
; tm
!= &timer_head
; tm
= tm_next
) {
132 if (TIMEVAL_LEQ(tm
->tm
, now
)) {
133 if (((*tm
->expire
)(tm
->expire_data
) == NULL
))
134 continue; /* the timer was removed */
136 (*tm
->update
)(tm
->update_data
, &tm
->tm
);
137 TIMEVAL_ADD(&tm
->tm
, &now
, &tm
->tm
);
140 if (TIMEVAL_LT(tm
->tm
, timer_head
.tm
))
141 timer_head
.tm
= tm
->tm
;
144 if (TIMEVAL_EQUAL(&tm_max
, &timer_head
.tm
)) {
145 /* no need to timeout */
147 } else if (TIMEVAL_LT(timer_head
.tm
, now
)) {
148 /* this may occur when the interval is too small */
149 returnval
.tv_sec
= returnval
.tv_usec
= 0;
151 TIMEVAL_SUB(&timer_head
.tm
, &now
, &returnval
);
156 rtadvd_timer_rest(struct rtadvd_timer
*timer
)
158 static struct timeval returnval
, now
;
160 gettimeofday(&now
, NULL
);
161 if (TIMEVAL_LEQ(timer
->tm
, now
)) {
162 debuglog("<%s> a timer must be expired, but not yet",
164 returnval
.tv_sec
= returnval
.tv_usec
= 0;
167 TIMEVAL_SUB(&timer
->tm
, &now
, &returnval
);
174 TIMEVAL_ADD(struct timeval
*a
, struct timeval
*b
, struct timeval
*result
)
178 if ((l
= a
->tv_usec
+ b
->tv_usec
) < MILLION
) {
180 result
->tv_sec
= a
->tv_sec
+ b
->tv_sec
;
183 result
->tv_usec
= l
- MILLION
;
184 result
->tv_sec
= a
->tv_sec
+ b
->tv_sec
+ 1;
190 * XXX: this function assumes that a >= b.
193 TIMEVAL_SUB(struct timeval
*a
, struct timeval
*b
, struct timeval
*result
)
197 if ((l
= a
->tv_usec
- b
->tv_usec
) >= 0) {
199 result
->tv_sec
= a
->tv_sec
- b
->tv_sec
;
202 result
->tv_usec
= MILLION
+ l
;
203 result
->tv_sec
= a
->tv_sec
- b
->tv_sec
- 1;