xref: /openbsd-src/sbin/isakmpd/timer.c (revision 8500990981f885cbe5e6a4958549cacc238b5ae6)
1 /*	$OpenBSD: timer.c,v 1.11 2003/06/03 14:28:16 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  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /*
29  * This code was written under funding by Ericsson Radio Systems.
30  */
31 
32 #include <sys/queue.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #include "sysdep.h"
37 
38 #include "log.h"
39 #include "timer.h"
40 
41 static TAILQ_HEAD (event_list, event) events;
42 
43 void
44 timer_init (void)
45 {
46   TAILQ_INIT (&events);
47 }
48 
49 void
50 timer_next_event (struct timeval **timeout)
51 {
52   struct timeval now;
53 
54   if (TAILQ_FIRST (&events))
55     {
56       gettimeofday (&now, 0);
57       if (timercmp (&now, &TAILQ_FIRST (&events)->expiration, >=))
58 	timerclear (*timeout);
59       else
60 	timersub (&TAILQ_FIRST (&events)->expiration, &now, *timeout);
61     }
62   else
63     *timeout = 0;
64 }
65 
66 void
67 timer_handle_expirations (void)
68 {
69   struct timeval now;
70   struct event *n;
71 
72   gettimeofday (&now, 0);
73   for (n = TAILQ_FIRST (&events); n && timercmp (&now, &n->expiration, >=);
74        n = TAILQ_FIRST (&events))
75     {
76       LOG_DBG ((LOG_TIMER, 10,
77 		"timer_handle_expirations: event %s(%p)", n->name, n->arg));
78       TAILQ_REMOVE (&events, n, link);
79       (*n->func) (n->arg);
80       free (n);
81     }
82 }
83 
84 struct event *
85 timer_add_event (char *name, void (*func) (void *), void *arg,
86 		 struct timeval *expiration)
87 {
88   struct event *ev = (struct event *)malloc (sizeof *ev);
89   struct event *n;
90   struct timeval now;
91 
92   if (!ev)
93     return 0;
94   ev->name = name;
95   ev->func = func;
96   ev->arg = arg;
97   gettimeofday (&now, 0);
98   memcpy (&ev->expiration, expiration, sizeof *expiration);
99   for (n = TAILQ_FIRST (&events);
100        n && timercmp (expiration, &n->expiration, >=);
101        n = TAILQ_NEXT (n, link))
102     ;
103   if (n)
104     {
105       LOG_DBG ((LOG_TIMER, 10,
106 		"timer_add_event: event %s(%p) added before %s(%p), "
107 		"expiration in %lds", name,
108 		arg, n->name, n->arg, expiration->tv_sec - now.tv_sec));
109       TAILQ_INSERT_BEFORE (n, ev, link);
110     }
111   else
112     {
113       LOG_DBG ((LOG_TIMER, 10, "timer_add_event: event %s(%p) added last, "
114 		"expiration in %lds", name, arg,
115 		expiration->tv_sec - now.tv_sec));
116       TAILQ_INSERT_TAIL (&events, ev, link);
117     }
118   return ev;
119 }
120 
121 void
122 timer_remove_event (struct event *ev)
123 {
124   LOG_DBG ((LOG_TIMER, 10, "timer_remove_event: removing event %s(%p)",
125 	    ev->name, ev->arg));
126   TAILQ_REMOVE (&events, ev, link);
127   free (ev);
128 }
129 
130 void
131 timer_report (void)
132 {
133   struct event *ev;
134   struct timeval now;
135 
136   gettimeofday (&now, 0);
137 
138   for (ev = TAILQ_FIRST (&events); ev; ev = TAILQ_NEXT (ev, link))
139     LOG_DBG ((LOG_REPORT, 0,
140 	      "timer_report: event %s(%p) scheduled in %d seconds",
141 	      (ev->name ? ev->name : "<unknown>"), ev,
142 	      (int)(ev->expiration.tv_sec - now.tv_sec)));
143 }
144