3 Functions supporting memory allocation for the object management
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.
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''.
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
;
47 #if defined (DEBUG_RC_HISTORY)
48 struct rc_history_entry rc_history
[RC_HISTORY_MAX
];
53 #if defined (DEBUG_RC_HISTORY)
54 static void print_rc_hist_entry (int);
57 VOIDPTR
dmalloc (size
, file
, line
)
62 unsigned char *foo
= malloc (size
+ DMDSIZE
);
65 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
66 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
67 struct dmalloc_preamble
*dp
;
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
;
79 dmalloc_list
-> next
= dp
;
81 dp
-> next
= (struct dmalloc_preamble
*)0;
85 dp
-> generation
= dmalloc_generation
++;
86 dmalloc_outstanding
+= size
;
87 for (i
= 0; i
< DMLFSIZE
; i
++)
90 (&dp
-> low_fence
[i
])) % 143) + 113;
91 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++)
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
] !=
101 (&dp
-> low_fence
[i
])) % 143) + 113)
103 log_error ("malloc fence modified: %s(%d)",
104 dp
-> file
, dp
-> line
);
108 foo
= (unsigned char *)dp
;
109 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++) {
110 if (foo
[i
+ dp
-> size
] !=
112 (&foo
[i
+ dp
-> size
])) % 143) + 113) {
113 log_error ("malloc fence modified: %s(%d)",
114 dp
-> file
, dp
-> line
);
121 #ifdef DEBUG_REFCNT_DMALLOC_FREE
122 rc_register (file
, line
, 0, foo
+ DMDOFFSET
, 1, 0, RC_MALLOC
);
127 void dfree (ptr
, file
, line
)
133 log_error ("dfree %s(%d): free on null pointer.", file
, line
);
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
;
143 cur
= (struct dmalloc_preamble
*)bar
;
144 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
)
148 log_error ("%s(%d): freeing unknown memory: %lx",
149 file
, line
, (unsigned long)cur
);
153 dp
-> prev
-> next
= 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
;
161 dmalloc_longterm
-= dp
-> size
;
163 for (i
= 0; i
< DMLFSIZE
; i
++) {
164 if (dp
-> low_fence
[i
] !=
166 (&dp
-> low_fence
[i
])) % 143) + 113)
168 log_error ("malloc fence modified: %s(%d)",
169 dp
-> file
, dp
-> line
);
173 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++) {
174 if (bar
[i
+ dp
-> size
] !=
176 (&bar
[i
+ dp
-> size
])) % 143) + 113) {
177 log_error ("malloc fence modified: %s(%d)",
178 dp
-> file
, dp
-> line
);
185 #ifdef DEBUG_REFCNT_DMALLOC_FREE
186 rc_register (file
, line
,
187 0, (unsigned char *)ptr
+ DMDOFFSET
, 0, 1, RC_MALLOC
);
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
)
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
;
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
)
266 #if defined (DEBUG_MALLOC_POOL)
267 for (i
= 0; i
< DMLFSIZE
; i
++) {
268 if (dp
-> low_fence
[i
] !=
270 (&dp
-> low_fence
[i
])) % 143) + 113)
272 log_error ("malloc fence modified: %s(%d)",
273 dp
-> file
, dp
-> line
);
277 foo
= (unsigned char *)dp
;
278 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++) {
279 if (foo
[i
+ dp
-> size
] !=
281 (&foo
[i
+ dp
-> size
])) % 143) + 113) {
282 log_error ("malloc fence modified: %s(%d)",
283 dp
-> file
, dp
-> line
);
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
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
298 if (rc_history_count
< RC_HISTORY_MAX
) {
299 count
= rc_history_count
;
301 count
= RC_HISTORY_MAX
;
302 i
= rc_history_index
- 1;
307 if (rc_history
[i
].addr
== dp
+ 1) {
310 log_info (" %s(%d): %d", dp
-> file
,
311 dp
-> line
, dp
-> size
);
314 print_rc_hist_entry (i
);
315 if (!rc_history
[i
].refcnt
)
319 i
= RC_HISTORY_MAX
- 1;
323 log_info (" %s(%d): %d",
324 dp
-> file
, dp
-> line
, dp
-> size
);
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
)
347 i
= rc_history_index
;
348 if (!rc_history
[i
].file
)
350 else if (rc_history_count
< RC_HISTORY_MAX
) {
351 i
-= rc_history_count
;
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
);
361 if (i
== RC_HISTORY_MAX
)
363 if (i
== rc_history_index
)
367 void rc_history_next (int d
)
369 #if defined (RC_HISTORY_COMPRESSION)
370 int i
, j
= 0, m
, n
= 0;
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. */
377 m
= rc_history_index
- 1000;
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
) {
386 for (n
= i
; n
<= rc_history_index
; n
++)
387 print_rc_hist_entry (n
);
390 memmove (&rc_history
[i
],
392 (unsigned)((rc_history_index
- i
) *
393 sizeof (struct rc_history_entry
)));
396 for (j
= i
; j
< rc_history_count
; j
++) {
397 if (rc_history
[j
].addr
== ap
)
398 --rc_history
[j
].refcnt
;
401 for (n
= i
; n
<= rc_history_index
; n
++)
402 print_rc_hist_entry (n
);
412 if (++rc_history_index
== RC_HISTORY_MAX
)
413 rc_history_index
= 0;
418 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
419 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
421 struct dmalloc_preamble
*dp
;
425 static int dmalloc_find_entry (struct dmalloc_preamble
*dp
,
426 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 int ccur
, cmax
, i
, j
;
453 struct caller cp
[1024];
458 memset (cp
, 0, sizeof cp
);
459 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
) {
460 i
= dmalloc_find_entry (dp
, cp
, 0, ccur
);
462 cp
[i
].dp
-> file
!= dp
-> file
||
463 cp
[i
].dp
-> line
!= dp
-> line
) &&
465 log_error ("no space for memory usage summary.");
471 } else if (cp
[i
].dp
-> file
< dp
-> file
||
472 (cp
[i
].dp
-> file
== dp
-> file
&&
473 cp
[i
].dp
-> line
< dp
-> line
)) {
475 memmove (cp
+ i
+ 2, cp
+ i
+ 1,
476 (ccur
- i
) * sizeof *cp
);
478 cp
[i
+ 1].count
= 1;
480 } else if (cp
[i
].dp
-> file
!= dp
-> file
||
481 cp
[i
].dp
-> line
!= dp
-> line
) {
483 cp
+ i
, (ccur
- i
) * sizeof *cp
);
490 printf ("%d\t%s:%d\n", i
, dp
-> file
, dp
-> line
);
491 dump_rc_history (dp
+ 1);
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
,
505 const char *file
, int line
)
511 if (type
-> allocator
) {
512 foo
= (omapi_object_t
*)0;
513 status
= (*type
-> allocator
) (&foo
, file
, line
);
514 tsize
= type
-> size
;
516 status
= ISC_R_NOMEMORY
;
520 if (status
== ISC_R_NOMEMORY
) {
522 tsize
= (*type
-> sizer
) (size
);
524 tsize
= type
-> size
;
527 if (tsize
< sizeof (omapi_object_t
))
528 return ISC_R_INVALIDARG
;
530 foo
= dmalloc (tsize
, file
, line
);
532 return ISC_R_NOMEMORY
;
535 status
= omapi_object_initialize (foo
, type
, size
, tsize
, file
, line
);
536 if (status
!= ISC_R_SUCCESS
) {
538 (*type
-> freer
) (foo
, file
, line
);
540 dfree (foo
, file
, line
);
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
);
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
,
560 const char *file
, int line
)
563 return ISC_R_INVALIDARG
;
566 #if defined (POINTER_DEBUG)
567 log_error ("%s(%d): reference store into non-null pointer!",
571 return ISC_R_INVALIDARG
;
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
;
590 return ISC_R_INVALIDARG
;
593 #if defined (POINTER_DEBUG)
594 log_error ("%s(%d): dereference of null pointer!", file
, line
);
597 return ISC_R_INVALIDARG
;
601 if ((*h
) -> refcnt
<= 0) {
602 #if defined (POINTER_DEBUG)
603 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
605 #if defined (DEBUG_RC_HISTORY)
606 dump_rc_history (*h
);
611 return ISC_R_INVALIDARG
;
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
))
622 /* Ditto for the outer object. */
623 if ((*h
) -> outer
&& (*h
) -> outer
-> inner
&&
624 h
!= &((*h
) -> outer
-> inner
))
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. */
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
)
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
)
669 extra_references
= 0;
671 if (!extra_references
) {
676 omapi_object_dereference
677 (&hp
-> inner
, file
, line
);
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
));
689 dfree (hp
, file
, line
);
692 /* if (!(*h) -> type -> freer) */
693 rc_register (file
, line
,
694 h
, *h
, (*h
) -> refcnt
, 1,
695 (*h
) -> type
-> rc_flag
);
699 /* if (!(*h) -> type -> freer) */
700 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1,
701 (*h
) -> type
-> rc_flag
);
704 return ISC_R_SUCCESS
;
707 isc_result_t
omapi_buffer_new (omapi_buffer_t
**h
,
708 const char *file
, int line
)
713 t
= (omapi_buffer_t
*)dmalloc (sizeof *t
, file
, line
);
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;
724 isc_result_t
omapi_buffer_reference (omapi_buffer_t
**r
,
726 const char *file
, int line
)
729 return ISC_R_INVALIDARG
;
732 #if defined (POINTER_DEBUG)
733 log_error ("%s(%d): reference store into non-null pointer!",
737 return ISC_R_INVALIDARG
;
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
)
750 return ISC_R_INVALIDARG
;
753 #if defined (POINTER_DEBUG)
754 log_error ("%s(%d): dereference of null pointer!", file
, line
);
757 return ISC_R_INVALIDARG
;
761 if ((*h
) -> refcnt
<= 0) {
762 #if defined (POINTER_DEBUG)
763 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
765 #if defined (DEBUG_RC_HISTORY)
766 dump_rc_history (*h
);
771 return ISC_R_INVALIDARG
;
776 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
777 if ((*h
) -> refcnt
== 0)
778 dfree (*h
, file
, line
);
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
, ...)
788 omapi_typed_data_t
*new;
794 omapi_object_t
*obj
= NULL
;
799 case omapi_datatype_int
:
800 len
= OMAPI_TYPED_DATA_INT_LEN
;
801 intval
= va_arg (l
, int);
803 case omapi_datatype_string
:
804 s
= va_arg (l
, char *);
806 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
808 case omapi_datatype_data
:
809 val
= va_arg (l
, unsigned);
810 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
812 case omapi_datatype_object
:
813 len
= OMAPI_TYPED_DATA_OBJECT_LEN
;
814 obj
= va_arg (l
, omapi_object_t
*);
818 return ISC_R_INVALIDARG
;
822 new = dmalloc (len
, file
, line
);
824 return ISC_R_NOMEMORY
;
825 memset (new, 0, len
);
828 case omapi_datatype_int
:
829 new -> u
.integer
= intval
;
831 case omapi_datatype_string
:
832 memcpy (new -> u
.buffer
.value
, s
, val
);
833 new -> u
.buffer
.len
= val
;
835 case omapi_datatype_data
:
836 new -> u
.buffer
.len
= val
;
838 case omapi_datatype_object
:
839 status
= omapi_object_reference (&new -> u
.object
, obj
,
841 if (status
!= ISC_R_SUCCESS
) {
842 dfree (new, file
, line
);
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
)
857 return ISC_R_INVALIDARG
;
860 #if defined (POINTER_DEBUG)
861 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
864 return ISC_R_INVALIDARG
;
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
)
877 return ISC_R_INVALIDARG
;
880 #if defined (POINTER_DEBUG)
881 log_error ("%s(%d): dereference of null pointer!", file
, line
);
884 return ISC_R_INVALIDARG
;
888 if ((*h
) -> refcnt
<= 0) {
889 #if defined (POINTER_DEBUG)
890 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
892 #if defined (DEBUG_RC_HISTORY)
893 dump_rc_history (*h
);
898 return ISC_R_INVALIDARG
;
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
:
911 case omapi_datatype_object
:
912 omapi_object_dereference (&(*h
) -> u
.object
,
916 dfree (*h
, file
, line
);
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
);
929 return ISC_R_NOMEMORY
;
930 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE
);
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
)
940 return ISC_R_INVALIDARG
;
943 #if defined (POINTER_DEBUG)
944 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
947 return ISC_R_INVALIDARG
;
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
)
960 return ISC_R_INVALIDARG
;
963 #if defined (POINTER_DEBUG)
964 log_error ("%s(%d): dereference of null pointer!", file
, line
);
967 return ISC_R_INVALIDARG
;
971 if ((*h
) -> refcnt
<= 0) {
972 #if defined (POINTER_DEBUG)
973 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
975 #if defined (DEBUG_RC_HISTORY)
976 dump_rc_history (*h
);
981 return ISC_R_INVALIDARG
;
986 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
987 if ((*h
) -> refcnt
<= 0 ) {
988 dfree (*h
, file
, line
);
991 return ISC_R_SUCCESS
;
994 isc_result_t
omapi_value_new (omapi_value_t
**d
,
995 const char *file
, int line
)
999 new = dmalloc (sizeof *new, file
, line
);
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
,
1008 const char *file
, int line
)
1011 return ISC_R_INVALIDARG
;
1014 #if defined (POINTER_DEBUG)
1015 log_error ("%s(%d): reference store into non-null pointer!",
1019 return ISC_R_INVALIDARG
;
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
)
1032 return ISC_R_INVALIDARG
;
1035 #if defined (POINTER_DEBUG)
1036 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1039 return ISC_R_INVALIDARG
;
1043 if ((*h
) -> refcnt
<= 0) {
1044 #if defined (POINTER_DEBUG)
1045 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1047 #if defined (DEBUG_RC_HISTORY)
1048 dump_rc_history (*h
);
1053 return ISC_R_INVALIDARG
;
1058 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1059 if ((*h
) -> refcnt
== 0) {
1061 omapi_data_string_dereference (&(*h
) -> name
,
1064 omapi_typed_data_dereference (&(*h
) -> value
,
1066 dfree (*h
, file
, line
);
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
);
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
)
1093 return ISC_R_INVALIDARG
;
1096 #if defined (POINTER_DEBUG)
1097 log_error ("%s(%d): reference store into non-null pointer!",
1101 return ISC_R_INVALIDARG
;
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
)
1114 return ISC_R_INVALIDARG
;
1117 #if defined (POINTER_DEBUG)
1118 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1121 return ISC_R_INVALIDARG
;
1125 if ((*h
) -> refcnt
<= 0) {
1126 #if defined (POINTER_DEBUG)
1127 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1129 #if defined (DEBUG_RC_HISTORY)
1130 dump_rc_history (*h
);
1135 return ISC_R_INVALIDARG
;
1140 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1141 if ((*h
) -> refcnt
<= 0 ) {
1142 dfree (*h
, file
, line
);
1145 return ISC_R_SUCCESS
;