3 Functions supporting memory allocation for the object management
7 * Copyright (c) 2004-2007 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.
24 * Redwood City, CA 94063
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''.
38 #include <omapip/omapip_p.h>
40 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
41 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
42 struct dmalloc_preamble
*dmalloc_list
;
43 unsigned long dmalloc_outstanding
;
44 unsigned long dmalloc_longterm
;
45 unsigned long dmalloc_generation
;
46 unsigned long dmalloc_cutoff_generation
;
49 #if defined (DEBUG_RC_HISTORY)
50 struct rc_history_entry rc_history
[RC_HISTORY_MAX
];
55 #if defined (DEBUG_RC_HISTORY)
56 static void print_rc_hist_entry (int);
60 dmalloc(unsigned size
, const char *file
, int line
) {
64 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
65 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
67 struct dmalloc_preamble
*dp
;
78 bar
= (void *)(foo
+ DMDOFFSET
);
79 memset (bar
, 0, size
);
81 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
82 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
83 dp
= (struct dmalloc_preamble
*)foo
;
84 dp
-> prev
= dmalloc_list
;
86 dmalloc_list
-> next
= dp
;
88 dp
-> next
= (struct dmalloc_preamble
*)0;
92 dp
-> generation
= dmalloc_generation
++;
93 dmalloc_outstanding
+= size
;
94 for (i
= 0; i
< DMLFSIZE
; i
++)
97 (&dp
-> low_fence
[i
])) % 143) + 113;
98 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++)
101 (&foo
[i
+ size
])) % 143) + 113;
102 #if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
103 /* Check _every_ entry in the pool! Very expensive. */
104 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
) {
105 for (i
= 0; i
< DMLFSIZE
; i
++) {
106 if (dp
-> low_fence
[i
] !=
108 (&dp
-> low_fence
[i
])) % 143) + 113)
110 log_error ("malloc fence modified: %s(%d)",
111 dp
-> file
, dp
-> line
);
115 foo
= (unsigned char *)dp
;
116 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++) {
117 if (foo
[i
+ dp
-> size
] !=
119 (&foo
[i
+ dp
-> size
])) % 143) + 113) {
120 log_error ("malloc fence modified: %s(%d)",
121 dp
-> file
, dp
-> line
);
128 #ifdef DEBUG_REFCNT_DMALLOC_FREE
129 rc_register (file
, line
, 0, foo
+ DMDOFFSET
, 1, 0, RC_MALLOC
);
135 dfree(void *ptr
, const char *file
, int line
) {
137 log_error ("dfree %s(%d): free on null pointer.", file
, line
);
140 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
141 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
143 unsigned char *bar
= ptr
;
144 struct dmalloc_preamble
*dp
, *cur
;
147 cur
= (struct dmalloc_preamble
*)bar
;
148 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
)
152 log_error ("%s(%d): freeing unknown memory: %lx",
153 file
, line
, (unsigned long)cur
);
157 dp
-> prev
-> next
= dp
-> next
;
159 dp
-> next
-> prev
= dp
-> prev
;
160 if (dp
== dmalloc_list
)
161 dmalloc_list
= dp
-> prev
;
162 if (dp
-> generation
>= dmalloc_cutoff_generation
)
163 dmalloc_outstanding
-= dp
-> size
;
165 dmalloc_longterm
-= dp
-> size
;
167 for (i
= 0; i
< DMLFSIZE
; i
++) {
168 if (dp
-> low_fence
[i
] !=
170 (&dp
-> low_fence
[i
])) % 143) + 113)
172 log_error ("malloc fence modified: %s(%d)",
173 dp
-> file
, dp
-> line
);
177 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++) {
178 if (bar
[i
+ dp
-> size
] !=
180 (&bar
[i
+ dp
-> size
])) % 143) + 113) {
181 log_error ("malloc fence modified: %s(%d)",
182 dp
-> file
, dp
-> line
);
189 #ifdef DEBUG_REFCNT_DMALLOC_FREE
190 rc_register (file
, line
,
191 0, (unsigned char *)ptr
+ DMDOFFSET
, 0, 1, RC_MALLOC
);
196 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
197 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
198 /* For allocation functions that keep their own free lists, we want to
199 account for the reuse of the memory. */
202 dmalloc_reuse(void *foo
, const char *file
, int line
, int justref
) {
203 struct dmalloc_preamble
*dp
;
205 /* Get the pointer to the dmalloc header. */
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
213 if (dp
-> generation
== dmalloc_generation
)
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
)
222 /* Take it out of the place in the allocated list where it was. */
224 dp
-> prev
-> next
= 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
;
234 dmalloc_longterm
-= dp
-> size
;
236 /* Now put it at the head of the list. */
237 dp
-> prev
= dmalloc_list
;
239 dmalloc_list
-> next
= dp
;
241 dp
-> next
= (struct dmalloc_preamble
*)0;
243 /* Change the reference location information. */
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 #if defined(DEBUG_MALLOC_POOL)
262 if (!dmalloc_cutoff_point
)
263 dmalloc_cutoff_point
= dmalloc_cutoff_generation
;
264 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
) {
265 if (dp
-> generation
<= dmalloc_cutoff_point
)
267 #if defined (DEBUG_MALLOC_POOL)
268 for (i
= 0; i
< DMLFSIZE
; i
++) {
269 if (dp
-> low_fence
[i
] !=
271 (&dp
-> low_fence
[i
])) % 143) + 113)
273 log_error ("malloc fence modified: %s(%d)",
274 dp
-> file
, dp
-> line
);
278 foo
= (unsigned char *)dp
;
279 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++) {
280 if (foo
[i
+ dp
-> size
] !=
282 (&foo
[i
+ dp
-> size
])) % 143) + 113) {
283 log_error ("malloc fence modified: %s(%d)",
284 dp
-> file
, dp
-> line
);
289 #if defined (DEBUG_MEMORY_LEAKAGE) || \
290 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
291 /* Don't count data that's actually on a free list
294 #if defined (DEBUG_RC_HISTORY)
295 int i
, count
, inhistory
= 0, noted
= 0;
297 /* If we have the info, see if this is actually
299 if (rc_history_count
< RC_HISTORY_MAX
) {
300 count
= rc_history_count
;
302 count
= RC_HISTORY_MAX
;
303 i
= rc_history_index
- 1;
308 if (rc_history
[i
].addr
== dp
+ 1) {
311 log_info (" %s(%d): %ld", dp
-> file
,
312 dp
-> line
, dp
-> size
);
315 print_rc_hist_entry (i
);
316 if (!rc_history
[i
].refcnt
)
320 i
= RC_HISTORY_MAX
- 1;
324 log_info (" %s(%d): %ld",
325 dp
-> file
, dp
-> line
, dp
-> size
);
330 dmalloc_cutoff_point
= dmalloc_list
-> generation
;
332 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
334 #if defined (DEBUG_RC_HISTORY)
335 static void print_rc_hist_entry (int i
)
337 log_info (" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
338 rc_history
[i
].file
, rc_history
[i
].line
,
339 (unsigned long)rc_history
[i
].reference
,
340 (unsigned long)rc_history
[i
].addr
,
341 rc_history
[i
].refcnt
);
344 void dump_rc_history (void *addr
)
348 i
= rc_history_index
;
349 if (!rc_history
[i
].file
)
351 else if (rc_history_count
< RC_HISTORY_MAX
) {
352 i
-= rc_history_count
;
356 rc_history_count
= 0;
358 while (rc_history
[i
].file
) {
359 if (!addr
|| addr
== rc_history
[i
].addr
)
360 print_rc_hist_entry (i
);
362 if (i
== RC_HISTORY_MAX
)
364 if (i
== rc_history_index
)
368 void rc_history_next (int d
)
370 #if defined (RC_HISTORY_COMPRESSION)
371 int i
, j
= 0, m
, n
= 0;
374 /* If we are decreasing the reference count, try to find the
375 entry where the reference was made and eliminate it; then
376 we can also eliminate this reference. */
378 m
= rc_history_index
- 1000;
381 ap
= rc_history
[rc_history_index
].addr
;
382 rp
= rc_history
[rc_history_index
].reference
;
383 for (i
= rc_history_index
- 1; i
> m
; i
--) {
384 if (rc_history
[i
].addr
== ap
) {
385 if (rc_history
[i
].reference
== rp
) {
387 for (n
= i
; n
<= rc_history_index
; n
++)
388 print_rc_hist_entry (n
);
391 memmove (&rc_history
[i
],
393 (unsigned)((rc_history_index
- i
) *
394 sizeof (struct rc_history_entry
)));
397 for (j
= i
; j
< rc_history_count
; j
++) {
398 if (rc_history
[j
].addr
== ap
)
399 --rc_history
[j
].refcnt
;
402 for (n
= i
; n
<= rc_history_index
; n
++)
403 print_rc_hist_entry (n
);
413 if (++rc_history_index
== RC_HISTORY_MAX
)
414 rc_history_index
= 0;
417 #endif /* DEBUG_RC_HISTORY */
419 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
420 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
422 struct dmalloc_preamble
*dp
;
426 static int dmalloc_find_entry (struct dmalloc_preamble
*dp
,
427 struct caller
*array
,
432 middle
= (min
+ max
) / 2;
435 if (array
[middle
].dp
-> file
== dp
-> file
) {
436 if (array
[middle
].dp
-> line
== dp
-> line
)
438 else if (array
[middle
].dp
-> line
< dp
-> line
)
439 return dmalloc_find_entry (dp
, array
, middle
, max
);
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
);
445 return dmalloc_find_entry (dp
, array
, 0, middle
);
448 void omapi_print_dmalloc_usage_by_caller ()
450 struct dmalloc_preamble
*dp
;
452 struct caller cp
[1024];
457 memset (cp
, 0, sizeof cp
);
458 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
) {
459 i
= dmalloc_find_entry (dp
, cp
, 0, ccur
);
461 cp
[i
].dp
-> file
!= dp
-> file
||
462 cp
[i
].dp
-> line
!= dp
-> line
) &&
464 log_error ("no space for memory usage summary.");
470 } else if (cp
[i
].dp
-> file
< dp
-> file
||
471 (cp
[i
].dp
-> file
== dp
-> file
&&
472 cp
[i
].dp
-> line
< dp
-> line
)) {
474 memmove (cp
+ i
+ 2, cp
+ i
+ 1,
475 (ccur
- i
) * sizeof *cp
);
477 cp
[i
+ 1].count
= 1;
479 } else if (cp
[i
].dp
-> file
!= dp
-> file
||
480 cp
[i
].dp
-> line
!= dp
-> line
) {
482 cp
+ i
, (ccur
- i
) * sizeof *cp
);
489 printf ("%d\t%s:%d\n", i
, dp
-> file
, dp
-> line
);
490 dump_rc_history (dp
+ 1);
493 for (i
= 0; i
< ccur
; i
++) {
494 printf ("%d\t%s:%d\t%d\n", i
,
495 cp
[i
].dp
-> file
, cp
[i
].dp
-> line
, cp
[i
].count
);
496 #if defined(DUMP_RC_HISTORY)
497 dump_rc_history (cp
[i
].dp
+ 1);
501 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
503 isc_result_t
omapi_object_allocate (omapi_object_t
**o
,
504 omapi_object_type_t
*type
,
506 const char *file
, int line
)
512 if (type
-> allocator
) {
513 foo
= (omapi_object_t
*)0;
514 status
= (*type
-> allocator
) (&foo
, file
, line
);
515 tsize
= type
-> size
;
517 status
= ISC_R_NOMEMORY
;
521 if (status
== ISC_R_NOMEMORY
) {
523 tsize
= (*type
-> sizer
) (size
);
525 tsize
= type
-> size
;
528 if (tsize
< sizeof (omapi_object_t
))
529 return ISC_R_INVALIDARG
;
531 foo
= dmalloc (tsize
, file
, line
);
533 return ISC_R_NOMEMORY
;
536 status
= omapi_object_initialize (foo
, type
, size
, tsize
, file
, line
);
537 if (status
!= ISC_R_SUCCESS
) {
539 (*type
-> freer
) (foo
, file
, line
);
541 dfree (foo
, file
, line
);
544 return omapi_object_reference (o
, foo
, file
, line
);
547 isc_result_t
omapi_object_initialize (omapi_object_t
*o
,
548 omapi_object_type_t
*type
,
549 size_t usize
, size_t psize
,
550 const char *file
, int line
)
552 memset (o
, 0, psize
);
554 if (type
-> initialize
)
555 (*type
-> initialize
) (o
, file
, line
);
556 return ISC_R_SUCCESS
;
559 isc_result_t
omapi_object_reference (omapi_object_t
**r
,
561 const char *file
, int line
)
564 return ISC_R_INVALIDARG
;
567 #if defined (POINTER_DEBUG)
568 log_error ("%s(%d): reference store into non-null pointer!",
572 return ISC_R_INVALIDARG
;
577 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, h
-> type
-> rc_flag
);
578 return ISC_R_SUCCESS
;
581 isc_result_t
omapi_object_dereference (omapi_object_t
**h
,
582 const char *file
, int line
)
584 int outer_reference
= 0;
585 int inner_reference
= 0;
586 int handle_reference
= 0;
587 int extra_references
;
588 omapi_object_t
*p
, *hp
;
591 return ISC_R_INVALIDARG
;
594 #if defined (POINTER_DEBUG)
595 log_error ("%s(%d): dereference of null pointer!", file
, line
);
598 return ISC_R_INVALIDARG
;
602 if ((*h
) -> refcnt
<= 0) {
603 #if defined (POINTER_DEBUG)
604 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
606 #if defined (DEBUG_RC_HISTORY)
607 dump_rc_history (*h
);
612 return ISC_R_INVALIDARG
;
616 /* See if this object's inner object refers to it, but don't
617 count this as a reference if we're being asked to free the
618 reference from the inner object. */
619 if ((*h
) -> inner
&& (*h
) -> inner
-> outer
&&
620 h
!= &((*h
) -> inner
-> outer
))
623 /* Ditto for the outer object. */
624 if ((*h
) -> outer
&& (*h
) -> outer
-> inner
&&
625 h
!= &((*h
) -> outer
-> inner
))
628 /* Ditto for the outer object. The code below assumes that
629 the only reason we'd get a dereference from the handle
630 table is if this function does it - otherwise we'd have to
631 traverse the handle table to find the address where the
632 reference is stored and compare against that, and we don't
633 want to do that if we can avoid it. */
635 handle_reference
= 1;
637 /* If we are getting rid of the last reference other than
638 references to inner and outer objects, or from the handle
639 table, then we must examine all the objects in either
640 direction to see if they hold any non-inner, non-outer,
641 non-handle-table references. If not, we need to free the
642 entire chain of objects. */
643 if ((*h
) -> refcnt
==
644 inner_reference
+ outer_reference
+ handle_reference
+ 1) {
645 if (inner_reference
|| outer_reference
|| handle_reference
) {
646 /* XXX we could check for a reference from the
647 handle table here. */
648 extra_references
= 0;
649 for (p
= (*h
) -> inner
;
650 p
&& !extra_references
; p
= p
-> inner
) {
651 extra_references
+= p
-> refcnt
;
652 if (p
-> inner
&& p
-> inner
-> outer
== p
)
659 for (p
= (*h
) -> outer
;
660 p
&& !extra_references
; p
= p
-> outer
) {
661 extra_references
+= p
-> refcnt
;
662 if (p
-> outer
&& p
-> outer
-> inner
== p
)
670 extra_references
= 0;
672 if (!extra_references
) {
677 omapi_object_dereference
678 (&hp
-> inner
, file
, line
);
680 omapi_object_dereference
681 (&hp
-> outer
, file
, line
);
682 /* if (!hp -> type -> freer) */
683 rc_register (file
, line
, h
, hp
,
684 0, 1, hp
-> type
-> rc_flag
);
685 if (hp
-> type
-> destroy
)
686 (*(hp
-> type
-> destroy
)) (hp
, file
, line
);
687 if (hp
-> type
-> freer
)
688 (hp
-> type
-> freer (hp
, file
, line
));
690 dfree (hp
, file
, line
);
693 /* if (!(*h) -> type -> freer) */
694 rc_register (file
, line
,
695 h
, *h
, (*h
) -> refcnt
, 1,
696 (*h
) -> type
-> rc_flag
);
700 /* if (!(*h) -> type -> freer) */
701 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1,
702 (*h
) -> type
-> rc_flag
);
705 return ISC_R_SUCCESS
;
708 isc_result_t
omapi_buffer_new (omapi_buffer_t
**h
,
709 const char *file
, int line
)
714 t
= (omapi_buffer_t
*)dmalloc (sizeof *t
, file
, line
);
716 return ISC_R_NOMEMORY
;
717 memset (t
, 0, sizeof *t
);
718 status
= omapi_buffer_reference (h
, t
, file
, line
);
719 if (status
!= ISC_R_SUCCESS
)
720 dfree (t
, file
, line
);
721 (*h
) -> head
= sizeof ((*h
) -> buf
) - 1;
725 isc_result_t
omapi_buffer_reference (omapi_buffer_t
**r
,
727 const char *file
, int line
)
730 return ISC_R_INVALIDARG
;
733 #if defined (POINTER_DEBUG)
734 log_error ("%s(%d): reference store into non-null pointer!",
738 return ISC_R_INVALIDARG
;
743 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
744 return ISC_R_SUCCESS
;
747 isc_result_t
omapi_buffer_dereference (omapi_buffer_t
**h
,
748 const char *file
, int line
)
751 return ISC_R_INVALIDARG
;
754 #if defined (POINTER_DEBUG)
755 log_error ("%s(%d): dereference of null pointer!", file
, line
);
758 return ISC_R_INVALIDARG
;
762 if ((*h
) -> refcnt
<= 0) {
763 #if defined (POINTER_DEBUG)
764 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
766 #if defined (DEBUG_RC_HISTORY)
767 dump_rc_history (*h
);
772 return ISC_R_INVALIDARG
;
777 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
778 if ((*h
) -> refcnt
== 0)
779 dfree (*h
, file
, line
);
781 return ISC_R_SUCCESS
;
784 isc_result_t
omapi_typed_data_new (const char *file
, int line
,
785 omapi_typed_data_t
**t
,
786 omapi_datatype_t type
, ...)
789 omapi_typed_data_t
*new;
795 omapi_object_t
*obj
= NULL
;
800 case omapi_datatype_int
:
801 len
= OMAPI_TYPED_DATA_INT_LEN
;
802 intval
= va_arg (l
, int);
804 case omapi_datatype_string
:
805 s
= va_arg (l
, char *);
807 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
810 return ISC_R_INVALIDARG
;
813 case omapi_datatype_data
:
814 val
= va_arg (l
, unsigned);
815 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
818 return ISC_R_INVALIDARG
;
821 case omapi_datatype_object
:
822 len
= OMAPI_TYPED_DATA_OBJECT_LEN
;
823 obj
= va_arg (l
, omapi_object_t
*);
827 return ISC_R_INVALIDARG
;
831 new = dmalloc (len
, file
, line
);
833 return ISC_R_NOMEMORY
;
834 memset (new, 0, len
);
837 case omapi_datatype_int
:
838 new -> u
.integer
= intval
;
840 case omapi_datatype_string
:
841 memcpy (new -> u
.buffer
.value
, s
, val
);
842 new -> u
.buffer
.len
= val
;
844 case omapi_datatype_data
:
845 new -> u
.buffer
.len
= val
;
847 case omapi_datatype_object
:
848 status
= omapi_object_reference (&new -> u
.object
, obj
,
850 if (status
!= ISC_R_SUCCESS
) {
851 dfree (new, file
, line
);
858 return omapi_typed_data_reference (t
, new, file
, line
);
861 isc_result_t
omapi_typed_data_reference (omapi_typed_data_t
**r
,
862 omapi_typed_data_t
*h
,
863 const char *file
, int line
)
866 return ISC_R_INVALIDARG
;
869 #if defined (POINTER_DEBUG)
870 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
873 return ISC_R_INVALIDARG
;
878 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
879 return ISC_R_SUCCESS
;
882 isc_result_t
omapi_typed_data_dereference (omapi_typed_data_t
**h
,
883 const char *file
, int line
)
886 return ISC_R_INVALIDARG
;
889 #if defined (POINTER_DEBUG)
890 log_error ("%s(%d): dereference of null pointer!", file
, line
);
893 return ISC_R_INVALIDARG
;
897 if ((*h
) -> refcnt
<= 0) {
898 #if defined (POINTER_DEBUG)
899 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
901 #if defined (DEBUG_RC_HISTORY)
902 dump_rc_history (*h
);
907 return ISC_R_INVALIDARG
;
912 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
913 if ((*h
) -> refcnt
<= 0 ) {
914 switch ((*h
) -> type
) {
915 case omapi_datatype_int
:
916 case omapi_datatype_string
:
917 case omapi_datatype_data
:
920 case omapi_datatype_object
:
921 omapi_object_dereference (&(*h
) -> u
.object
,
925 dfree (*h
, file
, line
);
928 return ISC_R_SUCCESS
;
931 isc_result_t
omapi_data_string_new (omapi_data_string_t
**d
, unsigned len
,
932 const char *file
, int line
)
934 omapi_data_string_t
*new;
937 nlen
= OMAPI_DATA_STRING_EMPTY_SIZE
+ len
;
939 return ISC_R_INVALIDARG
;
940 new = dmalloc (nlen
, file
, line
);
942 return ISC_R_NOMEMORY
;
943 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE
);
945 return omapi_data_string_reference (d
, new, file
, line
);
948 isc_result_t
omapi_data_string_reference (omapi_data_string_t
**r
,
949 omapi_data_string_t
*h
,
950 const char *file
, int line
)
953 return ISC_R_INVALIDARG
;
956 #if defined (POINTER_DEBUG)
957 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
960 return ISC_R_INVALIDARG
;
965 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
966 return ISC_R_SUCCESS
;
969 isc_result_t
omapi_data_string_dereference (omapi_data_string_t
**h
,
970 const char *file
, int line
)
973 return ISC_R_INVALIDARG
;
976 #if defined (POINTER_DEBUG)
977 log_error ("%s(%d): dereference of null pointer!", file
, line
);
980 return ISC_R_INVALIDARG
;
984 if ((*h
) -> refcnt
<= 0) {
985 #if defined (POINTER_DEBUG)
986 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
988 #if defined (DEBUG_RC_HISTORY)
989 dump_rc_history (*h
);
994 return ISC_R_INVALIDARG
;
999 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1000 if ((*h
) -> refcnt
<= 0 ) {
1001 dfree (*h
, file
, line
);
1004 return ISC_R_SUCCESS
;
1007 isc_result_t
omapi_value_new (omapi_value_t
**d
,
1008 const char *file
, int line
)
1012 new = dmalloc (sizeof *new, file
, line
);
1014 return ISC_R_NOMEMORY
;
1015 memset (new, 0, sizeof *new);
1016 return omapi_value_reference (d
, new, file
, line
);
1019 isc_result_t
omapi_value_reference (omapi_value_t
**r
,
1021 const char *file
, int line
)
1024 return ISC_R_INVALIDARG
;
1027 #if defined (POINTER_DEBUG)
1028 log_error ("%s(%d): reference store into non-null pointer!",
1032 return ISC_R_INVALIDARG
;
1037 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
1038 return ISC_R_SUCCESS
;
1041 isc_result_t
omapi_value_dereference (omapi_value_t
**h
,
1042 const char *file
, int line
)
1045 return ISC_R_INVALIDARG
;
1048 #if defined (POINTER_DEBUG)
1049 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1052 return ISC_R_INVALIDARG
;
1056 if ((*h
) -> refcnt
<= 0) {
1057 #if defined (POINTER_DEBUG)
1058 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1060 #if defined (DEBUG_RC_HISTORY)
1061 dump_rc_history (*h
);
1066 return ISC_R_INVALIDARG
;
1071 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1072 if ((*h
) -> refcnt
== 0) {
1074 omapi_data_string_dereference (&(*h
) -> name
,
1077 omapi_typed_data_dereference (&(*h
) -> value
,
1079 dfree (*h
, file
, line
);
1082 return ISC_R_SUCCESS
;
1085 isc_result_t
omapi_addr_list_new (omapi_addr_list_t
**d
, unsigned count
,
1086 const char *file
, int line
)
1088 omapi_addr_list_t
*new;
1090 new = dmalloc ((count
* sizeof (omapi_addr_t
)) +
1091 sizeof (omapi_addr_list_t
), file
, line
);
1093 return ISC_R_NOMEMORY
;
1094 memset (new, 0, ((count
* sizeof (omapi_addr_t
)) +
1095 sizeof (omapi_addr_list_t
)));
1096 new -> count
= count
;
1097 new -> addresses
= (omapi_addr_t
*)(new + 1);
1098 return omapi_addr_list_reference (d
, new, file
, line
);
1101 isc_result_t
omapi_addr_list_reference (omapi_addr_list_t
**r
,
1102 omapi_addr_list_t
*h
,
1103 const char *file
, int line
)
1106 return ISC_R_INVALIDARG
;
1109 #if defined (POINTER_DEBUG)
1110 log_error ("%s(%d): reference store into non-null pointer!",
1114 return ISC_R_INVALIDARG
;
1119 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
1120 return ISC_R_SUCCESS
;
1123 isc_result_t
omapi_addr_list_dereference (omapi_addr_list_t
**h
,
1124 const char *file
, int line
)
1127 return ISC_R_INVALIDARG
;
1130 #if defined (POINTER_DEBUG)
1131 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1134 return ISC_R_INVALIDARG
;
1138 if ((*h
) -> refcnt
<= 0) {
1139 #if defined (POINTER_DEBUG)
1140 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1142 #if defined (DEBUG_RC_HISTORY)
1143 dump_rc_history (*h
);
1148 return ISC_R_INVALIDARG
;
1153 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1154 if ((*h
) -> refcnt
<= 0 ) {
1155 dfree (*h
, file
, line
);
1158 return ISC_R_SUCCESS
;