3 Functions supporting memory allocation for the object management
7 * Copyright (c) 1999-2003 Internet Software Consortium.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of The Internet Software Consortium nor the names
20 * of its contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
24 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
31 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * This software has been written for the Internet Software Consortium
38 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
39 * To learn more about the Internet Software Consortium, see
40 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
41 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
42 * ``http://www.nominum.com''.
45 #include <omapip/omapip_p.h>
47 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
48 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
49 struct dmalloc_preamble *dmalloc_list;
50 unsigned long dmalloc_outstanding;
51 unsigned long dmalloc_longterm;
52 unsigned long dmalloc_generation;
53 unsigned long dmalloc_cutoff_generation;
56 #if defined (DEBUG_RC_HISTORY)
57 struct rc_history_entry rc_history [RC_HISTORY_MAX];
62 #if defined (DEBUG_RC_HISTORY)
63 static void print_rc_hist_entry (int);
66 VOIDPTR dmalloc (size, file, line)
71 unsigned char *foo = malloc (size + DMDSIZE);
74 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
75 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
76 struct dmalloc_preamble *dp;
80 bar = (VOIDPTR)(foo + DMDOFFSET);
81 memset (bar, 0, size);
83 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
84 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
85 dp = (struct dmalloc_preamble *)foo;
86 dp -> prev = dmalloc_list;
88 dmalloc_list -> next = dp;
90 dp -> next = (struct dmalloc_preamble *)0;
94 dp -> generation = dmalloc_generation++;
95 dmalloc_outstanding += size;
96 for (i = 0; i < DMLFSIZE; i++)
99 (&dp -> low_fence [i])) % 143) + 113;
100 for (i = DMDOFFSET; i < DMDSIZE; i++)
103 (&foo [i + size])) % 143) + 113;
104 #if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
105 /* Check _every_ entry in the pool! Very expensive. */
106 for (dp = dmalloc_list; dp; dp = dp -> prev) {
107 for (i = 0; i < DMLFSIZE; i++) {
108 if (dp -> low_fence [i] !=
110 (&dp -> low_fence [i])) % 143) + 113)
112 log_error ("malloc fence modified: %s(%d)",
113 dp -> file, dp -> line);
117 foo = (unsigned char *)dp;
118 for (i = DMDOFFSET; i < DMDSIZE; i++) {
119 if (foo [i + dp -> size] !=
121 (&foo [i + dp -> size])) % 143) + 113) {
122 log_error ("malloc fence modified: %s(%d)",
123 dp -> file, dp -> line);
130 #ifdef DEBUG_REFCNT_DMALLOC_FREE
131 rc_register (file, line, 0, foo + DMDOFFSET, 1, 0, RC_MALLOC);
136 void dfree (ptr, file, line)
142 log_error ("dfree %s(%d): free on null pointer.", file, line);
145 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
146 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
148 unsigned char *bar = ptr;
149 struct dmalloc_preamble *dp, *cur;
152 cur = (struct dmalloc_preamble *)bar;
153 for (dp = dmalloc_list; dp; dp = dp -> prev)
157 log_error ("%s(%d): freeing unknown memory: %lx",
158 file, line, (unsigned long)cur);
162 dp -> prev -> next = dp -> next;
164 dp -> next -> prev = dp -> prev;
165 if (dp == dmalloc_list)
166 dmalloc_list = dp -> prev;
167 if (dp -> generation >= dmalloc_cutoff_generation)
168 dmalloc_outstanding -= dp -> size;
170 dmalloc_longterm -= dp -> size;
172 for (i = 0; i < DMLFSIZE; i++) {
173 if (dp -> low_fence [i] !=
175 (&dp -> low_fence [i])) % 143) + 113)
177 log_error ("malloc fence modified: %s(%d)",
178 dp -> file, dp -> line);
182 for (i = DMDOFFSET; i < DMDSIZE; i++) {
183 if (bar [i + dp -> size] !=
185 (&bar [i + dp -> size])) % 143) + 113) {
186 log_error ("malloc fence modified: %s(%d)",
187 dp -> file, dp -> line);
194 #ifdef DEBUG_REFCNT_DMALLOC_FREE
195 rc_register (file, line,
196 0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);
201 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
202 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
203 /* For allocation functions that keep their own free lists, we want to
204 account for the reuse of the memory. */
206 void dmalloc_reuse (foo, file, line, justref)
212 struct dmalloc_preamble *dp;
214 /* Get the pointer to the dmalloc header. */
218 /* If we just allocated this and are now referencing it, this
219 function would almost be a no-op, except that it would
220 increment the generation count needlessly. So just return
222 if (dp -> generation == dmalloc_generation)
225 /* If this is longterm data, and we just made reference to it,
226 don't put it on the short-term list or change its name -
227 we don't need to know about this. */
228 if (dp -> generation < dmalloc_cutoff_generation && justref)
231 /* Take it out of the place in the allocated list where it was. */
233 dp -> prev -> next = dp -> next;
235 dp -> next -> prev = dp -> prev;
236 if (dp == dmalloc_list)
237 dmalloc_list = dp -> prev;
239 /* Account for its removal. */
240 if (dp -> generation >= dmalloc_cutoff_generation)
241 dmalloc_outstanding -= dp -> size;
243 dmalloc_longterm -= dp -> size;
245 /* Now put it at the head of the list. */
246 dp -> prev = dmalloc_list;
248 dmalloc_list -> next = dp;
250 dp -> next = (struct dmalloc_preamble *)0;
252 /* Change the reference location information. */
256 /* Increment the generation. */
257 dp -> generation = dmalloc_generation++;
259 /* Account for it. */
260 dmalloc_outstanding += dp -> size;
263 void dmalloc_dump_outstanding ()
265 static unsigned long dmalloc_cutoff_point;
266 struct dmalloc_preamble *dp;
270 if (!dmalloc_cutoff_point)
271 dmalloc_cutoff_point = dmalloc_cutoff_generation;
272 for (dp = dmalloc_list; dp; dp = dp -> prev) {
273 if (dp -> generation <= dmalloc_cutoff_point)
275 #if defined (DEBUG_MALLOC_POOL)
276 for (i = 0; i < DMLFSIZE; i++) {
277 if (dp -> low_fence [i] !=
279 (&dp -> low_fence [i])) % 143) + 113)
281 log_error ("malloc fence modified: %s(%d)",
282 dp -> file, dp -> line);
286 foo = (unsigned char *)dp;
287 for (i = DMDOFFSET; i < DMDSIZE; i++) {
288 if (foo [i + dp -> size] !=
290 (&foo [i + dp -> size])) % 143) + 113) {
291 log_error ("malloc fence modified: %s(%d)",
292 dp -> file, dp -> line);
297 #if defined (DEBUG_MEMORY_LEAKAGE) || \
298 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
299 /* Don't count data that's actually on a free list
302 #if defined (DEBUG_RC_HISTORY)
303 int i, count, inhistory = 0, noted = 0;
305 /* If we have the info, see if this is actually
307 if (rc_history_count < RC_HISTORY_MAX) {
308 count = rc_history_count;
310 count = RC_HISTORY_MAX;
311 i = rc_history_index - 1;
316 if (rc_history [i].addr == dp + 1) {
319 log_info (" %s(%d): %d", dp -> file,
320 dp -> line, dp -> size);
323 print_rc_hist_entry (i);
324 if (!rc_history [i].refcnt)
328 i = RC_HISTORY_MAX - 1;
332 log_info (" %s(%d): %d",
333 dp -> file, dp -> line, dp -> size);
338 dmalloc_cutoff_point = dmalloc_list -> generation;
340 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
342 #if defined (DEBUG_RC_HISTORY)
343 static void print_rc_hist_entry (int i)
345 log_info (" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
346 rc_history [i].file, rc_history [i].line,
347 (unsigned long)rc_history [i].reference,
348 (unsigned long)rc_history [i].addr,
349 rc_history [i].refcnt);
352 void dump_rc_history (void *addr)
356 i = rc_history_index;
357 if (!rc_history [i].file)
359 else if (rc_history_count < RC_HISTORY_MAX) {
360 i -= rc_history_count;
364 rc_history_count = 0;
366 while (rc_history [i].file) {
367 if (!addr || addr == rc_history [i].addr)
368 print_rc_hist_entry (i);
370 if (i == RC_HISTORY_MAX)
372 if (i == rc_history_index)
376 void rc_history_next (int d)
378 #if defined (RC_HISTORY_COMPRESSION)
379 int i, j = 0, m, n = 0;
382 /* If we are decreasing the reference count, try to find the
383 entry where the reference was made and eliminate it; then
384 we can also eliminate this reference. */
386 m = rc_history_index - 1000;
389 ap = rc_history [rc_history_index].addr;
390 rp = rc_history [rc_history_index].reference;
391 for (i = rc_history_index - 1; i > m; i--) {
392 if (rc_history [i].addr == ap) {
393 if (rc_history [i].reference == rp) {
395 for (n = i; n <= rc_history_index; n++)
396 print_rc_hist_entry (n);
399 memmove (&rc_history [i],
401 (unsigned)((rc_history_index - i) *
402 sizeof (struct rc_history_entry)));
405 for (j = i; j < rc_history_count; j++) {
406 if (rc_history [j].addr == ap)
407 --rc_history [j].refcnt;
410 for (n = i; n <= rc_history_index; n++)
411 print_rc_hist_entry (n);
421 if (++rc_history_index == RC_HISTORY_MAX)
422 rc_history_index = 0;
427 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
428 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
430 struct dmalloc_preamble *dp;
434 static int dmalloc_find_entry (struct dmalloc_preamble *dp,
435 struct caller *array,
441 middle = (min + max) / 2;
444 if (array [middle].dp -> file == dp -> file) {
445 if (array [middle].dp -> line == dp -> line)
447 else if (array [middle].dp -> line < dp -> line)
448 return dmalloc_find_entry (dp, array, middle, max);
450 return dmalloc_find_entry (dp, array, 0, middle);
451 } else if (array [middle].dp -> file < dp -> file)
452 return dmalloc_find_entry (dp, array, middle, max);
454 return dmalloc_find_entry (dp, array, 0, middle);
457 void omapi_print_dmalloc_usage_by_caller ()
459 struct dmalloc_preamble *dp;
461 int ccur, cmax, i, j;
462 struct caller cp [1024];
467 memset (cp, 0, sizeof cp);
468 for (dp = dmalloc_list; dp; dp = dp -> prev) {
469 i = dmalloc_find_entry (dp, cp, 0, ccur);
471 cp [i].dp -> file != dp -> file ||
472 cp [i].dp -> line != dp -> line) &&
474 log_error ("no space for memory usage summary.");
480 } else if (cp [i].dp -> file < dp -> file ||
481 (cp [i].dp -> file == dp -> file &&
482 cp [i].dp -> line < dp -> line)) {
484 memmove (cp + i + 2, cp + i + 1,
485 (ccur - i) * sizeof *cp);
487 cp [i + 1].count = 1;
489 } else if (cp [i].dp -> file != dp -> file ||
490 cp [i].dp -> line != dp -> line) {
492 cp + i, (ccur - i) * sizeof *cp);
499 printf ("%d\t%s:%d\n", i, dp -> file, dp -> line);
500 dump_rc_history (dp + 1);
503 for (i = 0; i < ccur; i++) {
504 printf ("%d\t%s:%d\t%d\n", i,
505 cp [i].dp -> file, cp [i].dp -> line, cp [i].count);
506 dump_rc_history (cp [i].dp + 1);
509 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
511 isc_result_t omapi_object_allocate (omapi_object_t **o,
512 omapi_object_type_t *type,
514 const char *file, int line)
520 if (type -> allocator) {
521 foo = (omapi_object_t *)0;
522 status = (*type -> allocator) (&foo, file, line);
523 tsize = type -> size;
525 status = ISC_R_NOMEMORY;
526 if (status == ISC_R_NOMEMORY) {
528 tsize = (*type -> sizer) (size);
530 tsize = type -> size;
533 if (tsize < sizeof (omapi_object_t))
534 return ISC_R_INVALIDARG;
536 foo = dmalloc (tsize, file, line);
538 return ISC_R_NOMEMORY;
541 status = omapi_object_initialize (foo, type, size, tsize, file, line);
542 if (status != ISC_R_SUCCESS) {
544 (*type -> freer) (foo, file, line);
546 dfree (foo, file, line);
549 return omapi_object_reference (o, foo, file, line);
552 isc_result_t omapi_object_initialize (omapi_object_t *o,
553 omapi_object_type_t *type,
554 size_t usize, size_t psize,
555 const char *file, int line)
557 memset (o, 0, psize);
559 if (type -> initialize)
560 (*type -> initialize) (o, file, line);
561 return ISC_R_SUCCESS;
564 isc_result_t omapi_object_reference (omapi_object_t **r,
566 const char *file, int line)
569 return ISC_R_INVALIDARG;
572 #if defined (POINTER_DEBUG)
573 log_error ("%s(%d): reference store into non-null pointer!",
577 return ISC_R_INVALIDARG;
582 rc_register (file, line, r, h, h -> refcnt, 0, h -> type -> rc_flag);
583 return ISC_R_SUCCESS;
586 isc_result_t omapi_object_dereference (omapi_object_t **h,
587 const char *file, int line)
589 int outer_reference = 0;
590 int inner_reference = 0;
591 int handle_reference = 0;
592 int extra_references;
593 omapi_object_t *p, *hp;
596 return ISC_R_INVALIDARG;
599 #if defined (POINTER_DEBUG)
600 log_error ("%s(%d): dereference of null pointer!", file, line);
603 return ISC_R_INVALIDARG;
607 if ((*h) -> refcnt <= 0) {
608 #if defined (POINTER_DEBUG)
609 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
611 #if defined (DEBUG_RC_HISTORY)
612 dump_rc_history (*h);
617 return ISC_R_INVALIDARG;
621 /* See if this object's inner object refers to it, but don't
622 count this as a reference if we're being asked to free the
623 reference from the inner object. */
624 if ((*h) -> inner && (*h) -> inner -> outer &&
625 h != &((*h) -> inner -> outer))
628 /* Ditto for the outer object. */
629 if ((*h) -> outer && (*h) -> outer -> inner &&
630 h != &((*h) -> outer -> inner))
633 /* Ditto for the outer object. The code below assumes that
634 the only reason we'd get a dereference from the handle
635 table is if this function does it - otherwise we'd have to
636 traverse the handle table to find the address where the
637 reference is stored and compare against that, and we don't
638 want to do that if we can avoid it. */
640 handle_reference = 1;
642 /* If we are getting rid of the last reference other than
643 references to inner and outer objects, or from the handle
644 table, then we must examine all the objects in either
645 direction to see if they hold any non-inner, non-outer,
646 non-handle-table references. If not, we need to free the
647 entire chain of objects. */
648 if ((*h) -> refcnt ==
649 inner_reference + outer_reference + handle_reference + 1) {
650 if (inner_reference || outer_reference || handle_reference) {
651 /* XXX we could check for a reference from the
652 handle table here. */
653 extra_references = 0;
654 for (p = (*h) -> inner;
655 p && !extra_references; p = p -> inner) {
656 extra_references += p -> refcnt;
657 if (p -> inner && p -> inner -> outer == p)
664 for (p = (*h) -> outer;
665 p && !extra_references; p = p -> outer) {
666 extra_references += p -> refcnt;
667 if (p -> outer && p -> outer -> inner == p)
675 extra_references = 0;
677 if (!extra_references) {
682 omapi_object_dereference
683 (&hp -> inner, file, line);
685 omapi_object_dereference
686 (&hp -> outer, file, line);
687 /* if (!hp -> type -> freer) */
688 rc_register (file, line, h, hp,
689 0, 1, hp -> type -> rc_flag);
690 if (hp -> type -> destroy)
691 (*(hp -> type -> destroy)) (hp, file, line);
692 if (hp -> type -> freer)
693 (hp -> type -> freer (hp, file, line));
695 dfree (hp, file, line);
698 /* if (!(*h) -> type -> freer) */
699 rc_register (file, line,
700 h, *h, (*h) -> refcnt, 1,
701 (*h) -> type -> rc_flag);
705 /* if (!(*h) -> type -> freer) */
706 rc_register (file, line, h, *h, (*h) -> refcnt, 1,
707 (*h) -> type -> rc_flag);
710 return ISC_R_SUCCESS;
713 isc_result_t omapi_buffer_new (omapi_buffer_t **h,
714 const char *file, int line)
719 t = (omapi_buffer_t *)dmalloc (sizeof *t, file, line);
721 return ISC_R_NOMEMORY;
722 memset (t, 0, sizeof *t);
723 status = omapi_buffer_reference (h, t, file, line);
724 if (status != ISC_R_SUCCESS)
725 dfree (t, file, line);
726 (*h) -> head = sizeof ((*h) -> buf) - 1;
730 isc_result_t omapi_buffer_reference (omapi_buffer_t **r,
732 const char *file, int line)
735 return ISC_R_INVALIDARG;
738 #if defined (POINTER_DEBUG)
739 log_error ("%s(%d): reference store into non-null pointer!",
743 return ISC_R_INVALIDARG;
748 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
749 return ISC_R_SUCCESS;
752 isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
753 const char *file, int line)
756 return ISC_R_INVALIDARG;
759 #if defined (POINTER_DEBUG)
760 log_error ("%s(%d): dereference of null pointer!", file, line);
763 return ISC_R_INVALIDARG;
767 if ((*h) -> refcnt <= 0) {
768 #if defined (POINTER_DEBUG)
769 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
771 #if defined (DEBUG_RC_HISTORY)
772 dump_rc_history (*h);
777 return ISC_R_INVALIDARG;
782 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
783 if ((*h) -> refcnt == 0)
784 dfree (*h, file, line);
786 return ISC_R_SUCCESS;
789 isc_result_t omapi_typed_data_new (const char *file, int line,
790 omapi_typed_data_t **t,
791 omapi_datatype_t type, ...)
794 omapi_typed_data_t *new;
805 case omapi_datatype_int:
806 len = OMAPI_TYPED_DATA_INT_LEN;
807 intval = va_arg (l, int);
809 case omapi_datatype_string:
810 s = va_arg (l, char *);
812 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
814 case omapi_datatype_data:
815 val = va_arg (l, unsigned);
816 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
818 case omapi_datatype_object:
819 len = OMAPI_TYPED_DATA_OBJECT_LEN;
820 obj = va_arg (l, omapi_object_t *);
824 return ISC_R_INVALIDARG;
828 new = dmalloc (len, file, line);
830 return ISC_R_NOMEMORY;
831 memset (new, 0, len);
834 case omapi_datatype_int:
835 new -> u.integer = intval;
837 case omapi_datatype_string:
838 memcpy (new -> u.buffer.value, s, val);
839 new -> u.buffer.len = val;
841 case omapi_datatype_data:
842 new -> u.buffer.len = val;
844 case omapi_datatype_object:
845 status = omapi_object_reference (&new -> u.object, obj,
847 if (status != ISC_R_SUCCESS) {
848 dfree (new, file, line);
855 return omapi_typed_data_reference (t, new, file, line);
858 isc_result_t omapi_typed_data_reference (omapi_typed_data_t **r,
859 omapi_typed_data_t *h,
860 const char *file, int line)
863 return ISC_R_INVALIDARG;
866 #if defined (POINTER_DEBUG)
867 log_error ("%s(%d): reference store into non-null pointer!", file, line);
870 return ISC_R_INVALIDARG;
875 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
876 return ISC_R_SUCCESS;
879 isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
880 const char *file, int line)
883 return ISC_R_INVALIDARG;
886 #if defined (POINTER_DEBUG)
887 log_error ("%s(%d): dereference of null pointer!", file, line);
890 return ISC_R_INVALIDARG;
894 if ((*h) -> refcnt <= 0) {
895 #if defined (POINTER_DEBUG)
896 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
898 #if defined (DEBUG_RC_HISTORY)
899 dump_rc_history (*h);
904 return ISC_R_INVALIDARG;
909 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
910 if ((*h) -> refcnt <= 0 ) {
911 switch ((*h) -> type) {
912 case omapi_datatype_int:
913 case omapi_datatype_string:
914 case omapi_datatype_data:
917 case omapi_datatype_object:
918 omapi_object_dereference (&(*h) -> u.object,
922 dfree (*h, file, line);
925 return ISC_R_SUCCESS;
928 isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len,
929 const char *file, int line)
931 omapi_data_string_t *new;
933 new = dmalloc (OMAPI_DATA_STRING_EMPTY_SIZE + len, file, line);
935 return ISC_R_NOMEMORY;
936 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
938 return omapi_data_string_reference (d, new, file, line);
941 isc_result_t omapi_data_string_reference (omapi_data_string_t **r,
942 omapi_data_string_t *h,
943 const char *file, int line)
946 return ISC_R_INVALIDARG;
949 #if defined (POINTER_DEBUG)
950 log_error ("%s(%d): reference store into non-null pointer!", file, line);
953 return ISC_R_INVALIDARG;
958 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
959 return ISC_R_SUCCESS;
962 isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
963 const char *file, int line)
966 return ISC_R_INVALIDARG;
969 #if defined (POINTER_DEBUG)
970 log_error ("%s(%d): dereference of null pointer!", file, line);
973 return ISC_R_INVALIDARG;
977 if ((*h) -> refcnt <= 0) {
978 #if defined (POINTER_DEBUG)
979 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
981 #if defined (DEBUG_RC_HISTORY)
982 dump_rc_history (*h);
987 return ISC_R_INVALIDARG;
992 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
993 if ((*h) -> refcnt <= 0 ) {
994 dfree (*h, file, line);
997 return ISC_R_SUCCESS;
1000 isc_result_t omapi_value_new (omapi_value_t **d,
1001 const char *file, int line)
1005 new = dmalloc (sizeof *new, file, line);
1007 return ISC_R_NOMEMORY;
1008 memset (new, 0, sizeof *new);
1009 return omapi_value_reference (d, new, file, line);
1012 isc_result_t omapi_value_reference (omapi_value_t **r,
1014 const char *file, int line)
1017 return ISC_R_INVALIDARG;
1020 #if defined (POINTER_DEBUG)
1021 log_error ("%s(%d): reference store into non-null pointer!",
1025 return ISC_R_INVALIDARG;
1030 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1031 return ISC_R_SUCCESS;
1034 isc_result_t omapi_value_dereference (omapi_value_t **h,
1035 const char *file, int line)
1038 return ISC_R_INVALIDARG;
1041 #if defined (POINTER_DEBUG)
1042 log_error ("%s(%d): dereference of null pointer!", file, line);
1045 return ISC_R_INVALIDARG;
1049 if ((*h) -> refcnt <= 0) {
1050 #if defined (POINTER_DEBUG)
1051 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1053 #if defined (DEBUG_RC_HISTORY)
1054 dump_rc_history (*h);
1059 return ISC_R_INVALIDARG;
1064 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1065 if ((*h) -> refcnt == 0) {
1067 omapi_data_string_dereference (&(*h) -> name,
1070 omapi_typed_data_dereference (&(*h) -> value,
1072 dfree (*h, file, line);
1075 return ISC_R_SUCCESS;
1078 isc_result_t omapi_addr_list_new (omapi_addr_list_t **d, unsigned count,
1079 const char *file, int line)
1081 omapi_addr_list_t *new;
1083 new = dmalloc ((count * sizeof (omapi_addr_t)) +
1084 sizeof (omapi_addr_list_t), file, line);
1086 return ISC_R_NOMEMORY;
1087 memset (new, 0, ((count * sizeof (omapi_addr_t)) +
1088 sizeof (omapi_addr_list_t)));
1089 new -> count = count;
1090 new -> addresses = (omapi_addr_t *)(new + 1);
1091 return omapi_addr_list_reference (d, new, file, line);
1094 isc_result_t omapi_addr_list_reference (omapi_addr_list_t **r,
1095 omapi_addr_list_t *h,
1096 const char *file, int line)
1099 return ISC_R_INVALIDARG;
1102 #if defined (POINTER_DEBUG)
1103 log_error ("%s(%d): reference store into non-null pointer!",
1107 return ISC_R_INVALIDARG;
1112 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1113 return ISC_R_SUCCESS;
1116 isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h,
1117 const char *file, int line)
1120 return ISC_R_INVALIDARG;
1123 #if defined (POINTER_DEBUG)
1124 log_error ("%s(%d): dereference of null pointer!", file, line);
1127 return ISC_R_INVALIDARG;
1131 if ((*h) -> refcnt <= 0) {
1132 #if defined (POINTER_DEBUG)
1133 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1135 #if defined (DEBUG_RC_HISTORY)
1136 dump_rc_history (*h);
1141 return ISC_R_INVALIDARG;
1146 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1147 if ((*h) -> refcnt <= 0 ) {
1148 dfree (*h, file, line);
1151 return ISC_R_SUCCESS;