xref: /openbsd-src/sbin/isakmpd/timer.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: timer.c,v 1.8 2001/07/06 14:37:11 ho Exp $	*/
2 /*	$EOM: timer.c,v 1.13 2000/02/20 19:58:42 niklas Exp $	*/
3 
4 /*
5  * Copyright (c) 1998, 1999 Niklas Hallqvist.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
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. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Ericsson Radio Systems.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * This code was written under funding by Ericsson Radio Systems.
35  */
36 
37 #include <sys/queue.h>
38 #include <stdlib.h>
39 #include <string.h>
40 
41 #include "sysdep.h"
42 
43 #include "log.h"
44 #include "timer.h"
45 
46 static TAILQ_HEAD (event_list, event) events;
47 
48 void
49 timer_init (void)
50 {
51   TAILQ_INIT (&events);
52 }
53 
54 void
55 timer_next_event (struct timeval **timeout)
56 {
57   struct timeval now;
58 
59   if (TAILQ_FIRST (&events))
60     {
61       gettimeofday (&now, 0);
62       if (timercmp (&now, &TAILQ_FIRST (&events)->expiration, >=))
63 	timerclear (*timeout);
64       else
65 	timersub (&TAILQ_FIRST (&events)->expiration, &now, *timeout);
66     }
67   else
68     *timeout = 0;
69 }
70 
71 void
72 timer_handle_expirations (void)
73 {
74   struct timeval now;
75   struct event *n;
76 
77   gettimeofday (&now, 0);
78   for (n = TAILQ_FIRST (&events); n && timercmp (&now, &n->expiration, >=);
79        n = TAILQ_FIRST (&events))
80     {
81       LOG_DBG ((LOG_TIMER, 10,
82 		"timer_handle_expirations: event %s(%p)", n->name, n->arg));
83       TAILQ_REMOVE (&events, n, link);
84       (*n->func) (n->arg);
85       free (n);
86     }
87 }
88 
89 struct event *
90 timer_add_event (char *name, void (*func) (void *), void *arg,
91 		 struct timeval *expiration)
92 {
93   struct event *ev = (struct event *)malloc (sizeof *ev);
94   struct event *n;
95   struct timeval now;
96 
97   if (!ev)
98     return 0;
99   ev->name = name;
100   ev->func = func;
101   ev->arg = arg;
102   gettimeofday (&now, 0);
103   memcpy (&ev->expiration, expiration, sizeof *expiration);
104   for (n = TAILQ_FIRST (&events);
105        n && timercmp (expiration, &n->expiration, >=);
106        n = TAILQ_NEXT (n, link))
107     ;
108   if (n)
109     {
110       LOG_DBG ((LOG_TIMER, 10,
111 		"timer_add_event: event %s(%p) added before %s(%p), "
112 		"expiration in %ds", name,
113 		arg, n->name, n->arg, expiration->tv_sec - now.tv_sec));
114       TAILQ_INSERT_BEFORE (n, ev, link);
115     }
116   else
117     {
118       LOG_DBG ((LOG_TIMER, 10, "timer_add_event: event %s(%p) added last, "
119 		"expiration in %ds", name, arg,
120 		expiration->tv_sec - now.tv_sec));
121       TAILQ_INSERT_TAIL (&events, ev, link);
122     }
123   return ev;
124 }
125 
126 void
127 timer_remove_event (struct event *ev)
128 {
129   LOG_DBG ((LOG_TIMER, 10, "timer_remove_event: removing event %s(%p)",
130 	    ev->name, ev->arg));
131   TAILQ_REMOVE (&events, ev, link);
132   free (ev);
133 }
134 
135 void
136 timer_report (void)
137 {
138   struct event *ev;
139   struct timeval now;
140 
141   gettimeofday (&now, 0);
142 
143   for (ev = TAILQ_FIRST (&events); ev; ev = TAILQ_NEXT (ev, link))
144     LOG_DBG ((LOG_REPORT, 0,
145 	      "timer_report: event %s(%p) scheduled in %d seconds",
146 	      (ev->name ? ev->name : "<unknown>"), ev,
147 	      (int)(ev->expiration.tv_sec - now.tv_sec)));
148 }
149