Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / dhcp / omapip / alloc.c
blobb33fd39b15e9cd0da7915e40c388c98a50e02396
1 /* alloc.c
3 Functions supporting memory allocation for the object management
4 protocol... */
6 /*
7 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 1999-2003 by Internet Software Consortium
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * Internet Systems Consortium, Inc.
23 * 950 Charter Street
24 * Redwood City, CA 94063
25 * <info@isc.org>
26 * http://www.isc.org/
28 * This software has been written for Internet Systems Consortium
29 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
30 * To learn more about Internet Systems Consortium, see
31 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
32 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
33 * ``http://www.nominum.com''.
36 #include <omapip/omapip_p.h>
38 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
39 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
40 struct dmalloc_preamble *dmalloc_list;
41 unsigned long dmalloc_outstanding;
42 unsigned long dmalloc_longterm;
43 unsigned long dmalloc_generation;
44 unsigned long dmalloc_cutoff_generation;
45 #endif
47 #if defined (DEBUG_RC_HISTORY)
48 struct rc_history_entry rc_history [RC_HISTORY_MAX];
49 int rc_history_index;
50 int rc_history_count;
51 #endif
53 #if defined (DEBUG_RC_HISTORY)
54 static void print_rc_hist_entry (int);
55 #endif
57 VOIDPTR dmalloc (size, file, line)
58 unsigned size;
59 const char *file;
60 int line;
62 unsigned char *foo = malloc (size + DMDSIZE);
63 VOIDPTR *bar;
64 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
65 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
66 int i;
67 struct dmalloc_preamble *dp;
68 #endif
69 if (!foo)
70 return (VOIDPTR)0;
71 bar = (VOIDPTR)(foo + DMDOFFSET);
72 memset (bar, 0, size);
74 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
75 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
76 dp = (struct dmalloc_preamble *)foo;
77 dp -> prev = dmalloc_list;
78 if (dmalloc_list)
79 dmalloc_list -> next = dp;
80 dmalloc_list = dp;
81 dp -> next = (struct dmalloc_preamble *)0;
82 dp -> size = size;
83 dp -> file = file;
84 dp -> line = line;
85 dp -> generation = dmalloc_generation++;
86 dmalloc_outstanding += size;
87 for (i = 0; i < DMLFSIZE; i++)
88 dp -> low_fence [i] =
89 (((unsigned long)
90 (&dp -> low_fence [i])) % 143) + 113;
91 for (i = DMDOFFSET; i < DMDSIZE; i++)
92 foo [i + size] =
93 (((unsigned long)
94 (&foo [i + size])) % 143) + 113;
95 #if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
96 /* Check _every_ entry in the pool! Very expensive. */
97 for (dp = dmalloc_list; dp; dp = dp -> prev) {
98 for (i = 0; i < DMLFSIZE; i++) {
99 if (dp -> low_fence [i] !=
100 (((unsigned long)
101 (&dp -> low_fence [i])) % 143) + 113)
103 log_error ("malloc fence modified: %s(%d)",
104 dp -> file, dp -> line);
105 abort ();
108 foo = (unsigned char *)dp;
109 for (i = DMDOFFSET; i < DMDSIZE; i++) {
110 if (foo [i + dp -> size] !=
111 (((unsigned long)
112 (&foo [i + dp -> size])) % 143) + 113) {
113 log_error ("malloc fence modified: %s(%d)",
114 dp -> file, dp -> line);
115 abort ();
119 #endif
120 #endif
121 #ifdef DEBUG_REFCNT_DMALLOC_FREE
122 rc_register (file, line, 0, foo + DMDOFFSET, 1, 0, RC_MALLOC);
123 #endif
124 return bar;
127 void dfree (ptr, file, line)
128 VOIDPTR ptr;
129 const char *file;
130 int line;
132 if (!ptr) {
133 log_error ("dfree %s(%d): free on null pointer.", file, line);
134 return;
136 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
137 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
139 unsigned char *bar = ptr;
140 struct dmalloc_preamble *dp, *cur;
141 int i;
142 bar -= DMDOFFSET;
143 cur = (struct dmalloc_preamble *)bar;
144 for (dp = dmalloc_list; dp; dp = dp -> prev)
145 if (dp == cur)
146 break;
147 if (!dp) {
148 log_error ("%s(%d): freeing unknown memory: %lx",
149 file, line, (unsigned long)cur);
150 abort ();
152 if (dp -> prev)
153 dp -> prev -> next = dp -> next;
154 if (dp -> next)
155 dp -> next -> prev = dp -> prev;
156 if (dp == dmalloc_list)
157 dmalloc_list = dp -> prev;
158 if (dp -> generation >= dmalloc_cutoff_generation)
159 dmalloc_outstanding -= dp -> size;
160 else
161 dmalloc_longterm -= dp -> size;
163 for (i = 0; i < DMLFSIZE; i++) {
164 if (dp -> low_fence [i] !=
165 (((unsigned long)
166 (&dp -> low_fence [i])) % 143) + 113)
168 log_error ("malloc fence modified: %s(%d)",
169 dp -> file, dp -> line);
170 abort ();
173 for (i = DMDOFFSET; i < DMDSIZE; i++) {
174 if (bar [i + dp -> size] !=
175 (((unsigned long)
176 (&bar [i + dp -> size])) % 143) + 113) {
177 log_error ("malloc fence modified: %s(%d)",
178 dp -> file, dp -> line);
179 abort ();
182 ptr = bar;
184 #endif
185 #ifdef DEBUG_REFCNT_DMALLOC_FREE
186 rc_register (file, line,
187 0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);
188 #endif
189 free (ptr);
192 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
193 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
194 /* For allocation functions that keep their own free lists, we want to
195 account for the reuse of the memory. */
197 void dmalloc_reuse (foo, file, line, justref)
198 VOIDPTR foo;
199 const char *file;
200 int line;
201 int justref;
203 struct dmalloc_preamble *dp;
205 /* Get the pointer to the dmalloc header. */
206 dp = foo;
207 dp--;
209 /* If we just allocated this and are now referencing it, this
210 function would almost be a no-op, except that it would
211 increment the generation count needlessly. So just return
212 in this case. */
213 if (dp -> generation == dmalloc_generation)
214 return;
216 /* If this is longterm data, and we just made reference to it,
217 don't put it on the short-term list or change its name -
218 we don't need to know about this. */
219 if (dp -> generation < dmalloc_cutoff_generation && justref)
220 return;
222 /* Take it out of the place in the allocated list where it was. */
223 if (dp -> prev)
224 dp -> prev -> next = dp -> next;
225 if (dp -> next)
226 dp -> next -> prev = dp -> prev;
227 if (dp == dmalloc_list)
228 dmalloc_list = dp -> prev;
230 /* Account for its removal. */
231 if (dp -> generation >= dmalloc_cutoff_generation)
232 dmalloc_outstanding -= dp -> size;
233 else
234 dmalloc_longterm -= dp -> size;
236 /* Now put it at the head of the list. */
237 dp -> prev = dmalloc_list;
238 if (dmalloc_list)
239 dmalloc_list -> next = dp;
240 dmalloc_list = dp;
241 dp -> next = (struct dmalloc_preamble *)0;
243 /* Change the reference location information. */
244 dp -> file = file;
245 dp -> line = line;
247 /* Increment the generation. */
248 dp -> generation = dmalloc_generation++;
250 /* Account for it. */
251 dmalloc_outstanding += dp -> size;
254 void dmalloc_dump_outstanding ()
256 static unsigned long dmalloc_cutoff_point;
257 struct dmalloc_preamble *dp;
258 unsigned char *foo;
259 int i;
261 if (!dmalloc_cutoff_point)
262 dmalloc_cutoff_point = dmalloc_cutoff_generation;
263 for (dp = dmalloc_list; dp; dp = dp -> prev) {
264 if (dp -> generation <= dmalloc_cutoff_point)
265 break;
266 #if defined (DEBUG_MALLOC_POOL)
267 for (i = 0; i < DMLFSIZE; i++) {
268 if (dp -> low_fence [i] !=
269 (((unsigned long)
270 (&dp -> low_fence [i])) % 143) + 113)
272 log_error ("malloc fence modified: %s(%d)",
273 dp -> file, dp -> line);
274 abort ();
277 foo = (unsigned char *)dp;
278 for (i = DMDOFFSET; i < DMDSIZE; i++) {
279 if (foo [i + dp -> size] !=
280 (((unsigned long)
281 (&foo [i + dp -> size])) % 143) + 113) {
282 log_error ("malloc fence modified: %s(%d)",
283 dp -> file, dp -> line);
284 abort ();
287 #endif
288 #if defined (DEBUG_MEMORY_LEAKAGE) || \
289 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
290 /* Don't count data that's actually on a free list
291 somewhere. */
292 if (dp -> file) {
293 #if defined (DEBUG_RC_HISTORY)
294 int i, count, inhistory = 0, noted = 0;
296 /* If we have the info, see if this is actually
297 new garbage. */
298 if (rc_history_count < RC_HISTORY_MAX) {
299 count = rc_history_count;
300 } else
301 count = RC_HISTORY_MAX;
302 i = rc_history_index - 1;
303 if (i < 0)
304 i += RC_HISTORY_MAX;
306 do {
307 if (rc_history [i].addr == dp + 1) {
308 inhistory = 1;
309 if (!noted) {
310 log_info (" %s(%d): %d", dp -> file,
311 dp -> line, dp -> size);
312 noted = 1;
314 print_rc_hist_entry (i);
315 if (!rc_history [i].refcnt)
316 break;
318 if (--i < 0)
319 i = RC_HISTORY_MAX - 1;
320 } while (count--);
321 if (!inhistory)
322 #endif
323 log_info (" %s(%d): %d",
324 dp -> file, dp -> line, dp -> size);
326 #endif
328 if (dmalloc_list)
329 dmalloc_cutoff_point = dmalloc_list -> generation;
331 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
333 #if defined (DEBUG_RC_HISTORY)
334 static void print_rc_hist_entry (int i)
336 log_info (" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
337 rc_history [i].file, rc_history [i].line,
338 (unsigned long)rc_history [i].reference,
339 (unsigned long)rc_history [i].addr,
340 rc_history [i].refcnt);
343 void dump_rc_history (void *addr)
345 int i;
347 i = rc_history_index;
348 if (!rc_history [i].file)
349 i = 0;
350 else if (rc_history_count < RC_HISTORY_MAX) {
351 i -= rc_history_count;
352 if (i < 0)
353 i += RC_HISTORY_MAX;
355 rc_history_count = 0;
357 while (rc_history [i].file) {
358 if (!addr || addr == rc_history [i].addr)
359 print_rc_hist_entry (i);
360 ++i;
361 if (i == RC_HISTORY_MAX)
362 i = 0;
363 if (i == rc_history_index)
364 break;
367 void rc_history_next (int d)
369 #if defined (RC_HISTORY_COMPRESSION)
370 int i, j = 0, m, n = 0;
371 void *ap, *rp;
373 /* If we are decreasing the reference count, try to find the
374 entry where the reference was made and eliminate it; then
375 we can also eliminate this reference. */
376 if (d) {
377 m = rc_history_index - 1000;
378 if (m < -1)
379 m = -1;
380 ap = rc_history [rc_history_index].addr;
381 rp = rc_history [rc_history_index].reference;
382 for (i = rc_history_index - 1; i > m; i--) {
383 if (rc_history [i].addr == ap) {
384 if (rc_history [i].reference == rp) {
385 if (n > 10) {
386 for (n = i; n <= rc_history_index; n++)
387 print_rc_hist_entry (n);
388 n = 11;
390 memmove (&rc_history [i],
391 &rc_history [i + 1],
392 (unsigned)((rc_history_index - i) *
393 sizeof (struct rc_history_entry)));
394 --rc_history_count;
395 --rc_history_index;
396 for (j = i; j < rc_history_count; j++) {
397 if (rc_history [j].addr == ap)
398 --rc_history [j].refcnt;
400 if (n > 10) {
401 for (n = i; n <= rc_history_index; n++)
402 print_rc_hist_entry (n);
403 n = 11;
404 exit (0);
406 return;
411 #endif
412 if (++rc_history_index == RC_HISTORY_MAX)
413 rc_history_index = 0;
414 ++rc_history_count;
416 #endif
418 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
419 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
420 struct caller {
421 struct dmalloc_preamble *dp;
422 int count;
425 static int dmalloc_find_entry (struct dmalloc_preamble *dp,
426 struct caller *array,
427 int min, int max)
429 int middle;
430 int cmp;
432 middle = (min + max) / 2;
433 if (middle == min)
434 return middle;
435 if (array [middle].dp -> file == dp -> file) {
436 if (array [middle].dp -> line == dp -> line)
437 return middle;
438 else if (array [middle].dp -> line < dp -> line)
439 return dmalloc_find_entry (dp, array, middle, max);
440 else
441 return dmalloc_find_entry (dp, array, 0, middle);
442 } else if (array [middle].dp -> file < dp -> file)
443 return dmalloc_find_entry (dp, array, middle, max);
444 else
445 return dmalloc_find_entry (dp, array, 0, middle);
448 void omapi_print_dmalloc_usage_by_caller ()
450 struct dmalloc_preamble *dp;
451 unsigned char *foo;
452 int ccur, cmax, i, j;
453 struct caller cp [1024];
455 cmax = 1024;
456 ccur = 0;
458 memset (cp, 0, sizeof cp);
459 for (dp = dmalloc_list; dp; dp = dp -> prev) {
460 i = dmalloc_find_entry (dp, cp, 0, ccur);
461 if ((i == ccur ||
462 cp [i].dp -> file != dp -> file ||
463 cp [i].dp -> line != dp -> line) &&
464 ccur == cmax) {
465 log_error ("no space for memory usage summary.");
466 return;
468 if (i == ccur) {
469 cp [ccur++].dp = dp;
470 cp [i].count = 1;
471 } else if (cp [i].dp -> file < dp -> file ||
472 (cp [i].dp -> file == dp -> file &&
473 cp [i].dp -> line < dp -> line)) {
474 if (i + 1 != ccur)
475 memmove (cp + i + 2, cp + i + 1,
476 (ccur - i) * sizeof *cp);
477 cp [i + 1].dp = dp;
478 cp [i + 1].count = 1;
479 ccur++;
480 } else if (cp [i].dp -> file != dp -> file ||
481 cp [i].dp -> line != dp -> line) {
482 memmove (cp + i + 1,
483 cp + i, (ccur - i) * sizeof *cp);
484 cp [i].dp = dp;
485 cp [i].count = 1;
486 ccur++;
487 } else
488 cp [i].count++;
489 #if 0
490 printf ("%d\t%s:%d\n", i, dp -> file, dp -> line);
491 dump_rc_history (dp + 1);
492 #endif
494 for (i = 0; i < ccur; i++) {
495 printf ("%d\t%s:%d\t%d\n", i,
496 cp [i].dp -> file, cp [i].dp -> line, cp [i].count);
497 dump_rc_history (cp [i].dp + 1);
500 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
502 isc_result_t omapi_object_allocate (omapi_object_t **o,
503 omapi_object_type_t *type,
504 size_t size,
505 const char *file, int line)
507 size_t tsize;
508 omapi_object_t *foo;
509 isc_result_t status;
511 tsize = 0; /* XXXGCC -Wuninitialized */
513 if (type -> allocator) {
514 foo = (omapi_object_t *)0;
515 status = (*type -> allocator) (&foo, file, line);
516 tsize = type -> size;
517 } else {
518 status = ISC_R_NOMEMORY;
519 tsize = 0;
522 if (status == ISC_R_NOMEMORY) {
523 if (type -> sizer)
524 tsize = (*type -> sizer) (size);
525 else
526 tsize = type -> size;
528 /* Sanity check. */
529 if (tsize < sizeof (omapi_object_t))
530 return ISC_R_INVALIDARG;
532 foo = dmalloc (tsize, file, line);
533 if (!foo)
534 return ISC_R_NOMEMORY;
537 status = omapi_object_initialize (foo, type, size, tsize, file, line);
538 if (status != ISC_R_SUCCESS) {
539 if (type -> freer)
540 (*type -> freer) (foo, file, line);
541 else
542 dfree (foo, file, line);
543 return status;
545 return omapi_object_reference (o, foo, file, line);
548 isc_result_t omapi_object_initialize (omapi_object_t *o,
549 omapi_object_type_t *type,
550 size_t usize, size_t psize,
551 const char *file, int line)
553 memset (o, 0, psize);
554 o -> type = type;
555 if (type -> initialize)
556 (*type -> initialize) (o, file, line);
557 return ISC_R_SUCCESS;
560 isc_result_t omapi_object_reference (omapi_object_t **r,
561 omapi_object_t *h,
562 const char *file, int line)
564 if (!h || !r)
565 return ISC_R_INVALIDARG;
567 if (*r) {
568 #if defined (POINTER_DEBUG)
569 log_error ("%s(%d): reference store into non-null pointer!",
570 file, line);
571 abort ();
572 #else
573 return ISC_R_INVALIDARG;
574 #endif
576 *r = h;
577 h -> refcnt++;
578 rc_register (file, line, r, h, h -> refcnt, 0, h -> type -> rc_flag);
579 return ISC_R_SUCCESS;
582 isc_result_t omapi_object_dereference (omapi_object_t **h,
583 const char *file, int line)
585 int outer_reference = 0;
586 int inner_reference = 0;
587 int handle_reference = 0;
588 int extra_references;
589 omapi_object_t *p, *hp;
591 if (!h)
592 return ISC_R_INVALIDARG;
594 if (!*h) {
595 #if defined (POINTER_DEBUG)
596 log_error ("%s(%d): dereference of null pointer!", file, line);
597 abort ();
598 #else
599 return ISC_R_INVALIDARG;
600 #endif
603 if ((*h) -> refcnt <= 0) {
604 #if defined (POINTER_DEBUG)
605 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
606 file, line);
607 #if defined (DEBUG_RC_HISTORY)
608 dump_rc_history (*h);
609 #endif
610 abort ();
611 #else
612 *h = 0;
613 return ISC_R_INVALIDARG;
614 #endif
617 /* See if this object's inner object refers to it, but don't
618 count this as a reference if we're being asked to free the
619 reference from the inner object. */
620 if ((*h) -> inner && (*h) -> inner -> outer &&
621 h != &((*h) -> inner -> outer))
622 inner_reference = 1;
624 /* Ditto for the outer object. */
625 if ((*h) -> outer && (*h) -> outer -> inner &&
626 h != &((*h) -> outer -> inner))
627 outer_reference = 1;
629 /* Ditto for the outer object. The code below assumes that
630 the only reason we'd get a dereference from the handle
631 table is if this function does it - otherwise we'd have to
632 traverse the handle table to find the address where the
633 reference is stored and compare against that, and we don't
634 want to do that if we can avoid it. */
635 if ((*h) -> handle)
636 handle_reference = 1;
638 /* If we are getting rid of the last reference other than
639 references to inner and outer objects, or from the handle
640 table, then we must examine all the objects in either
641 direction to see if they hold any non-inner, non-outer,
642 non-handle-table references. If not, we need to free the
643 entire chain of objects. */
644 if ((*h) -> refcnt ==
645 inner_reference + outer_reference + handle_reference + 1) {
646 if (inner_reference || outer_reference || handle_reference) {
647 /* XXX we could check for a reference from the
648 handle table here. */
649 extra_references = 0;
650 for (p = (*h) -> inner;
651 p && !extra_references; p = p -> inner) {
652 extra_references += p -> refcnt;
653 if (p -> inner && p -> inner -> outer == p)
654 --extra_references;
655 if (p -> outer)
656 --extra_references;
657 if (p -> handle)
658 --extra_references;
660 for (p = (*h) -> outer;
661 p && !extra_references; p = p -> outer) {
662 extra_references += p -> refcnt;
663 if (p -> outer && p -> outer -> inner == p)
664 --extra_references;
665 if (p -> inner)
666 --extra_references;
667 if (p -> handle)
668 --extra_references;
670 } else
671 extra_references = 0;
673 if (!extra_references) {
674 hp = *h;
675 *h = 0;
676 hp -> refcnt--;
677 if (inner_reference)
678 omapi_object_dereference
679 (&hp -> inner, file, line);
680 if (outer_reference)
681 omapi_object_dereference
682 (&hp -> outer, file, line);
683 /* if (!hp -> type -> freer) */
684 rc_register (file, line, h, hp,
685 0, 1, hp -> type -> rc_flag);
686 if (hp -> type -> destroy)
687 (*(hp -> type -> destroy)) (hp, file, line);
688 if (hp -> type -> freer)
689 (hp -> type -> freer (hp, file, line));
690 else
691 dfree (hp, file, line);
692 } else {
693 (*h) -> refcnt--;
694 /* if (!(*h) -> type -> freer) */
695 rc_register (file, line,
696 h, *h, (*h) -> refcnt, 1,
697 (*h) -> type -> rc_flag);
699 } else {
700 (*h) -> refcnt--;
701 /* if (!(*h) -> type -> freer) */
702 rc_register (file, line, h, *h, (*h) -> refcnt, 1,
703 (*h) -> type -> rc_flag);
705 *h = 0;
706 return ISC_R_SUCCESS;
709 isc_result_t omapi_buffer_new (omapi_buffer_t **h,
710 const char *file, int line)
712 omapi_buffer_t *t;
713 isc_result_t status;
715 t = (omapi_buffer_t *)dmalloc (sizeof *t, file, line);
716 if (!t)
717 return ISC_R_NOMEMORY;
718 memset (t, 0, sizeof *t);
719 status = omapi_buffer_reference (h, t, file, line);
720 if (status != ISC_R_SUCCESS)
721 dfree (t, file, line);
722 (*h) -> head = sizeof ((*h) -> buf) - 1;
723 return status;
726 isc_result_t omapi_buffer_reference (omapi_buffer_t **r,
727 omapi_buffer_t *h,
728 const char *file, int line)
730 if (!h || !r)
731 return ISC_R_INVALIDARG;
733 if (*r) {
734 #if defined (POINTER_DEBUG)
735 log_error ("%s(%d): reference store into non-null pointer!",
736 file, line);
737 abort ();
738 #else
739 return ISC_R_INVALIDARG;
740 #endif
742 *r = h;
743 h -> refcnt++;
744 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
745 return ISC_R_SUCCESS;
748 isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
749 const char *file, int line)
751 if (!h)
752 return ISC_R_INVALIDARG;
754 if (!*h) {
755 #if defined (POINTER_DEBUG)
756 log_error ("%s(%d): dereference of null pointer!", file, line);
757 abort ();
758 #else
759 return ISC_R_INVALIDARG;
760 #endif
763 if ((*h) -> refcnt <= 0) {
764 #if defined (POINTER_DEBUG)
765 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
766 file, line);
767 #if defined (DEBUG_RC_HISTORY)
768 dump_rc_history (*h);
769 #endif
770 abort ();
771 #else
772 *h = 0;
773 return ISC_R_INVALIDARG;
774 #endif
777 --(*h) -> refcnt;
778 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
779 if ((*h) -> refcnt == 0)
780 dfree (*h, file, line);
781 *h = 0;
782 return ISC_R_SUCCESS;
785 isc_result_t omapi_typed_data_new (const char *file, int line,
786 omapi_typed_data_t **t,
787 omapi_datatype_t type, ...)
789 va_list l;
790 omapi_typed_data_t *new;
791 unsigned len;
792 unsigned val = 0;
793 int intval = 0;
794 char *s = NULL;
795 isc_result_t status;
796 omapi_object_t *obj = NULL;
798 va_start (l, type);
800 val = 0; /* XXXGCC -Wuninitialized */
801 intval = 0; /* XXXGCC -Wuninitialized */
802 s = NULL; /* XXXGCC -Wuninitialized */
803 obj = NULL; /* XXXGCC -Wuninitialized */
805 switch (type) {
806 case omapi_datatype_int:
807 len = OMAPI_TYPED_DATA_INT_LEN;
808 intval = va_arg (l, int);
809 break;
810 case omapi_datatype_string:
811 s = va_arg (l, char *);
812 val = strlen (s);
813 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
814 break;
815 case omapi_datatype_data:
816 val = va_arg (l, unsigned);
817 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
818 break;
819 case omapi_datatype_object:
820 len = OMAPI_TYPED_DATA_OBJECT_LEN;
821 obj = va_arg (l, omapi_object_t *);
822 break;
823 default:
824 va_end (l);
825 return ISC_R_INVALIDARG;
827 va_end (l);
829 new = dmalloc (len, file, line);
830 if (!new)
831 return ISC_R_NOMEMORY;
832 memset (new, 0, len);
834 switch (type) {
835 case omapi_datatype_int:
836 new -> u.integer = intval;
837 break;
838 case omapi_datatype_string:
839 memcpy (new -> u.buffer.value, s, val);
840 new -> u.buffer.len = val;
841 break;
842 case omapi_datatype_data:
843 new -> u.buffer.len = val;
844 break;
845 case omapi_datatype_object:
846 status = omapi_object_reference (&new -> u.object, obj,
847 file, line);
848 if (status != ISC_R_SUCCESS) {
849 dfree (new, file, line);
850 return status;
852 break;
854 new -> type = type;
856 return omapi_typed_data_reference (t, new, file, line);
859 isc_result_t omapi_typed_data_reference (omapi_typed_data_t **r,
860 omapi_typed_data_t *h,
861 const char *file, int line)
863 if (!h || !r)
864 return ISC_R_INVALIDARG;
866 if (*r) {
867 #if defined (POINTER_DEBUG)
868 log_error ("%s(%d): reference store into non-null pointer!", file, line);
869 abort ();
870 #else
871 return ISC_R_INVALIDARG;
872 #endif
874 *r = h;
875 h -> refcnt++;
876 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
877 return ISC_R_SUCCESS;
880 isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
881 const char *file, int line)
883 if (!h)
884 return ISC_R_INVALIDARG;
886 if (!*h) {
887 #if defined (POINTER_DEBUG)
888 log_error ("%s(%d): dereference of null pointer!", file, line);
889 abort ();
890 #else
891 return ISC_R_INVALIDARG;
892 #endif
895 if ((*h) -> refcnt <= 0) {
896 #if defined (POINTER_DEBUG)
897 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
898 file, line);
899 #if defined (DEBUG_RC_HISTORY)
900 dump_rc_history (*h);
901 #endif
902 abort ();
903 #else
904 *h = 0;
905 return ISC_R_INVALIDARG;
906 #endif
909 --((*h) -> refcnt);
910 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
911 if ((*h) -> refcnt <= 0 ) {
912 switch ((*h) -> type) {
913 case omapi_datatype_int:
914 case omapi_datatype_string:
915 case omapi_datatype_data:
916 default:
917 break;
918 case omapi_datatype_object:
919 omapi_object_dereference (&(*h) -> u.object,
920 file, line);
921 break;
923 dfree (*h, file, line);
925 *h = 0;
926 return ISC_R_SUCCESS;
929 isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len,
930 const char *file, int line)
932 omapi_data_string_t *new;
934 new = dmalloc (OMAPI_DATA_STRING_EMPTY_SIZE + len, file, line);
935 if (!new)
936 return ISC_R_NOMEMORY;
937 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
938 new -> len = len;
939 return omapi_data_string_reference (d, new, file, line);
942 isc_result_t omapi_data_string_reference (omapi_data_string_t **r,
943 omapi_data_string_t *h,
944 const char *file, int line)
946 if (!h || !r)
947 return ISC_R_INVALIDARG;
949 if (*r) {
950 #if defined (POINTER_DEBUG)
951 log_error ("%s(%d): reference store into non-null pointer!", file, line);
952 abort ();
953 #else
954 return ISC_R_INVALIDARG;
955 #endif
957 *r = h;
958 h -> refcnt++;
959 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
960 return ISC_R_SUCCESS;
963 isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
964 const char *file, int line)
966 if (!h)
967 return ISC_R_INVALIDARG;
969 if (!*h) {
970 #if defined (POINTER_DEBUG)
971 log_error ("%s(%d): dereference of null pointer!", file, line);
972 abort ();
973 #else
974 return ISC_R_INVALIDARG;
975 #endif
978 if ((*h) -> refcnt <= 0) {
979 #if defined (POINTER_DEBUG)
980 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
981 file, line);
982 #if defined (DEBUG_RC_HISTORY)
983 dump_rc_history (*h);
984 #endif
985 abort ();
986 #else
987 *h = 0;
988 return ISC_R_INVALIDARG;
989 #endif
992 --((*h) -> refcnt);
993 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
994 if ((*h) -> refcnt <= 0 ) {
995 dfree (*h, file, line);
997 *h = 0;
998 return ISC_R_SUCCESS;
1001 isc_result_t omapi_value_new (omapi_value_t **d,
1002 const char *file, int line)
1004 omapi_value_t *new;
1006 new = dmalloc (sizeof *new, file, line);
1007 if (!new)
1008 return ISC_R_NOMEMORY;
1009 memset (new, 0, sizeof *new);
1010 return omapi_value_reference (d, new, file, line);
1013 isc_result_t omapi_value_reference (omapi_value_t **r,
1014 omapi_value_t *h,
1015 const char *file, int line)
1017 if (!h || !r)
1018 return ISC_R_INVALIDARG;
1020 if (*r) {
1021 #if defined (POINTER_DEBUG)
1022 log_error ("%s(%d): reference store into non-null pointer!",
1023 file, line);
1024 abort ();
1025 #else
1026 return ISC_R_INVALIDARG;
1027 #endif
1029 *r = h;
1030 h -> refcnt++;
1031 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1032 return ISC_R_SUCCESS;
1035 isc_result_t omapi_value_dereference (omapi_value_t **h,
1036 const char *file, int line)
1038 if (!h)
1039 return ISC_R_INVALIDARG;
1041 if (!*h) {
1042 #if defined (POINTER_DEBUG)
1043 log_error ("%s(%d): dereference of null pointer!", file, line);
1044 abort ();
1045 #else
1046 return ISC_R_INVALIDARG;
1047 #endif
1050 if ((*h) -> refcnt <= 0) {
1051 #if defined (POINTER_DEBUG)
1052 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1053 file, line);
1054 #if defined (DEBUG_RC_HISTORY)
1055 dump_rc_history (*h);
1056 #endif
1057 abort ();
1058 #else
1059 *h = 0;
1060 return ISC_R_INVALIDARG;
1061 #endif
1064 --((*h) -> refcnt);
1065 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1066 if ((*h) -> refcnt == 0) {
1067 if ((*h) -> name)
1068 omapi_data_string_dereference (&(*h) -> name,
1069 file, line);
1070 if ((*h) -> value)
1071 omapi_typed_data_dereference (&(*h) -> value,
1072 file, line);
1073 dfree (*h, file, line);
1075 *h = 0;
1076 return ISC_R_SUCCESS;
1079 isc_result_t omapi_addr_list_new (omapi_addr_list_t **d, unsigned count,
1080 const char *file, int line)
1082 omapi_addr_list_t *new;
1084 new = dmalloc ((count * sizeof (omapi_addr_t)) +
1085 sizeof (omapi_addr_list_t), file, line);
1086 if (!new)
1087 return ISC_R_NOMEMORY;
1088 memset (new, 0, ((count * sizeof (omapi_addr_t)) +
1089 sizeof (omapi_addr_list_t)));
1090 new -> count = count;
1091 new -> addresses = (omapi_addr_t *)(new + 1);
1092 return omapi_addr_list_reference (d, new, file, line);
1095 isc_result_t omapi_addr_list_reference (omapi_addr_list_t **r,
1096 omapi_addr_list_t *h,
1097 const char *file, int line)
1099 if (!h || !r)
1100 return ISC_R_INVALIDARG;
1102 if (*r) {
1103 #if defined (POINTER_DEBUG)
1104 log_error ("%s(%d): reference store into non-null pointer!",
1105 file, line);
1106 abort ();
1107 #else
1108 return ISC_R_INVALIDARG;
1109 #endif
1111 *r = h;
1112 h -> refcnt++;
1113 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1114 return ISC_R_SUCCESS;
1117 isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h,
1118 const char *file, int line)
1120 if (!h)
1121 return ISC_R_INVALIDARG;
1123 if (!*h) {
1124 #if defined (POINTER_DEBUG)
1125 log_error ("%s(%d): dereference of null pointer!", file, line);
1126 abort ();
1127 #else
1128 return ISC_R_INVALIDARG;
1129 #endif
1132 if ((*h) -> refcnt <= 0) {
1133 #if defined (POINTER_DEBUG)
1134 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1135 file, line);
1136 #if defined (DEBUG_RC_HISTORY)
1137 dump_rc_history (*h);
1138 #endif
1139 abort ();
1140 #else
1141 *h = 0;
1142 return ISC_R_INVALIDARG;
1143 #endif
1146 --((*h) -> refcnt);
1147 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1148 if ((*h) -> refcnt <= 0 ) {
1149 dfree (*h, file, line);
1151 *h = 0;
1152 return ISC_R_SUCCESS;