revert between 56095 -> 55830 in arch
[AROS.git] / workbench / network / stacks / AROSTCP / dhcp / omapip / alloc.c
blob5716ae8ff17c9ddb768f45b1783aec04405bad9a
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 __unused int i;
64 VOIDPTR *bar;
65 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
66 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
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 if (type -> allocator) {
512 foo = (omapi_object_t *)0;
513 status = (*type -> allocator) (&foo, file, line);
514 tsize = type -> size;
515 } else {
516 status = ISC_R_NOMEMORY;
517 tsize = 0;
520 if (status == ISC_R_NOMEMORY) {
521 if (type -> sizer)
522 tsize = (*type -> sizer) (size);
523 else
524 tsize = type -> size;
526 /* Sanity check. */
527 if (tsize < sizeof (omapi_object_t))
528 return ISC_R_INVALIDARG;
530 foo = dmalloc (tsize, file, line);
531 if (!foo)
532 return ISC_R_NOMEMORY;
535 status = omapi_object_initialize (foo, type, size, tsize, file, line);
536 if (status != ISC_R_SUCCESS) {
537 if (type -> freer)
538 (*type -> freer) (foo, file, line);
539 else
540 dfree (foo, file, line);
541 return status;
543 return omapi_object_reference (o, foo, file, line);
546 isc_result_t omapi_object_initialize (omapi_object_t *o,
547 omapi_object_type_t *type,
548 size_t usize, size_t psize,
549 const char *file, int line)
551 memset (o, 0, psize);
552 o -> type = type;
553 if (type -> initialize)
554 (*type -> initialize) (o, file, line);
555 return ISC_R_SUCCESS;
558 isc_result_t omapi_object_reference (omapi_object_t **r,
559 omapi_object_t *h,
560 const char *file, int line)
562 if (!h || !r)
563 return ISC_R_INVALIDARG;
565 if (*r) {
566 #if defined (POINTER_DEBUG)
567 log_error ("%s(%d): reference store into non-null pointer!",
568 file, line);
569 abort ();
570 #else
571 return ISC_R_INVALIDARG;
572 #endif
574 *r = h;
575 h -> refcnt++;
576 rc_register (file, line, r, h, h -> refcnt, 0, h -> type -> rc_flag);
577 return ISC_R_SUCCESS;
580 isc_result_t omapi_object_dereference (omapi_object_t **h,
581 const char *file, int line)
583 int outer_reference = 0;
584 int inner_reference = 0;
585 int handle_reference = 0;
586 int extra_references;
587 omapi_object_t *p, *hp;
589 if (!h)
590 return ISC_R_INVALIDARG;
592 if (!*h) {
593 #if defined (POINTER_DEBUG)
594 log_error ("%s(%d): dereference of null pointer!", file, line);
595 abort ();
596 #else
597 return ISC_R_INVALIDARG;
598 #endif
601 if ((*h) -> refcnt <= 0) {
602 #if defined (POINTER_DEBUG)
603 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
604 file, line);
605 #if defined (DEBUG_RC_HISTORY)
606 dump_rc_history (*h);
607 #endif
608 abort ();
609 #else
610 *h = 0;
611 return ISC_R_INVALIDARG;
612 #endif
615 /* See if this object's inner object refers to it, but don't
616 count this as a reference if we're being asked to free the
617 reference from the inner object. */
618 if ((*h) -> inner && (*h) -> inner -> outer &&
619 h != &((*h) -> inner -> outer))
620 inner_reference = 1;
622 /* Ditto for the outer object. */
623 if ((*h) -> outer && (*h) -> outer -> inner &&
624 h != &((*h) -> outer -> inner))
625 outer_reference = 1;
627 /* Ditto for the outer object. The code below assumes that
628 the only reason we'd get a dereference from the handle
629 table is if this function does it - otherwise we'd have to
630 traverse the handle table to find the address where the
631 reference is stored and compare against that, and we don't
632 want to do that if we can avoid it. */
633 if ((*h) -> handle)
634 handle_reference = 1;
636 /* If we are getting rid of the last reference other than
637 references to inner and outer objects, or from the handle
638 table, then we must examine all the objects in either
639 direction to see if they hold any non-inner, non-outer,
640 non-handle-table references. If not, we need to free the
641 entire chain of objects. */
642 if ((*h) -> refcnt ==
643 inner_reference + outer_reference + handle_reference + 1) {
644 if (inner_reference || outer_reference || handle_reference) {
645 /* XXX we could check for a reference from the
646 handle table here. */
647 extra_references = 0;
648 for (p = (*h) -> inner;
649 p && !extra_references; p = p -> inner) {
650 extra_references += p -> refcnt;
651 if (p -> inner && p -> inner -> outer == p)
652 --extra_references;
653 if (p -> outer)
654 --extra_references;
655 if (p -> handle)
656 --extra_references;
658 for (p = (*h) -> outer;
659 p && !extra_references; p = p -> outer) {
660 extra_references += p -> refcnt;
661 if (p -> outer && p -> outer -> inner == p)
662 --extra_references;
663 if (p -> inner)
664 --extra_references;
665 if (p -> handle)
666 --extra_references;
668 } else
669 extra_references = 0;
671 if (!extra_references) {
672 hp = *h;
673 *h = 0;
674 hp -> refcnt--;
675 if (inner_reference)
676 omapi_object_dereference
677 (&hp -> inner, file, line);
678 if (outer_reference)
679 omapi_object_dereference
680 (&hp -> outer, file, line);
681 /* if (!hp -> type -> freer) */
682 rc_register (file, line, h, hp,
683 0, 1, hp -> type -> rc_flag);
684 if (hp -> type -> destroy)
685 (*(hp -> type -> destroy)) (hp, file, line);
686 if (hp -> type -> freer)
687 (hp -> type -> freer (hp, file, line));
688 else
689 dfree (hp, file, line);
690 } else {
691 (*h) -> refcnt--;
692 /* if (!(*h) -> type -> freer) */
693 rc_register (file, line,
694 h, *h, (*h) -> refcnt, 1,
695 (*h) -> type -> rc_flag);
697 } else {
698 (*h) -> refcnt--;
699 /* if (!(*h) -> type -> freer) */
700 rc_register (file, line, h, *h, (*h) -> refcnt, 1,
701 (*h) -> type -> rc_flag);
703 *h = 0;
704 return ISC_R_SUCCESS;
707 isc_result_t omapi_buffer_new (omapi_buffer_t **h,
708 const char *file, int line)
710 omapi_buffer_t *t;
711 isc_result_t status;
713 t = (omapi_buffer_t *)dmalloc (sizeof *t, file, line);
714 if (!t)
715 return ISC_R_NOMEMORY;
716 memset (t, 0, sizeof *t);
717 status = omapi_buffer_reference (h, t, file, line);
718 if (status != ISC_R_SUCCESS)
719 dfree (t, file, line);
720 (*h) -> head = sizeof ((*h) -> buf) - 1;
721 return status;
724 isc_result_t omapi_buffer_reference (omapi_buffer_t **r,
725 omapi_buffer_t *h,
726 const char *file, int line)
728 if (!h || !r)
729 return ISC_R_INVALIDARG;
731 if (*r) {
732 #if defined (POINTER_DEBUG)
733 log_error ("%s(%d): reference store into non-null pointer!",
734 file, line);
735 abort ();
736 #else
737 return ISC_R_INVALIDARG;
738 #endif
740 *r = h;
741 h -> refcnt++;
742 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
743 return ISC_R_SUCCESS;
746 isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
747 const char *file, int line)
749 if (!h)
750 return ISC_R_INVALIDARG;
752 if (!*h) {
753 #if defined (POINTER_DEBUG)
754 log_error ("%s(%d): dereference of null pointer!", file, line);
755 abort ();
756 #else
757 return ISC_R_INVALIDARG;
758 #endif
761 if ((*h) -> refcnt <= 0) {
762 #if defined (POINTER_DEBUG)
763 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
764 file, line);
765 #if defined (DEBUG_RC_HISTORY)
766 dump_rc_history (*h);
767 #endif
768 abort ();
769 #else
770 *h = 0;
771 return ISC_R_INVALIDARG;
772 #endif
775 --(*h) -> refcnt;
776 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
777 if ((*h) -> refcnt == 0)
778 dfree (*h, file, line);
779 *h = 0;
780 return ISC_R_SUCCESS;
783 isc_result_t omapi_typed_data_new (const char *file, int line,
784 omapi_typed_data_t **t,
785 omapi_datatype_t type, ...)
787 va_list l;
788 omapi_typed_data_t *new;
789 unsigned len;
790 unsigned val = 0;
791 int intval = 0;
792 char *s = NULL;
793 isc_result_t status;
794 omapi_object_t *obj = NULL;
796 va_start (l, type);
798 switch (type) {
799 case omapi_datatype_int:
800 len = OMAPI_TYPED_DATA_INT_LEN;
801 intval = va_arg (l, int);
802 break;
803 case omapi_datatype_string:
804 s = va_arg (l, char *);
805 val = strlen (s);
806 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
807 break;
808 case omapi_datatype_data:
809 val = va_arg (l, unsigned);
810 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
811 break;
812 case omapi_datatype_object:
813 len = OMAPI_TYPED_DATA_OBJECT_LEN;
814 obj = va_arg (l, omapi_object_t *);
815 break;
816 default:
817 va_end (l);
818 return ISC_R_INVALIDARG;
820 va_end (l);
822 new = dmalloc (len, file, line);
823 if (!new)
824 return ISC_R_NOMEMORY;
825 memset (new, 0, len);
827 switch (type) {
828 case omapi_datatype_int:
829 new -> u.integer = intval;
830 break;
831 case omapi_datatype_string:
832 memcpy (new -> u.buffer.value, s, val);
833 new -> u.buffer.len = val;
834 break;
835 case omapi_datatype_data:
836 new -> u.buffer.len = val;
837 break;
838 case omapi_datatype_object:
839 status = omapi_object_reference (&new -> u.object, obj,
840 file, line);
841 if (status != ISC_R_SUCCESS) {
842 dfree (new, file, line);
843 return status;
845 break;
847 new -> type = type;
849 return omapi_typed_data_reference (t, new, file, line);
852 isc_result_t omapi_typed_data_reference (omapi_typed_data_t **r,
853 omapi_typed_data_t *h,
854 const char *file, int line)
856 if (!h || !r)
857 return ISC_R_INVALIDARG;
859 if (*r) {
860 #if defined (POINTER_DEBUG)
861 log_error ("%s(%d): reference store into non-null pointer!", file, line);
862 abort ();
863 #else
864 return ISC_R_INVALIDARG;
865 #endif
867 *r = h;
868 h -> refcnt++;
869 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
870 return ISC_R_SUCCESS;
873 isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
874 const char *file, int line)
876 if (!h)
877 return ISC_R_INVALIDARG;
879 if (!*h) {
880 #if defined (POINTER_DEBUG)
881 log_error ("%s(%d): dereference of null pointer!", file, line);
882 abort ();
883 #else
884 return ISC_R_INVALIDARG;
885 #endif
888 if ((*h) -> refcnt <= 0) {
889 #if defined (POINTER_DEBUG)
890 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
891 file, line);
892 #if defined (DEBUG_RC_HISTORY)
893 dump_rc_history (*h);
894 #endif
895 abort ();
896 #else
897 *h = 0;
898 return ISC_R_INVALIDARG;
899 #endif
902 --((*h) -> refcnt);
903 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
904 if ((*h) -> refcnt <= 0 ) {
905 switch ((*h) -> type) {
906 case omapi_datatype_int:
907 case omapi_datatype_string:
908 case omapi_datatype_data:
909 default:
910 break;
911 case omapi_datatype_object:
912 omapi_object_dereference (&(*h) -> u.object,
913 file, line);
914 break;
916 dfree (*h, file, line);
918 *h = 0;
919 return ISC_R_SUCCESS;
922 isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len,
923 const char *file, int line)
925 omapi_data_string_t *new;
927 new = dmalloc (OMAPI_DATA_STRING_EMPTY_SIZE + len, file, line);
928 if (!new)
929 return ISC_R_NOMEMORY;
930 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
931 new -> len = len;
932 return omapi_data_string_reference (d, new, file, line);
935 isc_result_t omapi_data_string_reference (omapi_data_string_t **r,
936 omapi_data_string_t *h,
937 const char *file, int line)
939 if (!h || !r)
940 return ISC_R_INVALIDARG;
942 if (*r) {
943 #if defined (POINTER_DEBUG)
944 log_error ("%s(%d): reference store into non-null pointer!", file, line);
945 abort ();
946 #else
947 return ISC_R_INVALIDARG;
948 #endif
950 *r = h;
951 h -> refcnt++;
952 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
953 return ISC_R_SUCCESS;
956 isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
957 const char *file, int line)
959 if (!h)
960 return ISC_R_INVALIDARG;
962 if (!*h) {
963 #if defined (POINTER_DEBUG)
964 log_error ("%s(%d): dereference of null pointer!", file, line);
965 abort ();
966 #else
967 return ISC_R_INVALIDARG;
968 #endif
971 if ((*h) -> refcnt <= 0) {
972 #if defined (POINTER_DEBUG)
973 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
974 file, line);
975 #if defined (DEBUG_RC_HISTORY)
976 dump_rc_history (*h);
977 #endif
978 abort ();
979 #else
980 *h = 0;
981 return ISC_R_INVALIDARG;
982 #endif
985 --((*h) -> refcnt);
986 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
987 if ((*h) -> refcnt <= 0 ) {
988 dfree (*h, file, line);
990 *h = 0;
991 return ISC_R_SUCCESS;
994 isc_result_t omapi_value_new (omapi_value_t **d,
995 const char *file, int line)
997 omapi_value_t *new;
999 new = dmalloc (sizeof *new, file, line);
1000 if (!new)
1001 return ISC_R_NOMEMORY;
1002 memset (new, 0, sizeof *new);
1003 return omapi_value_reference (d, new, file, line);
1006 isc_result_t omapi_value_reference (omapi_value_t **r,
1007 omapi_value_t *h,
1008 const char *file, int line)
1010 if (!h || !r)
1011 return ISC_R_INVALIDARG;
1013 if (*r) {
1014 #if defined (POINTER_DEBUG)
1015 log_error ("%s(%d): reference store into non-null pointer!",
1016 file, line);
1017 abort ();
1018 #else
1019 return ISC_R_INVALIDARG;
1020 #endif
1022 *r = h;
1023 h -> refcnt++;
1024 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1025 return ISC_R_SUCCESS;
1028 isc_result_t omapi_value_dereference (omapi_value_t **h,
1029 const char *file, int line)
1031 if (!h)
1032 return ISC_R_INVALIDARG;
1034 if (!*h) {
1035 #if defined (POINTER_DEBUG)
1036 log_error ("%s(%d): dereference of null pointer!", file, line);
1037 abort ();
1038 #else
1039 return ISC_R_INVALIDARG;
1040 #endif
1043 if ((*h) -> refcnt <= 0) {
1044 #if defined (POINTER_DEBUG)
1045 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1046 file, line);
1047 #if defined (DEBUG_RC_HISTORY)
1048 dump_rc_history (*h);
1049 #endif
1050 abort ();
1051 #else
1052 *h = 0;
1053 return ISC_R_INVALIDARG;
1054 #endif
1057 --((*h) -> refcnt);
1058 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1059 if ((*h) -> refcnt == 0) {
1060 if ((*h) -> name)
1061 omapi_data_string_dereference (&(*h) -> name,
1062 file, line);
1063 if ((*h) -> value)
1064 omapi_typed_data_dereference (&(*h) -> value,
1065 file, line);
1066 dfree (*h, file, line);
1068 *h = 0;
1069 return ISC_R_SUCCESS;
1072 isc_result_t omapi_addr_list_new (omapi_addr_list_t **d, unsigned count,
1073 const char *file, int line)
1075 omapi_addr_list_t *new;
1077 new = dmalloc ((count * sizeof (omapi_addr_t)) +
1078 sizeof (omapi_addr_list_t), file, line);
1079 if (!new)
1080 return ISC_R_NOMEMORY;
1081 memset (new, 0, ((count * sizeof (omapi_addr_t)) +
1082 sizeof (omapi_addr_list_t)));
1083 new -> count = count;
1084 new -> addresses = (omapi_addr_t *)(new + 1);
1085 return omapi_addr_list_reference (d, new, file, line);
1088 isc_result_t omapi_addr_list_reference (omapi_addr_list_t **r,
1089 omapi_addr_list_t *h,
1090 const char *file, int line)
1092 if (!h || !r)
1093 return ISC_R_INVALIDARG;
1095 if (*r) {
1096 #if defined (POINTER_DEBUG)
1097 log_error ("%s(%d): reference store into non-null pointer!",
1098 file, line);
1099 abort ();
1100 #else
1101 return ISC_R_INVALIDARG;
1102 #endif
1104 *r = h;
1105 h -> refcnt++;
1106 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1107 return ISC_R_SUCCESS;
1110 isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h,
1111 const char *file, int line)
1113 if (!h)
1114 return ISC_R_INVALIDARG;
1116 if (!*h) {
1117 #if defined (POINTER_DEBUG)
1118 log_error ("%s(%d): dereference of null pointer!", file, line);
1119 abort ();
1120 #else
1121 return ISC_R_INVALIDARG;
1122 #endif
1125 if ((*h) -> refcnt <= 0) {
1126 #if defined (POINTER_DEBUG)
1127 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1128 file, line);
1129 #if defined (DEBUG_RC_HISTORY)
1130 dump_rc_history (*h);
1131 #endif
1132 abort ();
1133 #else
1134 *h = 0;
1135 return ISC_R_INVALIDARG;
1136 #endif
1139 --((*h) -> refcnt);
1140 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1141 if ((*h) -> refcnt <= 0 ) {
1142 dfree (*h, file, line);
1144 *h = 0;
1145 return ISC_R_SUCCESS;