1 /* $NetBSD: alloc.c,v 1.1.1.3 2014/07/12 11:57:58 spz Exp $ */
4 Functions supporting memory allocation for the object management
8 * Copyright (c) 2012,2014 by Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC")
10 * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
11 * Copyright (c) 1999-2003 by Internet Software Consortium
13 * Permission to use, copy, modify, and distribute this software for any
14 * purpose with or without fee is hereby granted, provided that the above
15 * copyright notice and this permission notice appear in all copies.
17 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
18 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
20 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
23 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 * Internet Systems Consortium, Inc.
27 * Redwood City, CA 94063
29 * https://www.isc.org/
33 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: alloc.c,v 1.1.1.3 2014/07/12 11:57:58 spz Exp $");
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)
263 if (!dmalloc_cutoff_point
)
264 dmalloc_cutoff_point
= dmalloc_cutoff_generation
;
265 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
) {
266 if (dp
-> generation
<= dmalloc_cutoff_point
)
268 #if defined (DEBUG_MALLOC_POOL)
269 for (i
= 0; i
< DMLFSIZE
; i
++) {
270 if (dp
-> low_fence
[i
] !=
272 (&dp
-> low_fence
[i
])) % 143) + 113)
274 log_error ("malloc fence modified: %s(%d)",
275 dp
-> file
, dp
-> line
);
279 foo
= (unsigned char *)dp
;
280 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++) {
281 if (foo
[i
+ dp
-> size
] !=
283 (&foo
[i
+ dp
-> size
])) % 143) + 113) {
284 log_error ("malloc fence modified: %s(%d)",
285 dp
-> file
, dp
-> line
);
290 #if defined (DEBUG_MEMORY_LEAKAGE) || \
291 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
292 /* Don't count data that's actually on a free list
295 #if defined (DEBUG_RC_HISTORY)
296 int i
, count
, inhistory
= 0, noted
= 0;
298 /* If we have the info, see if this is actually
300 if (rc_history_count
< RC_HISTORY_MAX
) {
301 count
= rc_history_count
;
303 count
= RC_HISTORY_MAX
;
304 i
= rc_history_index
- 1;
309 if (rc_history
[i
].addr
== dp
+ 1) {
312 log_info (" %s(%d): %ld", dp
-> file
,
313 dp
-> line
, (long) dp
-> size
);
316 print_rc_hist_entry (i
);
317 if (!rc_history
[i
].refcnt
)
321 i
= RC_HISTORY_MAX
- 1;
325 log_info (" %s(%d): %ld",
326 dp
-> file
, dp
-> line
,
332 dmalloc_cutoff_point
= dmalloc_list
-> generation
;
334 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
336 #if defined (DEBUG_RC_HISTORY)
337 static void print_rc_hist_entry (int i
)
339 log_info (" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
340 rc_history
[i
].file
, rc_history
[i
].line
,
341 (unsigned long)rc_history
[i
].reference
,
342 (unsigned long)rc_history
[i
].addr
,
343 rc_history
[i
].refcnt
);
346 void dump_rc_history (void *addr
)
350 i
= rc_history_index
;
351 if (!rc_history
[i
].file
)
353 else if (rc_history_count
< RC_HISTORY_MAX
) {
354 i
-= rc_history_count
;
358 rc_history_count
= 0;
360 while (rc_history
[i
].file
) {
361 if (!addr
|| addr
== rc_history
[i
].addr
)
362 print_rc_hist_entry (i
);
364 if (i
== RC_HISTORY_MAX
)
366 if (i
== rc_history_index
)
370 void rc_history_next (int d
)
372 #if defined (RC_HISTORY_COMPRESSION)
373 int i
, j
= 0, m
, n
= 0;
376 /* If we are decreasing the reference count, try to find the
377 entry where the reference was made and eliminate it; then
378 we can also eliminate this reference. */
380 m
= rc_history_index
- 1000;
383 ap
= rc_history
[rc_history_index
].addr
;
384 rp
= rc_history
[rc_history_index
].reference
;
385 for (i
= rc_history_index
- 1; i
> m
; i
--) {
386 if (rc_history
[i
].addr
== ap
) {
387 if (rc_history
[i
].reference
== rp
) {
389 for (n
= i
; n
<= rc_history_index
; n
++)
390 print_rc_hist_entry (n
);
393 memmove (&rc_history
[i
],
395 (unsigned)((rc_history_index
- i
) *
396 sizeof (struct rc_history_entry
)));
399 for (j
= i
; j
< rc_history_count
; j
++) {
400 if (rc_history
[j
].addr
== ap
)
401 --rc_history
[j
].refcnt
;
404 for (n
= i
; n
<= rc_history_index
; n
++)
405 print_rc_hist_entry (n
);
415 if (++rc_history_index
== RC_HISTORY_MAX
)
416 rc_history_index
= 0;
419 #endif /* DEBUG_RC_HISTORY */
421 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
422 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
424 struct dmalloc_preamble
*dp
;
428 static int dmalloc_find_entry (struct dmalloc_preamble
*dp
,
429 struct caller
*array
,
434 middle
= (min
+ max
) / 2;
437 if (array
[middle
].dp
-> file
== dp
-> file
) {
438 if (array
[middle
].dp
-> line
== dp
-> line
)
440 else if (array
[middle
].dp
-> line
< dp
-> line
)
441 return dmalloc_find_entry (dp
, array
, middle
, max
);
443 return dmalloc_find_entry (dp
, array
, 0, middle
);
444 } else if (array
[middle
].dp
-> file
< dp
-> file
)
445 return dmalloc_find_entry (dp
, array
, middle
, max
);
447 return dmalloc_find_entry (dp
, array
, 0, middle
);
450 void omapi_print_dmalloc_usage_by_caller ()
452 struct dmalloc_preamble
*dp
;
454 struct caller cp
[1024];
459 memset (cp
, 0, sizeof cp
);
460 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
) {
461 i
= dmalloc_find_entry (dp
, cp
, 0, ccur
);
463 cp
[i
].dp
-> file
!= dp
-> file
||
464 cp
[i
].dp
-> line
!= dp
-> line
) &&
466 log_error ("no space for memory usage summary.");
472 } else if (cp
[i
].dp
-> file
< dp
-> file
||
473 (cp
[i
].dp
-> file
== dp
-> file
&&
474 cp
[i
].dp
-> line
< dp
-> line
)) {
476 memmove (cp
+ i
+ 2, cp
+ i
+ 1,
477 (ccur
- i
) * sizeof *cp
);
479 cp
[i
+ 1].count
= 1;
481 } else if (cp
[i
].dp
-> file
!= dp
-> file
||
482 cp
[i
].dp
-> line
!= dp
-> line
) {
484 cp
+ i
, (ccur
- i
) * sizeof *cp
);
491 printf ("%d\t%s:%d\n", i
, dp
-> file
, dp
-> line
);
492 dump_rc_history (dp
+ 1);
495 for (i
= 0; i
< ccur
; i
++) {
496 printf ("%d\t%s:%d\t%d\n", i
,
497 cp
[i
].dp
-> file
, cp
[i
].dp
-> line
, cp
[i
].count
);
498 #if defined(DUMP_RC_HISTORY)
499 dump_rc_history (cp
[i
].dp
+ 1);
503 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
505 isc_result_t
omapi_object_allocate (omapi_object_t
**o
,
506 omapi_object_type_t
*type
,
508 const char *file
, int line
)
514 if (type
-> allocator
) {
515 foo
= (omapi_object_t
*)0;
516 status
= (*type
-> allocator
) (&foo
, file
, line
);
517 tsize
= type
-> size
;
519 status
= ISC_R_NOMEMORY
;
523 if (status
== ISC_R_NOMEMORY
) {
525 tsize
= (*type
-> sizer
) (size
);
527 tsize
= type
-> size
;
530 if (tsize
< sizeof (omapi_object_t
))
531 return DHCP_R_INVALIDARG
;
533 foo
= dmalloc (tsize
, file
, line
);
535 return ISC_R_NOMEMORY
;
538 status
= omapi_object_initialize (foo
, type
, size
, tsize
, file
, line
);
539 if (status
!= ISC_R_SUCCESS
) {
541 (*type
-> freer
) (foo
, file
, line
);
543 dfree (foo
, file
, line
);
546 return omapi_object_reference (o
, foo
, file
, line
);
549 isc_result_t
omapi_object_initialize (omapi_object_t
*o
,
550 omapi_object_type_t
*type
,
551 size_t usize
, size_t psize
,
552 const char *file
, int line
)
554 memset (o
, 0, psize
);
556 if (type
-> initialize
)
557 (*type
-> initialize
) (o
, file
, line
);
558 return ISC_R_SUCCESS
;
561 isc_result_t
omapi_object_reference (omapi_object_t
**r
,
563 const char *file
, int line
)
566 return DHCP_R_INVALIDARG
;
569 #if defined (POINTER_DEBUG)
570 log_error ("%s(%d): reference store into non-null pointer!",
574 return DHCP_R_INVALIDARG
;
579 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, h
-> type
-> rc_flag
);
580 return ISC_R_SUCCESS
;
583 isc_result_t
omapi_object_dereference (omapi_object_t
**h
,
584 const char *file
, int line
)
586 int outer_reference
= 0;
587 int inner_reference
= 0;
588 int handle_reference
= 0;
589 int extra_references
;
590 omapi_object_t
*p
, *hp
;
593 return DHCP_R_INVALIDARG
;
596 #if defined (POINTER_DEBUG)
597 log_error ("%s(%d): dereference of null pointer!", file
, line
);
600 return DHCP_R_INVALIDARG
;
604 if ((*h
) -> refcnt
<= 0) {
605 #if defined (POINTER_DEBUG)
606 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
608 #if defined (DEBUG_RC_HISTORY)
609 dump_rc_history (*h
);
614 return DHCP_R_INVALIDARG
;
618 /* See if this object's inner object refers to it, but don't
619 count this as a reference if we're being asked to free the
620 reference from the inner object. */
621 if ((*h
) -> inner
&& (*h
) -> inner
-> outer
&&
622 h
!= &((*h
) -> inner
-> outer
))
625 /* Ditto for the outer object. */
626 if ((*h
) -> outer
&& (*h
) -> outer
-> inner
&&
627 h
!= &((*h
) -> outer
-> inner
))
630 /* Ditto for the outer object. The code below assumes that
631 the only reason we'd get a dereference from the handle
632 table is if this function does it - otherwise we'd have to
633 traverse the handle table to find the address where the
634 reference is stored and compare against that, and we don't
635 want to do that if we can avoid it. */
637 handle_reference
= 1;
639 /* If we are getting rid of the last reference other than
640 references to inner and outer objects, or from the handle
641 table, then we must examine all the objects in either
642 direction to see if they hold any non-inner, non-outer,
643 non-handle-table references. If not, we need to free the
644 entire chain of objects. */
645 if ((*h
) -> refcnt
==
646 inner_reference
+ outer_reference
+ handle_reference
+ 1) {
647 if (inner_reference
|| outer_reference
|| handle_reference
) {
648 /* XXX we could check for a reference from the
649 handle table here. */
650 extra_references
= 0;
651 for (p
= (*h
) -> inner
;
652 p
&& !extra_references
; p
= p
-> inner
) {
653 extra_references
+= p
-> refcnt
;
654 if (p
-> inner
&& p
-> inner
-> outer
== p
)
661 for (p
= (*h
) -> outer
;
662 p
&& !extra_references
; p
= p
-> outer
) {
663 extra_references
+= p
-> refcnt
;
664 if (p
-> outer
&& p
-> outer
-> inner
== p
)
672 extra_references
= 0;
674 if (!extra_references
) {
679 omapi_object_dereference
680 (&hp
-> inner
, file
, line
);
682 omapi_object_dereference
683 (&hp
-> outer
, file
, line
);
684 /* if (!hp -> type -> freer) */
685 rc_register (file
, line
, h
, hp
,
686 0, 1, hp
-> type
-> rc_flag
);
687 if (handle_reference
) {
688 if (omapi_handle_clear(hp
->handle
) !=
690 log_debug("Attempt to clear null "
694 if (hp
-> type
-> destroy
)
695 (*(hp
-> type
-> destroy
)) (hp
, file
, line
);
696 if (hp
-> type
-> freer
)
697 (hp
-> type
-> freer (hp
, file
, line
));
699 dfree (hp
, file
, line
);
702 /* if (!(*h) -> type -> freer) */
703 rc_register (file
, line
,
704 h
, *h
, (*h
) -> refcnt
, 1,
705 (*h
) -> type
-> rc_flag
);
709 /* if (!(*h) -> type -> freer) */
710 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1,
711 (*h
) -> type
-> rc_flag
);
714 return ISC_R_SUCCESS
;
717 isc_result_t
omapi_buffer_new (omapi_buffer_t
**h
,
718 const char *file
, int line
)
723 t
= (omapi_buffer_t
*)dmalloc (sizeof *t
, file
, line
);
725 return ISC_R_NOMEMORY
;
726 memset (t
, 0, sizeof *t
);
727 status
= omapi_buffer_reference (h
, t
, file
, line
);
728 if (status
!= ISC_R_SUCCESS
)
729 dfree (t
, file
, line
);
730 (*h
) -> head
= sizeof ((*h
) -> buf
) - 1;
734 isc_result_t
omapi_buffer_reference (omapi_buffer_t
**r
,
736 const char *file
, int line
)
739 return DHCP_R_INVALIDARG
;
742 #if defined (POINTER_DEBUG)
743 log_error ("%s(%d): reference store into non-null pointer!",
747 return DHCP_R_INVALIDARG
;
752 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
753 return ISC_R_SUCCESS
;
756 isc_result_t
omapi_buffer_dereference (omapi_buffer_t
**h
,
757 const char *file
, int line
)
760 return DHCP_R_INVALIDARG
;
763 #if defined (POINTER_DEBUG)
764 log_error ("%s(%d): dereference of null pointer!", file
, line
);
767 return DHCP_R_INVALIDARG
;
771 if ((*h
) -> refcnt
<= 0) {
772 #if defined (POINTER_DEBUG)
773 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
775 #if defined (DEBUG_RC_HISTORY)
776 dump_rc_history (*h
);
781 return DHCP_R_INVALIDARG
;
786 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
787 if ((*h
) -> refcnt
== 0)
788 dfree (*h
, file
, line
);
790 return ISC_R_SUCCESS
;
793 isc_result_t
omapi_typed_data_new (const char *file
, int line
,
794 omapi_typed_data_t
**t
,
795 omapi_datatype_t type
, ...)
798 omapi_typed_data_t
*new;
804 omapi_object_t
*obj
= NULL
;
809 case omapi_datatype_int
:
810 len
= OMAPI_TYPED_DATA_INT_LEN
;
811 intval
= va_arg (l
, int);
813 case omapi_datatype_string
:
814 s
= va_arg (l
, char *);
816 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
819 return DHCP_R_INVALIDARG
;
822 case omapi_datatype_data
:
823 val
= va_arg (l
, unsigned);
824 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
827 return DHCP_R_INVALIDARG
;
830 case omapi_datatype_object
:
831 len
= OMAPI_TYPED_DATA_OBJECT_LEN
;
832 obj
= va_arg (l
, omapi_object_t
*);
836 return DHCP_R_INVALIDARG
;
840 new = dmalloc (len
, file
, line
);
842 return ISC_R_NOMEMORY
;
843 memset (new, 0, len
);
846 case omapi_datatype_int
:
847 new -> u
.integer
= intval
;
849 case omapi_datatype_string
:
850 memcpy (new -> u
.buffer
.value
, s
, val
);
851 new -> u
.buffer
.len
= val
;
853 case omapi_datatype_data
:
854 new -> u
.buffer
.len
= val
;
856 case omapi_datatype_object
:
857 status
= omapi_object_reference (&new -> u
.object
, obj
,
859 if (status
!= ISC_R_SUCCESS
) {
860 dfree (new, file
, line
);
867 return omapi_typed_data_reference (t
, new, file
, line
);
870 isc_result_t
omapi_typed_data_reference (omapi_typed_data_t
**r
,
871 omapi_typed_data_t
*h
,
872 const char *file
, int line
)
875 return DHCP_R_INVALIDARG
;
878 #if defined (POINTER_DEBUG)
879 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
882 return DHCP_R_INVALIDARG
;
887 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
888 return ISC_R_SUCCESS
;
891 isc_result_t
omapi_typed_data_dereference (omapi_typed_data_t
**h
,
892 const char *file
, int line
)
895 return DHCP_R_INVALIDARG
;
898 #if defined (POINTER_DEBUG)
899 log_error ("%s(%d): dereference of null pointer!", file
, line
);
902 return DHCP_R_INVALIDARG
;
906 if ((*h
) -> refcnt
<= 0) {
907 #if defined (POINTER_DEBUG)
908 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
910 #if defined (DEBUG_RC_HISTORY)
911 dump_rc_history (*h
);
916 return DHCP_R_INVALIDARG
;
921 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
922 if ((*h
) -> refcnt
<= 0 ) {
923 switch ((*h
) -> type
) {
924 case omapi_datatype_int
:
925 case omapi_datatype_string
:
926 case omapi_datatype_data
:
929 case omapi_datatype_object
:
930 omapi_object_dereference (&(*h
) -> u
.object
,
934 dfree (*h
, file
, line
);
937 return ISC_R_SUCCESS
;
940 isc_result_t
omapi_data_string_new (omapi_data_string_t
**d
, unsigned len
,
941 const char *file
, int line
)
943 omapi_data_string_t
*new;
946 nlen
= OMAPI_DATA_STRING_EMPTY_SIZE
+ len
;
948 return DHCP_R_INVALIDARG
;
949 new = dmalloc (nlen
, file
, line
);
951 return ISC_R_NOMEMORY
;
952 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE
);
954 return omapi_data_string_reference (d
, new, file
, line
);
957 isc_result_t
omapi_data_string_reference (omapi_data_string_t
**r
,
958 omapi_data_string_t
*h
,
959 const char *file
, int line
)
962 return DHCP_R_INVALIDARG
;
965 #if defined (POINTER_DEBUG)
966 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
969 return DHCP_R_INVALIDARG
;
974 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
975 return ISC_R_SUCCESS
;
978 isc_result_t
omapi_data_string_dereference (omapi_data_string_t
**h
,
979 const char *file
, int line
)
982 return DHCP_R_INVALIDARG
;
985 #if defined (POINTER_DEBUG)
986 log_error ("%s(%d): dereference of null pointer!", file
, line
);
989 return DHCP_R_INVALIDARG
;
993 if ((*h
) -> refcnt
<= 0) {
994 #if defined (POINTER_DEBUG)
995 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
997 #if defined (DEBUG_RC_HISTORY)
998 dump_rc_history (*h
);
1003 return DHCP_R_INVALIDARG
;
1008 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1009 if ((*h
) -> refcnt
<= 0 ) {
1010 dfree (*h
, file
, line
);
1013 return ISC_R_SUCCESS
;
1016 isc_result_t
omapi_value_new (omapi_value_t
**d
,
1017 const char *file
, int line
)
1021 new = dmalloc (sizeof *new, file
, line
);
1023 return ISC_R_NOMEMORY
;
1024 memset (new, 0, sizeof *new);
1025 return omapi_value_reference (d
, new, file
, line
);
1028 isc_result_t
omapi_value_reference (omapi_value_t
**r
,
1030 const char *file
, int line
)
1033 return DHCP_R_INVALIDARG
;
1036 #if defined (POINTER_DEBUG)
1037 log_error ("%s(%d): reference store into non-null pointer!",
1041 return DHCP_R_INVALIDARG
;
1046 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
1047 return ISC_R_SUCCESS
;
1050 isc_result_t
omapi_value_dereference (omapi_value_t
**h
,
1051 const char *file
, int line
)
1054 return DHCP_R_INVALIDARG
;
1057 #if defined (POINTER_DEBUG)
1058 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1061 return DHCP_R_INVALIDARG
;
1065 if ((*h
) -> refcnt
<= 0) {
1066 #if defined (POINTER_DEBUG)
1067 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1069 #if defined (DEBUG_RC_HISTORY)
1070 dump_rc_history (*h
);
1075 return DHCP_R_INVALIDARG
;
1080 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1081 if ((*h
) -> refcnt
== 0) {
1083 omapi_data_string_dereference (&(*h
) -> name
,
1086 omapi_typed_data_dereference (&(*h
) -> value
,
1088 dfree (*h
, file
, line
);
1091 return ISC_R_SUCCESS
;
1094 isc_result_t
omapi_addr_list_new (omapi_addr_list_t
**d
, unsigned count
,
1095 const char *file
, int line
)
1097 omapi_addr_list_t
*new;
1099 new = dmalloc ((count
* sizeof (omapi_addr_t
)) +
1100 sizeof (omapi_addr_list_t
), file
, line
);
1102 return ISC_R_NOMEMORY
;
1103 memset (new, 0, ((count
* sizeof (omapi_addr_t
)) +
1104 sizeof (omapi_addr_list_t
)));
1105 new -> count
= count
;
1106 new -> addresses
= (omapi_addr_t
*)(new + 1);
1107 return omapi_addr_list_reference (d
, new, file
, line
);
1110 isc_result_t
omapi_addr_list_reference (omapi_addr_list_t
**r
,
1111 omapi_addr_list_t
*h
,
1112 const char *file
, int line
)
1115 return DHCP_R_INVALIDARG
;
1118 #if defined (POINTER_DEBUG)
1119 log_error ("%s(%d): reference store into non-null pointer!",
1123 return DHCP_R_INVALIDARG
;
1128 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
1129 return ISC_R_SUCCESS
;
1132 isc_result_t
omapi_addr_list_dereference (omapi_addr_list_t
**h
,
1133 const char *file
, int line
)
1136 return DHCP_R_INVALIDARG
;
1139 #if defined (POINTER_DEBUG)
1140 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1143 return DHCP_R_INVALIDARG
;
1147 if ((*h
) -> refcnt
<= 0) {
1148 #if defined (POINTER_DEBUG)
1149 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1151 #if defined (DEBUG_RC_HISTORY)
1152 dump_rc_history (*h
);
1157 return DHCP_R_INVALIDARG
;
1162 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1163 if ((*h
) -> refcnt
<= 0 ) {
1164 dfree (*h
, file
, line
);
1167 return ISC_R_SUCCESS
;