Pre-2.0 release, MFC firewire disk changes to properly detach SIMs.
[dragonfly.git] / contrib / dhcp-3.0 / common / dispatch.c
blob01865ddadc1cc4e7a80e0951ec9fc08d18cc8db4
1 /* dispatch.c
3 Network input dispatcher... */
5 /*
6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * http://www.isc.org/
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
35 #ifndef lint
36 static char copyright[] =
37 "$Id: dispatch.c,v 1.63.2.4 2004/06/10 17:59:16 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
38 #endif /* not lint */
40 #include "dhcpd.h"
42 struct timeout *timeouts;
43 static struct timeout *free_timeouts;
45 void set_time (u_int32_t t)
47 /* Do any outstanding timeouts. */
48 if (cur_time != t) {
49 cur_time = t;
50 process_outstanding_timeouts ((struct timeval *)0);
54 struct timeval *process_outstanding_timeouts (struct timeval *tvp)
56 /* Call any expired timeouts, and then if there's
57 still a timeout registered, time out the select
58 call then. */
59 another:
60 if (timeouts) {
61 struct timeout *t;
62 if (timeouts -> when <= cur_time) {
63 t = timeouts;
64 timeouts = timeouts -> next;
65 (*(t -> func)) (t -> what);
66 if (t -> unref)
67 (*t -> unref) (&t -> what, MDL);
68 t -> next = free_timeouts;
69 free_timeouts = t;
70 goto another;
72 if (tvp) {
73 tvp -> tv_sec = timeouts -> when;
74 tvp -> tv_usec = 0;
76 return tvp;
77 } else
78 return (struct timeval *)0;
81 /* Wait for packets to come in using select(). When one does, call
82 receive_packet to receive the packet and possibly strip hardware
83 addressing information from it, and then call through the
84 bootp_packet_handler hook to try to do something with it. */
86 void dispatch ()
88 struct timeval tv, *tvp;
89 isc_result_t status;
91 /* Wait for a packet or a timeout... XXX */
92 do {
93 tvp = process_outstanding_timeouts (&tv);
94 status = omapi_one_dispatch (0, tvp);
95 } while (status == ISC_R_TIMEDOUT || status == ISC_R_SUCCESS);
96 log_fatal ("omapi_one_dispatch failed: %s -- exiting.",
97 isc_result_totext (status));
100 void add_timeout (when, where, what, ref, unref)
101 TIME when;
102 void (*where) PROTO ((void *));
103 void *what;
104 tvref_t ref;
105 tvunref_t unref;
107 struct timeout *t, *q;
109 /* See if this timeout supersedes an existing timeout. */
110 t = (struct timeout *)0;
111 for (q = timeouts; q; q = q -> next) {
112 if ((where == NULL || q -> func == where) &&
113 q -> what == what) {
114 if (t)
115 t -> next = q -> next;
116 else
117 timeouts = q -> next;
118 break;
120 t = q;
123 /* If we didn't supersede a timeout, allocate a timeout
124 structure now. */
125 if (!q) {
126 if (free_timeouts) {
127 q = free_timeouts;
128 free_timeouts = q -> next;
129 } else {
130 q = ((struct timeout *)
131 dmalloc (sizeof (struct timeout), MDL));
132 if (!q)
133 log_fatal ("add_timeout: no memory!");
135 memset (q, 0, sizeof *q);
136 q -> func = where;
137 q -> ref = ref;
138 q -> unref = unref;
139 if (q -> ref)
140 (*q -> ref)(&q -> what, what, MDL);
141 else
142 q -> what = what;
145 q -> when = when;
147 /* Now sort this timeout into the timeout list. */
149 /* Beginning of list? */
150 if (!timeouts || timeouts -> when > q -> when) {
151 q -> next = timeouts;
152 timeouts = q;
153 return;
156 /* Middle of list? */
157 for (t = timeouts; t -> next; t = t -> next) {
158 if (t -> next -> when > q -> when) {
159 q -> next = t -> next;
160 t -> next = q;
161 return;
165 /* End of list. */
166 t -> next = q;
167 q -> next = (struct timeout *)0;
170 void cancel_timeout (where, what)
171 void (*where) PROTO ((void *));
172 void *what;
174 struct timeout *t, *q;
176 /* Look for this timeout on the list, and unlink it if we find it. */
177 t = (struct timeout *)0;
178 for (q = timeouts; q; q = q -> next) {
179 if (q -> func == where && q -> what == what) {
180 if (t)
181 t -> next = q -> next;
182 else
183 timeouts = q -> next;
184 break;
186 t = q;
189 /* If we found the timeout, put it on the free list. */
190 if (q) {
191 if (q -> unref)
192 (*q -> unref) (&q -> what, MDL);
193 q -> next = free_timeouts;
194 free_timeouts = q;
198 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
199 void cancel_all_timeouts ()
201 struct timeout *t, *n;
202 for (t = timeouts; t; t = n) {
203 n = t -> next;
204 if (t -> unref && t -> what)
205 (*t -> unref) (&t -> what, MDL);
206 t -> next = free_timeouts;
207 free_timeouts = t;
211 void relinquish_timeouts ()
213 struct timeout *t, *n;
214 for (t = free_timeouts; t; t = n) {
215 n = t -> next;
216 dfree (t, MDL);
219 #endif