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
);
64 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
65 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 tsize
= 0; /* XXXGCC -Wuninitialized */
513 if (type
-> allocator
) {
514 foo
= (omapi_object_t
*)0;
515 status
= (*type
-> allocator
) (&foo
, file
, line
);
516 tsize
= type
-> size
;
518 status
= ISC_R_NOMEMORY
;
522 if (status
== ISC_R_NOMEMORY
) {
524 tsize
= (*type
-> sizer
) (size
);
526 tsize
= type
-> size
;
529 if (tsize
< sizeof (omapi_object_t
))
530 return ISC_R_INVALIDARG
;
532 foo
= dmalloc (tsize
, file
, line
);
534 return ISC_R_NOMEMORY
;
537 status
= omapi_object_initialize (foo
, type
, size
, tsize
, file
, line
);
538 if (status
!= ISC_R_SUCCESS
) {
540 (*type
-> freer
) (foo
, file
, line
);
542 dfree (foo
, file
, line
);
545 return omapi_object_reference (o
, foo
, file
, line
);
548 isc_result_t
omapi_object_initialize (omapi_object_t
*o
,
549 omapi_object_type_t
*type
,
550 size_t usize
, size_t psize
,
551 const char *file
, int line
)
553 memset (o
, 0, psize
);
555 if (type
-> initialize
)
556 (*type
-> initialize
) (o
, file
, line
);
557 return ISC_R_SUCCESS
;
560 isc_result_t
omapi_object_reference (omapi_object_t
**r
,
562 const char *file
, int line
)
565 return ISC_R_INVALIDARG
;
568 #if defined (POINTER_DEBUG)
569 log_error ("%s(%d): reference store into non-null pointer!",
573 return ISC_R_INVALIDARG
;
578 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, h
-> type
-> rc_flag
);
579 return ISC_R_SUCCESS
;
582 isc_result_t
omapi_object_dereference (omapi_object_t
**h
,
583 const char *file
, int line
)
585 int outer_reference
= 0;
586 int inner_reference
= 0;
587 int handle_reference
= 0;
588 int extra_references
;
589 omapi_object_t
*p
, *hp
;
592 return ISC_R_INVALIDARG
;
595 #if defined (POINTER_DEBUG)
596 log_error ("%s(%d): dereference of null pointer!", file
, line
);
599 return ISC_R_INVALIDARG
;
603 if ((*h
) -> refcnt
<= 0) {
604 #if defined (POINTER_DEBUG)
605 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
607 #if defined (DEBUG_RC_HISTORY)
608 dump_rc_history (*h
);
613 return ISC_R_INVALIDARG
;
617 /* See if this object's inner object refers to it, but don't
618 count this as a reference if we're being asked to free the
619 reference from the inner object. */
620 if ((*h
) -> inner
&& (*h
) -> inner
-> outer
&&
621 h
!= &((*h
) -> inner
-> outer
))
624 /* Ditto for the outer object. */
625 if ((*h
) -> outer
&& (*h
) -> outer
-> inner
&&
626 h
!= &((*h
) -> outer
-> inner
))
629 /* Ditto for the outer object. The code below assumes that
630 the only reason we'd get a dereference from the handle
631 table is if this function does it - otherwise we'd have to
632 traverse the handle table to find the address where the
633 reference is stored and compare against that, and we don't
634 want to do that if we can avoid it. */
636 handle_reference
= 1;
638 /* If we are getting rid of the last reference other than
639 references to inner and outer objects, or from the handle
640 table, then we must examine all the objects in either
641 direction to see if they hold any non-inner, non-outer,
642 non-handle-table references. If not, we need to free the
643 entire chain of objects. */
644 if ((*h
) -> refcnt
==
645 inner_reference
+ outer_reference
+ handle_reference
+ 1) {
646 if (inner_reference
|| outer_reference
|| handle_reference
) {
647 /* XXX we could check for a reference from the
648 handle table here. */
649 extra_references
= 0;
650 for (p
= (*h
) -> inner
;
651 p
&& !extra_references
; p
= p
-> inner
) {
652 extra_references
+= p
-> refcnt
;
653 if (p
-> inner
&& p
-> inner
-> outer
== p
)
660 for (p
= (*h
) -> outer
;
661 p
&& !extra_references
; p
= p
-> outer
) {
662 extra_references
+= p
-> refcnt
;
663 if (p
-> outer
&& p
-> outer
-> inner
== p
)
671 extra_references
= 0;
673 if (!extra_references
) {
678 omapi_object_dereference
679 (&hp
-> inner
, file
, line
);
681 omapi_object_dereference
682 (&hp
-> outer
, file
, line
);
683 /* if (!hp -> type -> freer) */
684 rc_register (file
, line
, h
, hp
,
685 0, 1, hp
-> type
-> rc_flag
);
686 if (hp
-> type
-> destroy
)
687 (*(hp
-> type
-> destroy
)) (hp
, file
, line
);
688 if (hp
-> type
-> freer
)
689 (hp
-> type
-> freer (hp
, file
, line
));
691 dfree (hp
, file
, line
);
694 /* if (!(*h) -> type -> freer) */
695 rc_register (file
, line
,
696 h
, *h
, (*h
) -> refcnt
, 1,
697 (*h
) -> type
-> rc_flag
);
701 /* if (!(*h) -> type -> freer) */
702 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1,
703 (*h
) -> type
-> rc_flag
);
706 return ISC_R_SUCCESS
;
709 isc_result_t
omapi_buffer_new (omapi_buffer_t
**h
,
710 const char *file
, int line
)
715 t
= (omapi_buffer_t
*)dmalloc (sizeof *t
, file
, line
);
717 return ISC_R_NOMEMORY
;
718 memset (t
, 0, sizeof *t
);
719 status
= omapi_buffer_reference (h
, t
, file
, line
);
720 if (status
!= ISC_R_SUCCESS
)
721 dfree (t
, file
, line
);
722 (*h
) -> head
= sizeof ((*h
) -> buf
) - 1;
726 isc_result_t
omapi_buffer_reference (omapi_buffer_t
**r
,
728 const char *file
, int line
)
731 return ISC_R_INVALIDARG
;
734 #if defined (POINTER_DEBUG)
735 log_error ("%s(%d): reference store into non-null pointer!",
739 return ISC_R_INVALIDARG
;
744 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
745 return ISC_R_SUCCESS
;
748 isc_result_t
omapi_buffer_dereference (omapi_buffer_t
**h
,
749 const char *file
, int line
)
752 return ISC_R_INVALIDARG
;
755 #if defined (POINTER_DEBUG)
756 log_error ("%s(%d): dereference of null pointer!", file
, line
);
759 return ISC_R_INVALIDARG
;
763 if ((*h
) -> refcnt
<= 0) {
764 #if defined (POINTER_DEBUG)
765 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
767 #if defined (DEBUG_RC_HISTORY)
768 dump_rc_history (*h
);
773 return ISC_R_INVALIDARG
;
778 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
779 if ((*h
) -> refcnt
== 0)
780 dfree (*h
, file
, line
);
782 return ISC_R_SUCCESS
;
785 isc_result_t
omapi_typed_data_new (const char *file
, int line
,
786 omapi_typed_data_t
**t
,
787 omapi_datatype_t type
, ...)
790 omapi_typed_data_t
*new;
796 omapi_object_t
*obj
= NULL
;
800 val
= 0; /* XXXGCC -Wuninitialized */
801 intval
= 0; /* XXXGCC -Wuninitialized */
802 s
= NULL
; /* XXXGCC -Wuninitialized */
803 obj
= NULL
; /* XXXGCC -Wuninitialized */
806 case omapi_datatype_int
:
807 len
= OMAPI_TYPED_DATA_INT_LEN
;
808 intval
= va_arg (l
, int);
810 case omapi_datatype_string
:
811 s
= va_arg (l
, char *);
813 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
815 case omapi_datatype_data
:
816 val
= va_arg (l
, unsigned);
817 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
819 case omapi_datatype_object
:
820 len
= OMAPI_TYPED_DATA_OBJECT_LEN
;
821 obj
= va_arg (l
, omapi_object_t
*);
825 return ISC_R_INVALIDARG
;
829 new = dmalloc (len
, file
, line
);
831 return ISC_R_NOMEMORY
;
832 memset (new, 0, len
);
835 case omapi_datatype_int
:
836 new -> u
.integer
= intval
;
838 case omapi_datatype_string
:
839 memcpy (new -> u
.buffer
.value
, s
, val
);
840 new -> u
.buffer
.len
= val
;
842 case omapi_datatype_data
:
843 new -> u
.buffer
.len
= val
;
845 case omapi_datatype_object
:
846 status
= omapi_object_reference (&new -> u
.object
, obj
,
848 if (status
!= ISC_R_SUCCESS
) {
849 dfree (new, file
, line
);
856 return omapi_typed_data_reference (t
, new, file
, line
);
859 isc_result_t
omapi_typed_data_reference (omapi_typed_data_t
**r
,
860 omapi_typed_data_t
*h
,
861 const char *file
, int line
)
864 return ISC_R_INVALIDARG
;
867 #if defined (POINTER_DEBUG)
868 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
871 return ISC_R_INVALIDARG
;
876 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
877 return ISC_R_SUCCESS
;
880 isc_result_t
omapi_typed_data_dereference (omapi_typed_data_t
**h
,
881 const char *file
, int line
)
884 return ISC_R_INVALIDARG
;
887 #if defined (POINTER_DEBUG)
888 log_error ("%s(%d): dereference of null pointer!", file
, line
);
891 return ISC_R_INVALIDARG
;
895 if ((*h
) -> refcnt
<= 0) {
896 #if defined (POINTER_DEBUG)
897 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
899 #if defined (DEBUG_RC_HISTORY)
900 dump_rc_history (*h
);
905 return ISC_R_INVALIDARG
;
910 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
911 if ((*h
) -> refcnt
<= 0 ) {
912 switch ((*h
) -> type
) {
913 case omapi_datatype_int
:
914 case omapi_datatype_string
:
915 case omapi_datatype_data
:
918 case omapi_datatype_object
:
919 omapi_object_dereference (&(*h
) -> u
.object
,
923 dfree (*h
, file
, line
);
926 return ISC_R_SUCCESS
;
929 isc_result_t
omapi_data_string_new (omapi_data_string_t
**d
, unsigned len
,
930 const char *file
, int line
)
932 omapi_data_string_t
*new;
934 new = dmalloc (OMAPI_DATA_STRING_EMPTY_SIZE
+ len
, file
, line
);
936 return ISC_R_NOMEMORY
;
937 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE
);
939 return omapi_data_string_reference (d
, new, file
, line
);
942 isc_result_t
omapi_data_string_reference (omapi_data_string_t
**r
,
943 omapi_data_string_t
*h
,
944 const char *file
, int line
)
947 return ISC_R_INVALIDARG
;
950 #if defined (POINTER_DEBUG)
951 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
954 return ISC_R_INVALIDARG
;
959 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
960 return ISC_R_SUCCESS
;
963 isc_result_t
omapi_data_string_dereference (omapi_data_string_t
**h
,
964 const char *file
, int line
)
967 return ISC_R_INVALIDARG
;
970 #if defined (POINTER_DEBUG)
971 log_error ("%s(%d): dereference of null pointer!", file
, line
);
974 return ISC_R_INVALIDARG
;
978 if ((*h
) -> refcnt
<= 0) {
979 #if defined (POINTER_DEBUG)
980 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
982 #if defined (DEBUG_RC_HISTORY)
983 dump_rc_history (*h
);
988 return ISC_R_INVALIDARG
;
993 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
994 if ((*h
) -> refcnt
<= 0 ) {
995 dfree (*h
, file
, line
);
998 return ISC_R_SUCCESS
;
1001 isc_result_t
omapi_value_new (omapi_value_t
**d
,
1002 const char *file
, int line
)
1006 new = dmalloc (sizeof *new, file
, line
);
1008 return ISC_R_NOMEMORY
;
1009 memset (new, 0, sizeof *new);
1010 return omapi_value_reference (d
, new, file
, line
);
1013 isc_result_t
omapi_value_reference (omapi_value_t
**r
,
1015 const char *file
, int line
)
1018 return ISC_R_INVALIDARG
;
1021 #if defined (POINTER_DEBUG)
1022 log_error ("%s(%d): reference store into non-null pointer!",
1026 return ISC_R_INVALIDARG
;
1031 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
1032 return ISC_R_SUCCESS
;
1035 isc_result_t
omapi_value_dereference (omapi_value_t
**h
,
1036 const char *file
, int line
)
1039 return ISC_R_INVALIDARG
;
1042 #if defined (POINTER_DEBUG)
1043 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1046 return ISC_R_INVALIDARG
;
1050 if ((*h
) -> refcnt
<= 0) {
1051 #if defined (POINTER_DEBUG)
1052 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1054 #if defined (DEBUG_RC_HISTORY)
1055 dump_rc_history (*h
);
1060 return ISC_R_INVALIDARG
;
1065 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1066 if ((*h
) -> refcnt
== 0) {
1068 omapi_data_string_dereference (&(*h
) -> name
,
1071 omapi_typed_data_dereference (&(*h
) -> value
,
1073 dfree (*h
, file
, line
);
1076 return ISC_R_SUCCESS
;
1079 isc_result_t
omapi_addr_list_new (omapi_addr_list_t
**d
, unsigned count
,
1080 const char *file
, int line
)
1082 omapi_addr_list_t
*new;
1084 new = dmalloc ((count
* sizeof (omapi_addr_t
)) +
1085 sizeof (omapi_addr_list_t
), file
, line
);
1087 return ISC_R_NOMEMORY
;
1088 memset (new, 0, ((count
* sizeof (omapi_addr_t
)) +
1089 sizeof (omapi_addr_list_t
)));
1090 new -> count
= count
;
1091 new -> addresses
= (omapi_addr_t
*)(new + 1);
1092 return omapi_addr_list_reference (d
, new, file
, line
);
1095 isc_result_t
omapi_addr_list_reference (omapi_addr_list_t
**r
,
1096 omapi_addr_list_t
*h
,
1097 const char *file
, int line
)
1100 return ISC_R_INVALIDARG
;
1103 #if defined (POINTER_DEBUG)
1104 log_error ("%s(%d): reference store into non-null pointer!",
1108 return ISC_R_INVALIDARG
;
1113 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
1114 return ISC_R_SUCCESS
;
1117 isc_result_t
omapi_addr_list_dereference (omapi_addr_list_t
**h
,
1118 const char *file
, int line
)
1121 return ISC_R_INVALIDARG
;
1124 #if defined (POINTER_DEBUG)
1125 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1128 return ISC_R_INVALIDARG
;
1132 if ((*h
) -> refcnt
<= 0) {
1133 #if defined (POINTER_DEBUG)
1134 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1136 #if defined (DEBUG_RC_HISTORY)
1137 dump_rc_history (*h
);
1142 return ISC_R_INVALIDARG
;
1147 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1148 if ((*h
) -> refcnt
<= 0 ) {
1149 dfree (*h
, file
, line
);
1152 return ISC_R_SUCCESS
;