3 Functions supporting memory allocation for the object management
7 * Copyright (c) 2012,2014 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
10 * Copyright (c) 1999-2003 by Internet Software Consortium
12 * Permission to use, copy, modify, and distribute this software for any
13 * purpose with or without fee is hereby granted, provided that the above
14 * copyright notice and this permission notice appear in all copies.
16 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
17 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
19 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
22 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Internet Systems Consortium, Inc.
26 * Redwood City, CA 94063
28 * https://www.isc.org/
34 #include <omapip/omapip_p.h>
36 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
37 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
38 struct dmalloc_preamble
*dmalloc_list
;
39 unsigned long dmalloc_outstanding
;
40 unsigned long dmalloc_longterm
;
41 unsigned long dmalloc_generation
;
42 unsigned long dmalloc_cutoff_generation
;
45 #if defined (DEBUG_RC_HISTORY)
46 struct rc_history_entry rc_history
[RC_HISTORY_MAX
];
51 #if defined (DEBUG_RC_HISTORY)
52 static void print_rc_hist_entry (int);
56 dmalloc(unsigned size
, const char *file
, int line
) {
60 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
61 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
63 struct dmalloc_preamble
*dp
;
74 bar
= (void *)(foo
+ DMDOFFSET
);
75 memset (bar
, 0, size
);
77 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
78 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
79 dp
= (struct dmalloc_preamble
*)foo
;
80 dp
-> prev
= dmalloc_list
;
82 dmalloc_list
-> next
= dp
;
84 dp
-> next
= (struct dmalloc_preamble
*)0;
88 dp
-> generation
= dmalloc_generation
++;
89 dmalloc_outstanding
+= size
;
90 for (i
= 0; i
< DMLFSIZE
; i
++)
93 (&dp
-> low_fence
[i
])) % 143) + 113;
94 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++)
97 (&foo
[i
+ size
])) % 143) + 113;
98 #if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
99 /* Check _every_ entry in the pool! Very expensive. */
100 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
) {
101 for (i
= 0; i
< DMLFSIZE
; i
++) {
102 if (dp
-> low_fence
[i
] !=
104 (&dp
-> low_fence
[i
])) % 143) + 113)
106 log_error ("malloc fence modified: %s(%d)",
107 dp
-> file
, dp
-> line
);
111 foo
= (unsigned char *)dp
;
112 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++) {
113 if (foo
[i
+ dp
-> size
] !=
115 (&foo
[i
+ dp
-> size
])) % 143) + 113) {
116 log_error ("malloc fence modified: %s(%d)",
117 dp
-> file
, dp
-> line
);
124 #ifdef DEBUG_REFCNT_DMALLOC_FREE
125 rc_register (file
, line
, 0, foo
+ DMDOFFSET
, 1, 0, RC_MALLOC
);
131 dfree(void *ptr
, const char *file
, int 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. */
198 dmalloc_reuse(void *foo
, const char *file
, int line
, int justref
) {
199 struct dmalloc_preamble
*dp
;
201 /* Get the pointer to the dmalloc header. */
205 /* If we just allocated this and are now referencing it, this
206 function would almost be a no-op, except that it would
207 increment the generation count needlessly. So just return
209 if (dp
-> generation
== dmalloc_generation
)
212 /* If this is longterm data, and we just made reference to it,
213 don't put it on the short-term list or change its name -
214 we don't need to know about this. */
215 if (dp
-> generation
< dmalloc_cutoff_generation
&& justref
)
218 /* Take it out of the place in the allocated list where it was. */
220 dp
-> prev
-> next
= dp
-> next
;
222 dp
-> next
-> prev
= dp
-> prev
;
223 if (dp
== dmalloc_list
)
224 dmalloc_list
= dp
-> prev
;
226 /* Account for its removal. */
227 if (dp
-> generation
>= dmalloc_cutoff_generation
)
228 dmalloc_outstanding
-= dp
-> size
;
230 dmalloc_longterm
-= dp
-> size
;
232 /* Now put it at the head of the list. */
233 dp
-> prev
= dmalloc_list
;
235 dmalloc_list
-> next
= dp
;
237 dp
-> next
= (struct dmalloc_preamble
*)0;
239 /* Change the reference location information. */
243 /* Increment the generation. */
244 dp
-> generation
= dmalloc_generation
++;
246 /* Account for it. */
247 dmalloc_outstanding
+= dp
-> size
;
250 void dmalloc_dump_outstanding ()
252 static unsigned long dmalloc_cutoff_point
;
253 struct dmalloc_preamble
*dp
;
254 #if defined(DEBUG_MALLOC_POOL)
259 if (!dmalloc_cutoff_point
)
260 dmalloc_cutoff_point
= dmalloc_cutoff_generation
;
261 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
) {
262 if (dp
-> generation
<= dmalloc_cutoff_point
)
264 #if defined (DEBUG_MALLOC_POOL)
265 for (i
= 0; i
< DMLFSIZE
; i
++) {
266 if (dp
-> low_fence
[i
] !=
268 (&dp
-> low_fence
[i
])) % 143) + 113)
270 log_error ("malloc fence modified: %s(%d)",
271 dp
-> file
, dp
-> line
);
275 foo
= (unsigned char *)dp
;
276 for (i
= DMDOFFSET
; i
< DMDSIZE
; i
++) {
277 if (foo
[i
+ dp
-> size
] !=
279 (&foo
[i
+ dp
-> size
])) % 143) + 113) {
280 log_error ("malloc fence modified: %s(%d)",
281 dp
-> file
, dp
-> line
);
286 #if defined (DEBUG_MEMORY_LEAKAGE) || \
287 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
288 /* Don't count data that's actually on a free list
291 #if defined (DEBUG_RC_HISTORY)
292 int i
, count
, inhistory
= 0, noted
= 0;
294 /* If we have the info, see if this is actually
296 if (rc_history_count
< RC_HISTORY_MAX
) {
297 count
= rc_history_count
;
299 count
= RC_HISTORY_MAX
;
300 i
= rc_history_index
- 1;
305 if (rc_history
[i
].addr
== dp
+ 1) {
308 log_info (" %s(%d): %ld", dp
-> file
,
309 dp
-> line
, (long) dp
-> size
);
312 print_rc_hist_entry (i
);
313 if (!rc_history
[i
].refcnt
)
317 i
= RC_HISTORY_MAX
- 1;
321 log_info (" %s(%d): %ld",
322 dp
-> file
, dp
-> line
,
328 dmalloc_cutoff_point
= dmalloc_list
-> generation
;
330 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
332 #if defined (DEBUG_RC_HISTORY)
333 static void print_rc_hist_entry (int i
)
335 log_info (" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
336 rc_history
[i
].file
, rc_history
[i
].line
,
337 (unsigned long)rc_history
[i
].reference
,
338 (unsigned long)rc_history
[i
].addr
,
339 rc_history
[i
].refcnt
);
342 void dump_rc_history (void *addr
)
346 i
= rc_history_index
;
347 if (!rc_history
[i
].file
)
349 else if (rc_history_count
< RC_HISTORY_MAX
) {
350 i
-= rc_history_count
;
354 rc_history_count
= 0;
356 while (rc_history
[i
].file
) {
357 if (!addr
|| addr
== rc_history
[i
].addr
)
358 print_rc_hist_entry (i
);
360 if (i
== RC_HISTORY_MAX
)
362 if (i
== rc_history_index
)
366 void rc_history_next (int d
)
368 #if defined (RC_HISTORY_COMPRESSION)
369 int i
, j
= 0, m
, n
= 0;
372 /* If we are decreasing the reference count, try to find the
373 entry where the reference was made and eliminate it; then
374 we can also eliminate this reference. */
376 m
= rc_history_index
- 1000;
379 ap
= rc_history
[rc_history_index
].addr
;
380 rp
= rc_history
[rc_history_index
].reference
;
381 for (i
= rc_history_index
- 1; i
> m
; i
--) {
382 if (rc_history
[i
].addr
== ap
) {
383 if (rc_history
[i
].reference
== rp
) {
385 for (n
= i
; n
<= rc_history_index
; n
++)
386 print_rc_hist_entry (n
);
389 memmove (&rc_history
[i
],
391 (unsigned)((rc_history_index
- i
) *
392 sizeof (struct rc_history_entry
)));
395 for (j
= i
; j
< rc_history_count
; j
++) {
396 if (rc_history
[j
].addr
== ap
)
397 --rc_history
[j
].refcnt
;
400 for (n
= i
; n
<= rc_history_index
; n
++)
401 print_rc_hist_entry (n
);
411 if (++rc_history_index
== RC_HISTORY_MAX
)
412 rc_history_index
= 0;
415 #endif /* DEBUG_RC_HISTORY */
417 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
418 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
420 struct dmalloc_preamble
*dp
;
424 static int dmalloc_find_entry (struct dmalloc_preamble
*dp
,
425 struct caller
*array
,
430 middle
= (min
+ max
) / 2;
433 if (array
[middle
].dp
-> file
== dp
-> file
) {
434 if (array
[middle
].dp
-> line
== dp
-> line
)
436 else if (array
[middle
].dp
-> line
< dp
-> line
)
437 return dmalloc_find_entry (dp
, array
, middle
, max
);
439 return dmalloc_find_entry (dp
, array
, 0, middle
);
440 } else if (array
[middle
].dp
-> file
< dp
-> file
)
441 return dmalloc_find_entry (dp
, array
, middle
, max
);
443 return dmalloc_find_entry (dp
, array
, 0, middle
);
446 void omapi_print_dmalloc_usage_by_caller ()
448 struct dmalloc_preamble
*dp
;
450 struct caller cp
[1024];
455 memset (cp
, 0, sizeof cp
);
456 for (dp
= dmalloc_list
; dp
; dp
= dp
-> prev
) {
457 i
= dmalloc_find_entry (dp
, cp
, 0, ccur
);
459 cp
[i
].dp
-> file
!= dp
-> file
||
460 cp
[i
].dp
-> line
!= dp
-> line
) &&
462 log_error ("no space for memory usage summary.");
468 } else if (cp
[i
].dp
-> file
< dp
-> file
||
469 (cp
[i
].dp
-> file
== dp
-> file
&&
470 cp
[i
].dp
-> line
< dp
-> line
)) {
472 memmove (cp
+ i
+ 2, cp
+ i
+ 1,
473 (ccur
- i
) * sizeof *cp
);
475 cp
[i
+ 1].count
= 1;
477 } else if (cp
[i
].dp
-> file
!= dp
-> file
||
478 cp
[i
].dp
-> line
!= dp
-> line
) {
480 cp
+ i
, (ccur
- i
) * sizeof *cp
);
487 printf ("%d\t%s:%d\n", i
, dp
-> file
, dp
-> line
);
488 dump_rc_history (dp
+ 1);
491 for (i
= 0; i
< ccur
; i
++) {
492 printf ("%d\t%s:%d\t%d\n", i
,
493 cp
[i
].dp
-> file
, cp
[i
].dp
-> line
, cp
[i
].count
);
494 #if defined(DUMP_RC_HISTORY)
495 dump_rc_history (cp
[i
].dp
+ 1);
499 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
501 isc_result_t
omapi_object_allocate (omapi_object_t
**o
,
502 omapi_object_type_t
*type
,
504 const char *file
, int line
)
510 if (type
-> allocator
) {
511 foo
= (omapi_object_t
*)0;
512 status
= (*type
-> allocator
) (&foo
, file
, line
);
513 tsize
= type
-> size
;
515 status
= ISC_R_NOMEMORY
;
519 if (status
== ISC_R_NOMEMORY
) {
521 tsize
= (*type
-> sizer
) (size
);
523 tsize
= type
-> size
;
526 if (tsize
< sizeof (omapi_object_t
))
527 return DHCP_R_INVALIDARG
;
529 foo
= dmalloc (tsize
, file
, line
);
531 return ISC_R_NOMEMORY
;
534 status
= omapi_object_initialize (foo
, type
, size
, tsize
, file
, line
);
535 if (status
!= ISC_R_SUCCESS
) {
537 (*type
-> freer
) (foo
, file
, line
);
539 dfree (foo
, file
, line
);
542 return omapi_object_reference (o
, foo
, file
, line
);
545 isc_result_t
omapi_object_initialize (omapi_object_t
*o
,
546 omapi_object_type_t
*type
,
547 size_t usize
, size_t psize
,
548 const char *file
, int line
)
550 memset (o
, 0, psize
);
552 if (type
-> initialize
)
553 (*type
-> initialize
) (o
, file
, line
);
554 return ISC_R_SUCCESS
;
557 isc_result_t
omapi_object_reference (omapi_object_t
**r
,
559 const char *file
, int line
)
562 return DHCP_R_INVALIDARG
;
565 #if defined (POINTER_DEBUG)
566 log_error ("%s(%d): reference store into non-null pointer!",
570 return DHCP_R_INVALIDARG
;
575 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, h
-> type
-> rc_flag
);
576 return ISC_R_SUCCESS
;
579 isc_result_t
omapi_object_dereference (omapi_object_t
**h
,
580 const char *file
, int line
)
582 int outer_reference
= 0;
583 int inner_reference
= 0;
584 int handle_reference
= 0;
585 int extra_references
;
586 omapi_object_t
*p
, *hp
;
589 return DHCP_R_INVALIDARG
;
592 #if defined (POINTER_DEBUG)
593 log_error ("%s(%d): dereference of null pointer!", file
, line
);
596 return DHCP_R_INVALIDARG
;
600 if ((*h
) -> refcnt
<= 0) {
601 #if defined (POINTER_DEBUG)
602 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
604 #if defined (DEBUG_RC_HISTORY)
605 dump_rc_history (*h
);
610 return DHCP_R_INVALIDARG
;
614 /* See if this object's inner object refers to it, but don't
615 count this as a reference if we're being asked to free the
616 reference from the inner object. */
617 if ((*h
) -> inner
&& (*h
) -> inner
-> outer
&&
618 h
!= &((*h
) -> inner
-> outer
))
621 /* Ditto for the outer object. */
622 if ((*h
) -> outer
&& (*h
) -> outer
-> inner
&&
623 h
!= &((*h
) -> outer
-> inner
))
626 /* Ditto for the outer object. The code below assumes that
627 the only reason we'd get a dereference from the handle
628 table is if this function does it - otherwise we'd have to
629 traverse the handle table to find the address where the
630 reference is stored and compare against that, and we don't
631 want to do that if we can avoid it. */
633 handle_reference
= 1;
635 /* If we are getting rid of the last reference other than
636 references to inner and outer objects, or from the handle
637 table, then we must examine all the objects in either
638 direction to see if they hold any non-inner, non-outer,
639 non-handle-table references. If not, we need to free the
640 entire chain of objects. */
641 if ((*h
) -> refcnt
==
642 inner_reference
+ outer_reference
+ handle_reference
+ 1) {
643 if (inner_reference
|| outer_reference
|| handle_reference
) {
644 /* XXX we could check for a reference from the
645 handle table here. */
646 extra_references
= 0;
647 for (p
= (*h
) -> inner
;
648 p
&& !extra_references
; p
= p
-> inner
) {
649 extra_references
+= p
-> refcnt
;
650 if (p
-> inner
&& p
-> inner
-> outer
== p
)
657 for (p
= (*h
) -> outer
;
658 p
&& !extra_references
; p
= p
-> outer
) {
659 extra_references
+= p
-> refcnt
;
660 if (p
-> outer
&& p
-> outer
-> inner
== p
)
668 extra_references
= 0;
670 if (!extra_references
) {
675 omapi_object_dereference
676 (&hp
-> inner
, file
, line
);
678 omapi_object_dereference
679 (&hp
-> outer
, file
, line
);
680 /* if (!hp -> type -> freer) */
681 rc_register (file
, line
, h
, hp
,
682 0, 1, hp
-> type
-> rc_flag
);
683 if (handle_reference
) {
684 if (omapi_handle_clear(hp
->handle
) !=
686 log_debug("Attempt to clear null "
690 if (hp
-> type
-> destroy
)
691 (*(hp
-> type
-> destroy
)) (hp
, file
, line
);
692 if (hp
-> type
-> freer
)
693 (hp
-> type
-> freer (hp
, file
, line
));
695 dfree (hp
, file
, line
);
698 /* if (!(*h) -> type -> freer) */
699 rc_register (file
, line
,
700 h
, *h
, (*h
) -> refcnt
, 1,
701 (*h
) -> type
-> rc_flag
);
705 /* if (!(*h) -> type -> freer) */
706 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1,
707 (*h
) -> type
-> rc_flag
);
710 return ISC_R_SUCCESS
;
713 isc_result_t
omapi_buffer_new (omapi_buffer_t
**h
,
714 const char *file
, int line
)
719 t
= (omapi_buffer_t
*)dmalloc (sizeof *t
, file
, line
);
721 return ISC_R_NOMEMORY
;
722 memset (t
, 0, sizeof *t
);
723 status
= omapi_buffer_reference (h
, t
, file
, line
);
724 if (status
!= ISC_R_SUCCESS
)
725 dfree (t
, file
, line
);
726 (*h
) -> head
= sizeof ((*h
) -> buf
) - 1;
730 isc_result_t
omapi_buffer_reference (omapi_buffer_t
**r
,
732 const char *file
, int line
)
735 return DHCP_R_INVALIDARG
;
738 #if defined (POINTER_DEBUG)
739 log_error ("%s(%d): reference store into non-null pointer!",
743 return DHCP_R_INVALIDARG
;
748 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
749 return ISC_R_SUCCESS
;
752 isc_result_t
omapi_buffer_dereference (omapi_buffer_t
**h
,
753 const char *file
, int line
)
756 return DHCP_R_INVALIDARG
;
759 #if defined (POINTER_DEBUG)
760 log_error ("%s(%d): dereference of null pointer!", file
, line
);
763 return DHCP_R_INVALIDARG
;
767 if ((*h
) -> refcnt
<= 0) {
768 #if defined (POINTER_DEBUG)
769 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
771 #if defined (DEBUG_RC_HISTORY)
772 dump_rc_history (*h
);
777 return DHCP_R_INVALIDARG
;
782 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
783 if ((*h
) -> refcnt
== 0)
784 dfree (*h
, file
, line
);
786 return ISC_R_SUCCESS
;
789 isc_result_t
omapi_typed_data_new (const char *file
, int line
,
790 omapi_typed_data_t
**t
,
791 omapi_datatype_t type
, ...)
794 omapi_typed_data_t
*new;
800 omapi_object_t
*obj
= NULL
;
805 case omapi_datatype_int
:
806 len
= OMAPI_TYPED_DATA_INT_LEN
;
807 intval
= va_arg (l
, int);
809 case omapi_datatype_string
:
810 s
= va_arg (l
, char *);
812 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
815 return DHCP_R_INVALIDARG
;
818 case omapi_datatype_data
:
819 val
= va_arg (l
, unsigned);
820 len
= OMAPI_TYPED_DATA_NOBUFFER_LEN
+ val
;
823 return DHCP_R_INVALIDARG
;
826 case omapi_datatype_object
:
827 len
= OMAPI_TYPED_DATA_OBJECT_LEN
;
828 obj
= va_arg (l
, omapi_object_t
*);
832 return DHCP_R_INVALIDARG
;
836 new = dmalloc (len
, file
, line
);
838 return ISC_R_NOMEMORY
;
839 memset (new, 0, len
);
842 case omapi_datatype_int
:
843 new -> u
.integer
= intval
;
845 case omapi_datatype_string
:
846 memcpy (new -> u
.buffer
.value
, s
, val
);
847 new -> u
.buffer
.len
= val
;
849 case omapi_datatype_data
:
850 new -> u
.buffer
.len
= val
;
852 case omapi_datatype_object
:
853 status
= omapi_object_reference (&new -> u
.object
, obj
,
855 if (status
!= ISC_R_SUCCESS
) {
856 dfree (new, file
, line
);
863 return omapi_typed_data_reference (t
, new, file
, line
);
866 isc_result_t
omapi_typed_data_reference (omapi_typed_data_t
**r
,
867 omapi_typed_data_t
*h
,
868 const char *file
, int line
)
871 return DHCP_R_INVALIDARG
;
874 #if defined (POINTER_DEBUG)
875 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
878 return DHCP_R_INVALIDARG
;
883 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
884 return ISC_R_SUCCESS
;
887 isc_result_t
omapi_typed_data_dereference (omapi_typed_data_t
**h
,
888 const char *file
, int line
)
891 return DHCP_R_INVALIDARG
;
894 #if defined (POINTER_DEBUG)
895 log_error ("%s(%d): dereference of null pointer!", file
, line
);
898 return DHCP_R_INVALIDARG
;
902 if ((*h
) -> refcnt
<= 0) {
903 #if defined (POINTER_DEBUG)
904 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
906 #if defined (DEBUG_RC_HISTORY)
907 dump_rc_history (*h
);
912 return DHCP_R_INVALIDARG
;
917 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
918 if ((*h
) -> refcnt
<= 0 ) {
919 switch ((*h
) -> type
) {
920 case omapi_datatype_int
:
921 case omapi_datatype_string
:
922 case omapi_datatype_data
:
925 case omapi_datatype_object
:
926 omapi_object_dereference (&(*h
) -> u
.object
,
930 dfree (*h
, file
, line
);
933 return ISC_R_SUCCESS
;
936 isc_result_t
omapi_data_string_new (omapi_data_string_t
**d
, unsigned len
,
937 const char *file
, int line
)
939 omapi_data_string_t
*new;
942 nlen
= OMAPI_DATA_STRING_EMPTY_SIZE
+ len
;
944 return DHCP_R_INVALIDARG
;
945 new = dmalloc (nlen
, file
, line
);
947 return ISC_R_NOMEMORY
;
948 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE
);
950 return omapi_data_string_reference (d
, new, file
, line
);
953 isc_result_t
omapi_data_string_reference (omapi_data_string_t
**r
,
954 omapi_data_string_t
*h
,
955 const char *file
, int line
)
958 return DHCP_R_INVALIDARG
;
961 #if defined (POINTER_DEBUG)
962 log_error ("%s(%d): reference store into non-null pointer!", file
, line
);
965 return DHCP_R_INVALIDARG
;
970 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
971 return ISC_R_SUCCESS
;
974 isc_result_t
omapi_data_string_dereference (omapi_data_string_t
**h
,
975 const char *file
, int line
)
978 return DHCP_R_INVALIDARG
;
981 #if defined (POINTER_DEBUG)
982 log_error ("%s(%d): dereference of null pointer!", file
, line
);
985 return DHCP_R_INVALIDARG
;
989 if ((*h
) -> refcnt
<= 0) {
990 #if defined (POINTER_DEBUG)
991 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
993 #if defined (DEBUG_RC_HISTORY)
994 dump_rc_history (*h
);
999 return DHCP_R_INVALIDARG
;
1004 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1005 if ((*h
) -> refcnt
<= 0 ) {
1006 dfree (*h
, file
, line
);
1009 return ISC_R_SUCCESS
;
1012 isc_result_t
omapi_value_new (omapi_value_t
**d
,
1013 const char *file
, int line
)
1017 new = dmalloc (sizeof *new, file
, line
);
1019 return ISC_R_NOMEMORY
;
1020 memset (new, 0, sizeof *new);
1021 return omapi_value_reference (d
, new, file
, line
);
1024 isc_result_t
omapi_value_reference (omapi_value_t
**r
,
1026 const char *file
, int line
)
1029 return DHCP_R_INVALIDARG
;
1032 #if defined (POINTER_DEBUG)
1033 log_error ("%s(%d): reference store into non-null pointer!",
1037 return DHCP_R_INVALIDARG
;
1042 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
1043 return ISC_R_SUCCESS
;
1046 isc_result_t
omapi_value_dereference (omapi_value_t
**h
,
1047 const char *file
, int line
)
1050 return DHCP_R_INVALIDARG
;
1053 #if defined (POINTER_DEBUG)
1054 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1057 return DHCP_R_INVALIDARG
;
1061 if ((*h
) -> refcnt
<= 0) {
1062 #if defined (POINTER_DEBUG)
1063 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1065 #if defined (DEBUG_RC_HISTORY)
1066 dump_rc_history (*h
);
1071 return DHCP_R_INVALIDARG
;
1076 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1077 if ((*h
) -> refcnt
== 0) {
1079 omapi_data_string_dereference (&(*h
) -> name
,
1082 omapi_typed_data_dereference (&(*h
) -> value
,
1084 dfree (*h
, file
, line
);
1087 return ISC_R_SUCCESS
;
1090 isc_result_t
omapi_addr_list_new (omapi_addr_list_t
**d
, unsigned count
,
1091 const char *file
, int line
)
1093 omapi_addr_list_t
*new;
1095 new = dmalloc ((count
* sizeof (omapi_addr_t
)) +
1096 sizeof (omapi_addr_list_t
), file
, line
);
1098 return ISC_R_NOMEMORY
;
1099 memset (new, 0, ((count
* sizeof (omapi_addr_t
)) +
1100 sizeof (omapi_addr_list_t
)));
1101 new -> count
= count
;
1102 new -> addresses
= (omapi_addr_t
*)(new + 1);
1103 return omapi_addr_list_reference (d
, new, file
, line
);
1106 isc_result_t
omapi_addr_list_reference (omapi_addr_list_t
**r
,
1107 omapi_addr_list_t
*h
,
1108 const char *file
, int line
)
1111 return DHCP_R_INVALIDARG
;
1114 #if defined (POINTER_DEBUG)
1115 log_error ("%s(%d): reference store into non-null pointer!",
1119 return DHCP_R_INVALIDARG
;
1124 rc_register (file
, line
, r
, h
, h
-> refcnt
, 0, RC_MISC
);
1125 return ISC_R_SUCCESS
;
1128 isc_result_t
omapi_addr_list_dereference (omapi_addr_list_t
**h
,
1129 const char *file
, int line
)
1132 return DHCP_R_INVALIDARG
;
1135 #if defined (POINTER_DEBUG)
1136 log_error ("%s(%d): dereference of null pointer!", file
, line
);
1139 return DHCP_R_INVALIDARG
;
1143 if ((*h
) -> refcnt
<= 0) {
1144 #if defined (POINTER_DEBUG)
1145 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1147 #if defined (DEBUG_RC_HISTORY)
1148 dump_rc_history (*h
);
1153 return DHCP_R_INVALIDARG
;
1158 rc_register (file
, line
, h
, *h
, (*h
) -> refcnt
, 1, RC_MISC
);
1159 if ((*h
) -> refcnt
<= 0 ) {
1160 dfree (*h
, file
, line
);
1163 return ISC_R_SUCCESS
;