]>
Commit | Line | Data |
---|---|---|
61b844bf TL |
1 | /* dispatch.c |
2 | ||
3 | I/O dispatcher. */ | |
4 | ||
5 | /* | |
98311e4b DH |
6 | * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") |
7 | * Copyright (c) 1999-2003 by Internet Software Consortium | |
61b844bf | 8 | * |
98311e4b DH |
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. | |
61b844bf | 12 | * |
98311e4b DH |
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. | |
61b844bf | 20 | * |
98311e4b DH |
21 | * Internet Systems Consortium, Inc. |
22 | * 950 Charter Street | |
23 | * Redwood City, CA 94063 | |
24 | * <info@isc.org> | |
25 | * http://www.isc.org/ | |
49733f31 | 26 | * |
98311e4b | 27 | * This software has been written for Internet Systems Consortium |
49733f31 | 28 | * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. |
98311e4b | 29 | * To learn more about Internet Systems Consortium, see |
49733f31 TL |
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''. | |
61b844bf TL |
33 | */ |
34 | ||
6a4c4be8 | 35 | #include <omapip/omapip_p.h> |
61b844bf TL |
36 | |
37 | static omapi_io_object_t omapi_io_states; | |
98311e4b | 38 | TIME cur_time; |
61b844bf | 39 | |
20916cae TL |
40 | OMAPI_OBJECT_ALLOC (omapi_io, |
41 | omapi_io_object_t, omapi_type_io_object) | |
42 | OMAPI_OBJECT_ALLOC (omapi_waiter, | |
43 | omapi_waiter_object_t, omapi_type_waiter) | |
44 | ||
61b844bf TL |
45 | /* Register an I/O handle so that we can do asynchronous I/O on it. */ |
46 | ||
47 | isc_result_t omapi_register_io_object (omapi_object_t *h, | |
48 | int (*readfd) (omapi_object_t *), | |
49 | int (*writefd) (omapi_object_t *), | |
50 | isc_result_t (*reader) | |
51 | (omapi_object_t *), | |
52 | isc_result_t (*writer) | |
53 | (omapi_object_t *), | |
54 | isc_result_t (*reaper) | |
55 | (omapi_object_t *)) | |
56 | { | |
57 | isc_result_t status; | |
58 | omapi_io_object_t *obj, *p; | |
59 | ||
60 | /* omapi_io_states is a static object. If its reference count | |
61 | is zero, this is the first I/O handle to be registered, so | |
62 | we need to initialize it. Because there is no inner or outer | |
63 | pointer on this object, and we're setting its refcnt to 1, it | |
64 | will never be freed. */ | |
65 | if (!omapi_io_states.refcnt) { | |
66 | omapi_io_states.refcnt = 1; | |
67 | omapi_io_states.type = omapi_type_io_object; | |
68 | } | |
69 | ||
20916cae TL |
70 | obj = (omapi_io_object_t *)0; |
71 | status = omapi_io_allocate (&obj, MDL); | |
72 | if (status != ISC_R_SUCCESS) | |
73 | return status; | |
61b844bf | 74 | |
4bd8800e | 75 | status = omapi_object_reference (&obj -> inner, h, MDL); |
61b844bf | 76 | if (status != ISC_R_SUCCESS) { |
20916cae | 77 | omapi_io_dereference (&obj, MDL); |
61b844bf TL |
78 | return status; |
79 | } | |
80 | ||
4bd8800e TL |
81 | status = omapi_object_reference (&h -> outer, |
82 | (omapi_object_t *)obj, MDL); | |
61b844bf | 83 | if (status != ISC_R_SUCCESS) { |
20916cae | 84 | omapi_io_dereference (&obj, MDL); |
61b844bf TL |
85 | return status; |
86 | } | |
87 | ||
88 | /* Find the last I/O state, if there are any. */ | |
89 | for (p = omapi_io_states.next; | |
90 | p && p -> next; p = p -> next) | |
91 | ; | |
92 | if (p) | |
20916cae | 93 | omapi_io_reference (&p -> next, obj, MDL); |
61b844bf | 94 | else |
20916cae | 95 | omapi_io_reference (&omapi_io_states.next, obj, MDL); |
61b844bf TL |
96 | |
97 | obj -> readfd = readfd; | |
98 | obj -> writefd = writefd; | |
99 | obj -> reader = reader; | |
100 | obj -> writer = writer; | |
101 | obj -> reaper = reaper; | |
102 | return ISC_R_SUCCESS; | |
103 | } | |
104 | ||
b6237fb2 TL |
105 | isc_result_t omapi_unregister_io_object (omapi_object_t *h) |
106 | { | |
20916cae | 107 | omapi_io_object_t *p, *obj, *last, *ph; |
b6237fb2 | 108 | |
20916cae TL |
109 | if (!h -> outer || h -> outer -> type != omapi_type_io_object) |
110 | return ISC_R_INVALIDARG; | |
b6237fb2 | 111 | obj = (omapi_io_object_t *)h -> outer; |
20916cae TL |
112 | ph = (omapi_io_object_t *)0; |
113 | omapi_io_reference (&ph, obj, MDL); | |
b6237fb2 TL |
114 | |
115 | /* remove from the list of I/O states */ | |
c3064fe0 | 116 | last = &omapi_io_states; |
b6237fb2 | 117 | for (p = omapi_io_states.next; p; p = p -> next) { |
20916cae TL |
118 | if (p == obj) { |
119 | omapi_io_dereference (&last -> next, MDL); | |
120 | omapi_io_reference (&last -> next, p -> next, MDL); | |
b6237fb2 TL |
121 | break; |
122 | } | |
123 | last = p; | |
124 | } | |
125 | if (obj -> next) | |
20916cae TL |
126 | omapi_io_dereference (&obj -> next, MDL); |
127 | ||
b6237fb2 TL |
128 | if (obj -> outer) { |
129 | if (obj -> outer -> inner == (omapi_object_t *)obj) | |
130 | omapi_object_dereference (&obj -> outer -> inner, | |
131 | MDL); | |
132 | omapi_object_dereference (&obj -> outer, MDL); | |
133 | } | |
134 | omapi_object_dereference (&obj -> inner, MDL); | |
135 | omapi_object_dereference (&h -> outer, MDL); | |
20916cae | 136 | omapi_io_dereference (&ph, MDL); |
b6237fb2 TL |
137 | return ISC_R_SUCCESS; |
138 | } | |
139 | ||
61b844bf TL |
140 | isc_result_t omapi_dispatch (struct timeval *t) |
141 | { | |
142 | return omapi_wait_for_completion ((omapi_object_t *)&omapi_io_states, | |
143 | t); | |
144 | } | |
145 | ||
146 | isc_result_t omapi_wait_for_completion (omapi_object_t *object, | |
147 | struct timeval *t) | |
148 | { | |
149 | isc_result_t status; | |
150 | omapi_waiter_object_t *waiter; | |
151 | omapi_object_t *inner; | |
152 | ||
153 | if (object) { | |
20916cae TL |
154 | waiter = (omapi_waiter_object_t *)0; |
155 | status = omapi_waiter_allocate (&waiter, MDL); | |
156 | if (status != ISC_R_SUCCESS) | |
157 | return status; | |
61b844bf TL |
158 | |
159 | /* Paste the waiter object onto the inner object we're | |
160 | waiting on. */ | |
161 | for (inner = object; inner -> inner; inner = inner -> inner) | |
162 | ; | |
163 | ||
4bd8800e | 164 | status = omapi_object_reference (&waiter -> outer, inner, MDL); |
61b844bf | 165 | if (status != ISC_R_SUCCESS) { |
20916cae | 166 | omapi_waiter_dereference (&waiter, MDL); |
61b844bf TL |
167 | return status; |
168 | } | |
169 | ||
170 | status = omapi_object_reference (&inner -> inner, | |
171 | (omapi_object_t *)waiter, | |
4bd8800e | 172 | MDL); |
61b844bf | 173 | if (status != ISC_R_SUCCESS) { |
20916cae | 174 | omapi_waiter_dereference (&waiter, MDL); |
61b844bf TL |
175 | return status; |
176 | } | |
177 | } else | |
178 | waiter = (omapi_waiter_object_t *)0; | |
179 | ||
180 | do { | |
6a4c4be8 | 181 | status = omapi_one_dispatch ((omapi_object_t *)waiter, t); |
61b844bf TL |
182 | if (status != ISC_R_SUCCESS) |
183 | return status; | |
184 | } while (!waiter || !waiter -> ready); | |
185 | ||
727ebc3a TL |
186 | if (waiter -> outer) { |
187 | if (waiter -> outer -> inner) { | |
188 | omapi_object_dereference (&waiter -> outer -> inner, | |
4bd8800e | 189 | MDL); |
727ebc3a TL |
190 | if (waiter -> inner) |
191 | omapi_object_reference | |
192 | (&waiter -> outer -> inner, | |
4bd8800e | 193 | waiter -> inner, MDL); |
727ebc3a | 194 | } |
4bd8800e | 195 | omapi_object_dereference (&waiter -> outer, MDL); |
727ebc3a TL |
196 | } |
197 | if (waiter -> inner) | |
4bd8800e | 198 | omapi_object_dereference (&waiter -> inner, MDL); |
727ebc3a | 199 | |
49146f3c | 200 | status = waiter -> waitstatus; |
20916cae | 201 | omapi_waiter_dereference (&waiter, MDL); |
86a9cf83 | 202 | return status; |
61b844bf TL |
203 | } |
204 | ||
6a4c4be8 | 205 | isc_result_t omapi_one_dispatch (omapi_object_t *wo, |
61b844bf TL |
206 | struct timeval *t) |
207 | { | |
208 | fd_set r, w, x; | |
209 | int max = 0; | |
210 | int count; | |
211 | int desc; | |
212 | struct timeval now, to; | |
213 | omapi_io_object_t *io, *prev; | |
6a4c4be8 | 214 | omapi_waiter_object_t *waiter; |
b6237fb2 | 215 | omapi_object_t *tmp = (omapi_object_t *)0; |
6a4c4be8 TL |
216 | |
217 | if (!wo || wo -> type != omapi_type_waiter) | |
218 | waiter = (omapi_waiter_object_t *)0; | |
219 | else | |
220 | waiter = (omapi_waiter_object_t *)wo; | |
61b844bf TL |
221 | |
222 | FD_ZERO (&x); | |
223 | ||
224 | /* First, see if the timeout has expired, and if so return. */ | |
225 | if (t) { | |
226 | gettimeofday (&now, (struct timezone *)0); | |
227 | cur_time = now.tv_sec; | |
228 | if (now.tv_sec > t -> tv_sec || | |
229 | (now.tv_sec == t -> tv_sec && now.tv_usec >= t -> tv_usec)) | |
230 | return ISC_R_TIMEDOUT; | |
231 | ||
232 | /* We didn't time out, so figure out how long until | |
233 | we do. */ | |
234 | to.tv_sec = t -> tv_sec - now.tv_sec; | |
235 | to.tv_usec = t -> tv_usec - now.tv_usec; | |
236 | if (to.tv_usec < 0) { | |
237 | to.tv_usec += 1000000; | |
238 | to.tv_sec--; | |
239 | } | |
d01dde76 DN |
240 | |
241 | /* It is possible for the timeout to get set larger than | |
242 | the largest time select() is willing to accept. | |
243 | Restricting the timeout to a maximum of one day should | |
244 | work around this. -DPN. (Ref: Bug #416) */ | |
245 | if (to.tv_sec > (60 * 60 * 24)) | |
246 | to.tv_sec = 60 * 60 * 24; | |
61b844bf TL |
247 | } |
248 | ||
249 | /* If the object we're waiting on has reached completion, | |
250 | return now. */ | |
251 | if (waiter && waiter -> ready) | |
252 | return ISC_R_SUCCESS; | |
253 | ||
cfb3f45d | 254 | again: |
61b844bf TL |
255 | /* If we have no I/O state, we can't proceed. */ |
256 | if (!(io = omapi_io_states.next)) | |
257 | return ISC_R_NOMORE; | |
258 | ||
259 | /* Set up the read and write masks. */ | |
260 | FD_ZERO (&r); | |
261 | FD_ZERO (&w); | |
262 | ||
263 | for (; io; io = io -> next) { | |
264 | /* Check for a read socket. If we shouldn't be | |
265 | trying to read for this I/O object, either there | |
266 | won't be a readfd function, or it'll return -1. */ | |
d8c46740 | 267 | if (io -> readfd && io -> inner && |
61b844bf TL |
268 | (desc = (*(io -> readfd)) (io -> inner)) >= 0) { |
269 | FD_SET (desc, &r); | |
270 | if (desc > max) | |
271 | max = desc; | |
272 | } | |
273 | ||
274 | /* Same deal for write fdets. */ | |
d8c46740 | 275 | if (io -> writefd && io -> inner && |
61b844bf TL |
276 | (desc = (*(io -> writefd)) (io -> inner)) >= 0) { |
277 | FD_SET (desc, &w); | |
278 | if (desc > max) | |
279 | max = desc; | |
280 | } | |
281 | } | |
282 | ||
283 | /* Wait for a packet or a timeout... XXX */ | |
edbb7667 | 284 | #if 0 |
cfb3f45d TL |
285 | #if defined (__linux__) |
286 | #define fds_bits __fds_bits | |
287 | #endif | |
477e97dd TL |
288 | log_error ("dispatch: %d %lx %lx", max, |
289 | (unsigned long)r.fds_bits [0], | |
290 | (unsigned long)w.fds_bits [0]); | |
edbb7667 | 291 | #endif |
61b844bf TL |
292 | count = select (max + 1, &r, &w, &x, t ? &to : (struct timeval *)0); |
293 | ||
294 | /* Get the current time... */ | |
295 | gettimeofday (&now, (struct timezone *)0); | |
296 | cur_time = now.tv_sec; | |
297 | ||
cfb3f45d TL |
298 | /* We probably have a bad file descriptor. Figure out which one. |
299 | When we find it, call the reaper function on it, which will | |
300 | maybe make it go away, and then try again. */ | |
301 | if (count < 0) { | |
302 | struct timeval t0; | |
9bf59e83 TL |
303 | omapi_io_object_t *prev = (omapi_io_object_t *)0; |
304 | io = (omapi_io_object_t *)0; | |
305 | if (omapi_io_states.next) | |
306 | omapi_io_reference (&io, omapi_io_states.next, MDL); | |
cfb3f45d | 307 | |
9bf59e83 | 308 | while (io) { |
cfb3f45d TL |
309 | omapi_object_t *obj; |
310 | FD_ZERO (&r); | |
311 | FD_ZERO (&w); | |
312 | t0.tv_sec = t0.tv_usec = 0; | |
313 | ||
314 | if (io -> readfd && io -> inner && | |
315 | (desc = (*(io -> readfd)) (io -> inner)) >= 0) { | |
316 | FD_SET (desc, &r); | |
edbb7667 | 317 | #if 0 |
477e97dd TL |
318 | log_error ("read check: %d %lx %lx", max, |
319 | (unsigned long)r.fds_bits [0], | |
320 | (unsigned long)w.fds_bits [0]); | |
edbb7667 | 321 | #endif |
cfb3f45d TL |
322 | count = select (desc + 1, &r, &w, &x, &t0); |
323 | bogon: | |
324 | if (count < 0) { | |
325 | log_error ("Bad descriptor %d.", desc); | |
326 | for (obj = (omapi_object_t *)io; | |
327 | obj -> outer; | |
328 | obj = obj -> outer) | |
329 | ; | |
645eab7b TL |
330 | for (; obj; obj = obj -> inner) { |
331 | omapi_value_t *ov; | |
332 | int len; | |
333 | const char *s; | |
334 | ov = (omapi_value_t *)0; | |
335 | omapi_get_value_str (obj, | |
336 | (omapi_object_t *)0, | |
337 | "name", &ov); | |
338 | if (ov && ov -> value && | |
339 | (ov -> value -> type == | |
340 | omapi_datatype_string)) { | |
341 | s = (char *) | |
342 | ov -> value -> u.buffer.value; | |
343 | len = ov -> value -> u.buffer.len; | |
344 | } else { | |
345 | s = ""; | |
346 | len = 0; | |
347 | } | |
348 | log_error ("Object %lx %s%s%.*s", | |
349 | (unsigned long)obj, | |
350 | obj -> type -> name, | |
351 | len ? " " : "", | |
352 | len, s); | |
353 | if (len) | |
354 | omapi_value_dereference (&ov, MDL); | |
355 | } | |
98311e4b | 356 | (*(io -> reaper)) (io -> inner); |
9bf59e83 TL |
357 | if (prev) { |
358 | omapi_io_dereference (&prev -> next, MDL); | |
359 | if (io -> next) | |
360 | omapi_io_reference (&prev -> next, | |
361 | io -> next, MDL); | |
362 | } else { | |
363 | omapi_io_dereference | |
364 | (&omapi_io_states.next, MDL); | |
365 | if (io -> next) | |
366 | omapi_io_reference | |
367 | (&omapi_io_states.next, | |
368 | io -> next, MDL); | |
369 | } | |
370 | omapi_io_dereference (&io, MDL); | |
cfb3f45d TL |
371 | goto again; |
372 | } | |
373 | } | |
374 | ||
375 | FD_ZERO (&r); | |
376 | FD_ZERO (&w); | |
377 | t0.tv_sec = t0.tv_usec = 0; | |
378 | ||
379 | /* Same deal for write fdets. */ | |
380 | if (io -> writefd && io -> inner && | |
381 | (desc = (*(io -> writefd)) (io -> inner)) >= 0) { | |
382 | FD_SET (desc, &w); | |
cfb3f45d TL |
383 | count = select (desc + 1, &r, &w, &x, &t0); |
384 | if (count < 0) | |
385 | goto bogon; | |
386 | } | |
9bf59e83 TL |
387 | if (prev) |
388 | omapi_io_dereference (&prev, MDL); | |
389 | omapi_io_reference (&prev, io, MDL); | |
390 | omapi_io_dereference (&io, MDL); | |
391 | if (prev -> next) | |
392 | omapi_io_reference (&io, prev -> next, MDL); | |
cfb3f45d | 393 | } |
9bf59e83 TL |
394 | if (prev) |
395 | omapi_io_dereference (&prev, MDL); | |
396 | ||
cfb3f45d | 397 | } |
61b844bf TL |
398 | |
399 | for (io = omapi_io_states.next; io; io = io -> next) { | |
d8c46740 TL |
400 | if (!io -> inner) |
401 | continue; | |
b6237fb2 | 402 | omapi_object_reference (&tmp, io -> inner, MDL); |
61b844bf TL |
403 | /* Check for a read descriptor, and if there is one, |
404 | see if we got input on that socket. */ | |
405 | if (io -> readfd && | |
b6237fb2 | 406 | (desc = (*(io -> readfd)) (tmp)) >= 0) { |
61b844bf | 407 | if (FD_ISSET (desc, &r)) |
98311e4b | 408 | ((*(io -> reader)) (tmp)); |
61b844bf TL |
409 | } |
410 | ||
411 | /* Same deal for write descriptors. */ | |
412 | if (io -> writefd && | |
b6237fb2 | 413 | (desc = (*(io -> writefd)) (tmp)) >= 0) |
61b844bf TL |
414 | { |
415 | if (FD_ISSET (desc, &w)) | |
98311e4b | 416 | ((*(io -> writer)) (tmp)); |
61b844bf | 417 | } |
b6237fb2 | 418 | omapi_object_dereference (&tmp, MDL); |
61b844bf TL |
419 | } |
420 | ||
421 | /* Now check for I/O handles that are no longer valid, | |
422 | and remove them from the list. */ | |
423 | prev = (omapi_io_object_t *)0; | |
424 | for (io = omapi_io_states.next; io; io = io -> next) { | |
425 | if (io -> reaper) { | |
98311e4b DH |
426 | if (!io -> inner || |
427 | ((*(io -> reaper)) (io -> inner) != | |
428 | ISC_R_SUCCESS)) { | |
61b844bf TL |
429 | omapi_io_object_t *tmp = |
430 | (omapi_io_object_t *)0; | |
431 | /* Save a reference to the next | |
432 | pointer, if there is one. */ | |
433 | if (io -> next) | |
20916cae TL |
434 | omapi_io_reference (&tmp, |
435 | io -> next, MDL); | |
61b844bf | 436 | if (prev) { |
20916cae TL |
437 | omapi_io_dereference (&prev -> next, |
438 | MDL); | |
61b844bf | 439 | if (tmp) |
20916cae TL |
440 | omapi_io_reference |
441 | (&prev -> next, | |
442 | tmp, MDL); | |
61b844bf | 443 | } else { |
20916cae TL |
444 | omapi_io_dereference |
445 | (&omapi_io_states.next, MDL); | |
61b844bf | 446 | if (tmp) |
20916cae TL |
447 | omapi_io_reference |
448 | (&omapi_io_states.next, | |
449 | tmp, MDL); | |
61b844bf TL |
450 | else |
451 | omapi_signal_in | |
452 | ((omapi_object_t *) | |
453 | &omapi_io_states, | |
454 | "ready"); | |
455 | } | |
456 | if (tmp) | |
20916cae | 457 | omapi_io_dereference (&tmp, MDL); |
61b844bf TL |
458 | } |
459 | } | |
460 | prev = io; | |
461 | } | |
462 | ||
463 | return ISC_R_SUCCESS; | |
464 | } | |
465 | ||
466 | isc_result_t omapi_io_set_value (omapi_object_t *h, | |
467 | omapi_object_t *id, | |
468 | omapi_data_string_t *name, | |
469 | omapi_typed_data_t *value) | |
470 | { | |
471 | if (h -> type != omapi_type_io_object) | |
472 | return ISC_R_INVALIDARG; | |
473 | ||
474 | if (h -> inner && h -> inner -> type -> set_value) | |
475 | return (*(h -> inner -> type -> set_value)) | |
476 | (h -> inner, id, name, value); | |
477 | return ISC_R_NOTFOUND; | |
478 | } | |
479 | ||
480 | isc_result_t omapi_io_get_value (omapi_object_t *h, | |
481 | omapi_object_t *id, | |
482 | omapi_data_string_t *name, | |
483 | omapi_value_t **value) | |
484 | { | |
485 | if (h -> type != omapi_type_io_object) | |
486 | return ISC_R_INVALIDARG; | |
487 | ||
488 | if (h -> inner && h -> inner -> type -> get_value) | |
489 | return (*(h -> inner -> type -> get_value)) | |
490 | (h -> inner, id, name, value); | |
491 | return ISC_R_NOTFOUND; | |
492 | } | |
493 | ||
98311e4b DH |
494 | /* omapi_io_destroy (object, MDL); |
495 | * | |
496 | * Find the requsted IO [object] and remove it from the list of io | |
497 | * states, causing the cleanup functions to destroy it. Note that we must | |
498 | * hold a reference on the object while moving its ->next reference and | |
499 | * removing the reference in the chain to the target object...otherwise it | |
500 | * may be cleaned up from under us. | |
501 | */ | |
4bd8800e | 502 | isc_result_t omapi_io_destroy (omapi_object_t *h, const char *file, int line) |
61b844bf | 503 | { |
98311e4b | 504 | omapi_io_object_t *obj = NULL, *p, *last = NULL, **holder; |
bdcaf7b9 | 505 | |
61b844bf TL |
506 | if (h -> type != omapi_type_io_object) |
507 | return ISC_R_INVALIDARG; | |
bdcaf7b9 | 508 | |
b6237fb2 TL |
509 | /* remove from the list of I/O states */ |
510 | for (p = omapi_io_states.next; p; p = p -> next) { | |
98311e4b DH |
511 | if (p == (omapi_io_object_t *)h) { |
512 | omapi_io_reference (&obj, p, MDL); | |
513 | ||
514 | if (last) | |
515 | holder = &last -> next; | |
516 | else | |
517 | holder = &omapi_io_states.next; | |
518 | ||
519 | omapi_io_dereference (holder, MDL); | |
520 | ||
521 | if (obj -> next) { | |
522 | omapi_io_reference (holder, obj -> next, MDL); | |
523 | omapi_io_dereference (&obj -> next, MDL); | |
524 | } | |
525 | ||
526 | return omapi_io_dereference (&obj, MDL); | |
bdcaf7b9 | 527 | } |
b6237fb2 | 528 | last = p; |
bdcaf7b9 | 529 | } |
98311e4b DH |
530 | |
531 | return ISC_R_NOTFOUND; | |
61b844bf TL |
532 | } |
533 | ||
534 | isc_result_t omapi_io_signal_handler (omapi_object_t *h, | |
b1b7b521 | 535 | const char *name, va_list ap) |
61b844bf TL |
536 | { |
537 | if (h -> type != omapi_type_io_object) | |
538 | return ISC_R_INVALIDARG; | |
539 | ||
540 | if (h -> inner && h -> inner -> type -> signal_handler) | |
541 | return (*(h -> inner -> type -> signal_handler)) (h -> inner, | |
542 | name, ap); | |
543 | return ISC_R_NOTFOUND; | |
544 | } | |
545 | ||
546 | isc_result_t omapi_io_stuff_values (omapi_object_t *c, | |
547 | omapi_object_t *id, | |
548 | omapi_object_t *i) | |
549 | { | |
550 | if (i -> type != omapi_type_io_object) | |
551 | return ISC_R_INVALIDARG; | |
552 | ||
553 | if (i -> inner && i -> inner -> type -> stuff_values) | |
554 | return (*(i -> inner -> type -> stuff_values)) (c, id, | |
555 | i -> inner); | |
556 | return ISC_R_SUCCESS; | |
557 | } | |
558 | ||
559 | isc_result_t omapi_waiter_signal_handler (omapi_object_t *h, | |
b1b7b521 | 560 | const char *name, va_list ap) |
61b844bf TL |
561 | { |
562 | omapi_waiter_object_t *waiter; | |
563 | ||
564 | if (h -> type != omapi_type_waiter) | |
565 | return ISC_R_INVALIDARG; | |
566 | ||
567 | if (!strcmp (name, "ready")) { | |
568 | waiter = (omapi_waiter_object_t *)h; | |
569 | waiter -> ready = 1; | |
49146f3c DN |
570 | waiter -> waitstatus = ISC_R_SUCCESS; |
571 | return ISC_R_SUCCESS; | |
572 | } | |
573 | ||
574 | if (!strcmp (name, "status")) { | |
575 | waiter = (omapi_waiter_object_t *)h; | |
576 | waiter -> ready = 1; | |
577 | waiter -> waitstatus = va_arg (ap, isc_result_t); | |
61b844bf TL |
578 | return ISC_R_SUCCESS; |
579 | } | |
580 | ||
d758ad8c TL |
581 | if (!strcmp (name, "disconnect")) { |
582 | waiter = (omapi_waiter_object_t *)h; | |
583 | waiter -> ready = 1; | |
584 | waiter -> waitstatus = ISC_R_CONNRESET; | |
585 | return ISC_R_SUCCESS; | |
586 | } | |
587 | ||
61b844bf TL |
588 | if (h -> inner && h -> inner -> type -> signal_handler) |
589 | return (*(h -> inner -> type -> signal_handler)) (h -> inner, | |
590 | name, ap); | |
591 | return ISC_R_NOTFOUND; | |
592 | } | |
593 | ||
d758ad8c TL |
594 | isc_result_t omapi_io_state_foreach (isc_result_t (*func) (omapi_object_t *, |
595 | void *), | |
596 | void *p) | |
597 | { | |
598 | omapi_io_object_t *io; | |
599 | isc_result_t status; | |
600 | ||
601 | for (io = omapi_io_states.next; io; io = io -> next) { | |
602 | if (io -> inner) { | |
603 | status = (*func) (io -> inner, p); | |
604 | if (status != ISC_R_SUCCESS) | |
605 | return status; | |
606 | } | |
607 | } | |
608 | return ISC_R_SUCCESS; | |
609 | } |