1*83ee113eSDavid van Moolenbroek /* $NetBSD: alloc.c,v 1.1.1.3 2014/07/12 11:57:58 spz Exp $ */
2*83ee113eSDavid van Moolenbroek /* alloc.c
3*83ee113eSDavid van Moolenbroek
4*83ee113eSDavid van Moolenbroek Functions supporting memory allocation for the object management
5*83ee113eSDavid van Moolenbroek protocol... */
6*83ee113eSDavid van Moolenbroek
7*83ee113eSDavid van Moolenbroek /*
8*83ee113eSDavid van Moolenbroek * Copyright (c) 2012,2014 by Internet Systems Consortium, Inc. ("ISC")
9*83ee113eSDavid van Moolenbroek * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC")
10*83ee113eSDavid van Moolenbroek * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
11*83ee113eSDavid van Moolenbroek * Copyright (c) 1999-2003 by Internet Software Consortium
12*83ee113eSDavid van Moolenbroek *
13*83ee113eSDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any
14*83ee113eSDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
15*83ee113eSDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
16*83ee113eSDavid van Moolenbroek *
17*83ee113eSDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
18*83ee113eSDavid van Moolenbroek * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19*83ee113eSDavid van Moolenbroek * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
20*83ee113eSDavid van Moolenbroek * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21*83ee113eSDavid van Moolenbroek * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22*83ee113eSDavid van Moolenbroek * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
23*83ee113eSDavid van Moolenbroek * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24*83ee113eSDavid van Moolenbroek *
25*83ee113eSDavid van Moolenbroek * Internet Systems Consortium, Inc.
26*83ee113eSDavid van Moolenbroek * 950 Charter Street
27*83ee113eSDavid van Moolenbroek * Redwood City, CA 94063
28*83ee113eSDavid van Moolenbroek * <info@isc.org>
29*83ee113eSDavid van Moolenbroek * https://www.isc.org/
30*83ee113eSDavid van Moolenbroek *
31*83ee113eSDavid van Moolenbroek */
32*83ee113eSDavid van Moolenbroek
33*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
34*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: alloc.c,v 1.1.1.3 2014/07/12 11:57:58 spz Exp $");
35*83ee113eSDavid van Moolenbroek
36*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
37*83ee113eSDavid van Moolenbroek
38*83ee113eSDavid van Moolenbroek #include <omapip/omapip_p.h>
39*83ee113eSDavid van Moolenbroek
40*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
41*83ee113eSDavid van Moolenbroek defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
42*83ee113eSDavid van Moolenbroek struct dmalloc_preamble *dmalloc_list;
43*83ee113eSDavid van Moolenbroek unsigned long dmalloc_outstanding;
44*83ee113eSDavid van Moolenbroek unsigned long dmalloc_longterm;
45*83ee113eSDavid van Moolenbroek unsigned long dmalloc_generation;
46*83ee113eSDavid van Moolenbroek unsigned long dmalloc_cutoff_generation;
47*83ee113eSDavid van Moolenbroek #endif
48*83ee113eSDavid van Moolenbroek
49*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
50*83ee113eSDavid van Moolenbroek struct rc_history_entry rc_history [RC_HISTORY_MAX];
51*83ee113eSDavid van Moolenbroek int rc_history_index;
52*83ee113eSDavid van Moolenbroek int rc_history_count;
53*83ee113eSDavid van Moolenbroek #endif
54*83ee113eSDavid van Moolenbroek
55*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
56*83ee113eSDavid van Moolenbroek static void print_rc_hist_entry (int);
57*83ee113eSDavid van Moolenbroek #endif
58*83ee113eSDavid van Moolenbroek
59*83ee113eSDavid van Moolenbroek void *
dmalloc(unsigned size,const char * file,int line)60*83ee113eSDavid van Moolenbroek dmalloc(unsigned size, const char *file, int line) {
61*83ee113eSDavid van Moolenbroek unsigned char *foo;
62*83ee113eSDavid van Moolenbroek unsigned len;
63*83ee113eSDavid van Moolenbroek void **bar;
64*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
65*83ee113eSDavid van Moolenbroek defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
66*83ee113eSDavid van Moolenbroek int i;
67*83ee113eSDavid van Moolenbroek struct dmalloc_preamble *dp;
68*83ee113eSDavid van Moolenbroek #endif
69*83ee113eSDavid van Moolenbroek
70*83ee113eSDavid van Moolenbroek len = size + DMDSIZE;
71*83ee113eSDavid van Moolenbroek if (len < size)
72*83ee113eSDavid van Moolenbroek return NULL;
73*83ee113eSDavid van Moolenbroek
74*83ee113eSDavid van Moolenbroek foo = malloc(len);
75*83ee113eSDavid van Moolenbroek
76*83ee113eSDavid van Moolenbroek if (!foo)
77*83ee113eSDavid van Moolenbroek return NULL;
78*83ee113eSDavid van Moolenbroek bar = (void *)(foo + DMDOFFSET);
79*83ee113eSDavid van Moolenbroek memset (bar, 0, size);
80*83ee113eSDavid van Moolenbroek
81*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
82*83ee113eSDavid van Moolenbroek defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
83*83ee113eSDavid van Moolenbroek dp = (struct dmalloc_preamble *)foo;
84*83ee113eSDavid van Moolenbroek dp -> prev = dmalloc_list;
85*83ee113eSDavid van Moolenbroek if (dmalloc_list)
86*83ee113eSDavid van Moolenbroek dmalloc_list -> next = dp;
87*83ee113eSDavid van Moolenbroek dmalloc_list = dp;
88*83ee113eSDavid van Moolenbroek dp -> next = (struct dmalloc_preamble *)0;
89*83ee113eSDavid van Moolenbroek dp -> size = size;
90*83ee113eSDavid van Moolenbroek dp -> file = file;
91*83ee113eSDavid van Moolenbroek dp -> line = line;
92*83ee113eSDavid van Moolenbroek dp -> generation = dmalloc_generation++;
93*83ee113eSDavid van Moolenbroek dmalloc_outstanding += size;
94*83ee113eSDavid van Moolenbroek for (i = 0; i < DMLFSIZE; i++)
95*83ee113eSDavid van Moolenbroek dp -> low_fence [i] =
96*83ee113eSDavid van Moolenbroek (((unsigned long)
97*83ee113eSDavid van Moolenbroek (&dp -> low_fence [i])) % 143) + 113;
98*83ee113eSDavid van Moolenbroek for (i = DMDOFFSET; i < DMDSIZE; i++)
99*83ee113eSDavid van Moolenbroek foo [i + size] =
100*83ee113eSDavid van Moolenbroek (((unsigned long)
101*83ee113eSDavid van Moolenbroek (&foo [i + size])) % 143) + 113;
102*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
103*83ee113eSDavid van Moolenbroek /* Check _every_ entry in the pool! Very expensive. */
104*83ee113eSDavid van Moolenbroek for (dp = dmalloc_list; dp; dp = dp -> prev) {
105*83ee113eSDavid van Moolenbroek for (i = 0; i < DMLFSIZE; i++) {
106*83ee113eSDavid van Moolenbroek if (dp -> low_fence [i] !=
107*83ee113eSDavid van Moolenbroek (((unsigned long)
108*83ee113eSDavid van Moolenbroek (&dp -> low_fence [i])) % 143) + 113)
109*83ee113eSDavid van Moolenbroek {
110*83ee113eSDavid van Moolenbroek log_error ("malloc fence modified: %s(%d)",
111*83ee113eSDavid van Moolenbroek dp -> file, dp -> line);
112*83ee113eSDavid van Moolenbroek abort ();
113*83ee113eSDavid van Moolenbroek }
114*83ee113eSDavid van Moolenbroek }
115*83ee113eSDavid van Moolenbroek foo = (unsigned char *)dp;
116*83ee113eSDavid van Moolenbroek for (i = DMDOFFSET; i < DMDSIZE; i++) {
117*83ee113eSDavid van Moolenbroek if (foo [i + dp -> size] !=
118*83ee113eSDavid van Moolenbroek (((unsigned long)
119*83ee113eSDavid van Moolenbroek (&foo [i + dp -> size])) % 143) + 113) {
120*83ee113eSDavid van Moolenbroek log_error ("malloc fence modified: %s(%d)",
121*83ee113eSDavid van Moolenbroek dp -> file, dp -> line);
122*83ee113eSDavid van Moolenbroek abort ();
123*83ee113eSDavid van Moolenbroek }
124*83ee113eSDavid van Moolenbroek }
125*83ee113eSDavid van Moolenbroek }
126*83ee113eSDavid van Moolenbroek #endif
127*83ee113eSDavid van Moolenbroek #endif
128*83ee113eSDavid van Moolenbroek #ifdef DEBUG_REFCNT_DMALLOC_FREE
129*83ee113eSDavid van Moolenbroek rc_register (file, line, 0, foo + DMDOFFSET, 1, 0, RC_MALLOC);
130*83ee113eSDavid van Moolenbroek #endif
131*83ee113eSDavid van Moolenbroek return bar;
132*83ee113eSDavid van Moolenbroek }
133*83ee113eSDavid van Moolenbroek
134*83ee113eSDavid van Moolenbroek void
dfree(void * ptr,const char * file,int line)135*83ee113eSDavid van Moolenbroek dfree(void *ptr, const char *file, int line) {
136*83ee113eSDavid van Moolenbroek if (!ptr) {
137*83ee113eSDavid van Moolenbroek log_error ("dfree %s(%d): free on null pointer.", file, line);
138*83ee113eSDavid van Moolenbroek return;
139*83ee113eSDavid van Moolenbroek }
140*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
141*83ee113eSDavid van Moolenbroek defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
142*83ee113eSDavid van Moolenbroek {
143*83ee113eSDavid van Moolenbroek unsigned char *bar = ptr;
144*83ee113eSDavid van Moolenbroek struct dmalloc_preamble *dp, *cur;
145*83ee113eSDavid van Moolenbroek int i;
146*83ee113eSDavid van Moolenbroek bar -= DMDOFFSET;
147*83ee113eSDavid van Moolenbroek cur = (struct dmalloc_preamble *)bar;
148*83ee113eSDavid van Moolenbroek for (dp = dmalloc_list; dp; dp = dp -> prev)
149*83ee113eSDavid van Moolenbroek if (dp == cur)
150*83ee113eSDavid van Moolenbroek break;
151*83ee113eSDavid van Moolenbroek if (!dp) {
152*83ee113eSDavid van Moolenbroek log_error ("%s(%d): freeing unknown memory: %lx",
153*83ee113eSDavid van Moolenbroek file, line, (unsigned long)cur);
154*83ee113eSDavid van Moolenbroek abort ();
155*83ee113eSDavid van Moolenbroek }
156*83ee113eSDavid van Moolenbroek if (dp -> prev)
157*83ee113eSDavid van Moolenbroek dp -> prev -> next = dp -> next;
158*83ee113eSDavid van Moolenbroek if (dp -> next)
159*83ee113eSDavid van Moolenbroek dp -> next -> prev = dp -> prev;
160*83ee113eSDavid van Moolenbroek if (dp == dmalloc_list)
161*83ee113eSDavid van Moolenbroek dmalloc_list = dp -> prev;
162*83ee113eSDavid van Moolenbroek if (dp -> generation >= dmalloc_cutoff_generation)
163*83ee113eSDavid van Moolenbroek dmalloc_outstanding -= dp -> size;
164*83ee113eSDavid van Moolenbroek else
165*83ee113eSDavid van Moolenbroek dmalloc_longterm -= dp -> size;
166*83ee113eSDavid van Moolenbroek
167*83ee113eSDavid van Moolenbroek for (i = 0; i < DMLFSIZE; i++) {
168*83ee113eSDavid van Moolenbroek if (dp -> low_fence [i] !=
169*83ee113eSDavid van Moolenbroek (((unsigned long)
170*83ee113eSDavid van Moolenbroek (&dp -> low_fence [i])) % 143) + 113)
171*83ee113eSDavid van Moolenbroek {
172*83ee113eSDavid van Moolenbroek log_error ("malloc fence modified: %s(%d)",
173*83ee113eSDavid van Moolenbroek dp -> file, dp -> line);
174*83ee113eSDavid van Moolenbroek abort ();
175*83ee113eSDavid van Moolenbroek }
176*83ee113eSDavid van Moolenbroek }
177*83ee113eSDavid van Moolenbroek for (i = DMDOFFSET; i < DMDSIZE; i++) {
178*83ee113eSDavid van Moolenbroek if (bar [i + dp -> size] !=
179*83ee113eSDavid van Moolenbroek (((unsigned long)
180*83ee113eSDavid van Moolenbroek (&bar [i + dp -> size])) % 143) + 113) {
181*83ee113eSDavid van Moolenbroek log_error ("malloc fence modified: %s(%d)",
182*83ee113eSDavid van Moolenbroek dp -> file, dp -> line);
183*83ee113eSDavid van Moolenbroek abort ();
184*83ee113eSDavid van Moolenbroek }
185*83ee113eSDavid van Moolenbroek }
186*83ee113eSDavid van Moolenbroek ptr = bar;
187*83ee113eSDavid van Moolenbroek }
188*83ee113eSDavid van Moolenbroek #endif
189*83ee113eSDavid van Moolenbroek #ifdef DEBUG_REFCNT_DMALLOC_FREE
190*83ee113eSDavid van Moolenbroek rc_register (file, line,
191*83ee113eSDavid van Moolenbroek 0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);
192*83ee113eSDavid van Moolenbroek #endif
193*83ee113eSDavid van Moolenbroek free (ptr);
194*83ee113eSDavid van Moolenbroek }
195*83ee113eSDavid van Moolenbroek
196*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
197*83ee113eSDavid van Moolenbroek defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
198*83ee113eSDavid van Moolenbroek /* For allocation functions that keep their own free lists, we want to
199*83ee113eSDavid van Moolenbroek account for the reuse of the memory. */
200*83ee113eSDavid van Moolenbroek
201*83ee113eSDavid van Moolenbroek void
dmalloc_reuse(void * foo,const char * file,int line,int justref)202*83ee113eSDavid van Moolenbroek dmalloc_reuse(void *foo, const char *file, int line, int justref) {
203*83ee113eSDavid van Moolenbroek struct dmalloc_preamble *dp;
204*83ee113eSDavid van Moolenbroek
205*83ee113eSDavid van Moolenbroek /* Get the pointer to the dmalloc header. */
206*83ee113eSDavid van Moolenbroek dp = foo;
207*83ee113eSDavid van Moolenbroek dp--;
208*83ee113eSDavid van Moolenbroek
209*83ee113eSDavid van Moolenbroek /* If we just allocated this and are now referencing it, this
210*83ee113eSDavid van Moolenbroek function would almost be a no-op, except that it would
211*83ee113eSDavid van Moolenbroek increment the generation count needlessly. So just return
212*83ee113eSDavid van Moolenbroek in this case. */
213*83ee113eSDavid van Moolenbroek if (dp -> generation == dmalloc_generation)
214*83ee113eSDavid van Moolenbroek return;
215*83ee113eSDavid van Moolenbroek
216*83ee113eSDavid van Moolenbroek /* If this is longterm data, and we just made reference to it,
217*83ee113eSDavid van Moolenbroek don't put it on the short-term list or change its name -
218*83ee113eSDavid van Moolenbroek we don't need to know about this. */
219*83ee113eSDavid van Moolenbroek if (dp -> generation < dmalloc_cutoff_generation && justref)
220*83ee113eSDavid van Moolenbroek return;
221*83ee113eSDavid van Moolenbroek
222*83ee113eSDavid van Moolenbroek /* Take it out of the place in the allocated list where it was. */
223*83ee113eSDavid van Moolenbroek if (dp -> prev)
224*83ee113eSDavid van Moolenbroek dp -> prev -> next = dp -> next;
225*83ee113eSDavid van Moolenbroek if (dp -> next)
226*83ee113eSDavid van Moolenbroek dp -> next -> prev = dp -> prev;
227*83ee113eSDavid van Moolenbroek if (dp == dmalloc_list)
228*83ee113eSDavid van Moolenbroek dmalloc_list = dp -> prev;
229*83ee113eSDavid van Moolenbroek
230*83ee113eSDavid van Moolenbroek /* Account for its removal. */
231*83ee113eSDavid van Moolenbroek if (dp -> generation >= dmalloc_cutoff_generation)
232*83ee113eSDavid van Moolenbroek dmalloc_outstanding -= dp -> size;
233*83ee113eSDavid van Moolenbroek else
234*83ee113eSDavid van Moolenbroek dmalloc_longterm -= dp -> size;
235*83ee113eSDavid van Moolenbroek
236*83ee113eSDavid van Moolenbroek /* Now put it at the head of the list. */
237*83ee113eSDavid van Moolenbroek dp -> prev = dmalloc_list;
238*83ee113eSDavid van Moolenbroek if (dmalloc_list)
239*83ee113eSDavid van Moolenbroek dmalloc_list -> next = dp;
240*83ee113eSDavid van Moolenbroek dmalloc_list = dp;
241*83ee113eSDavid van Moolenbroek dp -> next = (struct dmalloc_preamble *)0;
242*83ee113eSDavid van Moolenbroek
243*83ee113eSDavid van Moolenbroek /* Change the reference location information. */
244*83ee113eSDavid van Moolenbroek dp -> file = file;
245*83ee113eSDavid van Moolenbroek dp -> line = line;
246*83ee113eSDavid van Moolenbroek
247*83ee113eSDavid van Moolenbroek /* Increment the generation. */
248*83ee113eSDavid van Moolenbroek dp -> generation = dmalloc_generation++;
249*83ee113eSDavid van Moolenbroek
250*83ee113eSDavid van Moolenbroek /* Account for it. */
251*83ee113eSDavid van Moolenbroek dmalloc_outstanding += dp -> size;
252*83ee113eSDavid van Moolenbroek }
253*83ee113eSDavid van Moolenbroek
dmalloc_dump_outstanding()254*83ee113eSDavid van Moolenbroek void dmalloc_dump_outstanding ()
255*83ee113eSDavid van Moolenbroek {
256*83ee113eSDavid van Moolenbroek static unsigned long dmalloc_cutoff_point;
257*83ee113eSDavid van Moolenbroek struct dmalloc_preamble *dp;
258*83ee113eSDavid van Moolenbroek #if defined(DEBUG_MALLOC_POOL)
259*83ee113eSDavid van Moolenbroek unsigned char *foo;
260*83ee113eSDavid van Moolenbroek int i;
261*83ee113eSDavid van Moolenbroek #endif
262*83ee113eSDavid van Moolenbroek
263*83ee113eSDavid van Moolenbroek if (!dmalloc_cutoff_point)
264*83ee113eSDavid van Moolenbroek dmalloc_cutoff_point = dmalloc_cutoff_generation;
265*83ee113eSDavid van Moolenbroek for (dp = dmalloc_list; dp; dp = dp -> prev) {
266*83ee113eSDavid van Moolenbroek if (dp -> generation <= dmalloc_cutoff_point)
267*83ee113eSDavid van Moolenbroek break;
268*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MALLOC_POOL)
269*83ee113eSDavid van Moolenbroek for (i = 0; i < DMLFSIZE; i++) {
270*83ee113eSDavid van Moolenbroek if (dp -> low_fence [i] !=
271*83ee113eSDavid van Moolenbroek (((unsigned long)
272*83ee113eSDavid van Moolenbroek (&dp -> low_fence [i])) % 143) + 113)
273*83ee113eSDavid van Moolenbroek {
274*83ee113eSDavid van Moolenbroek log_error ("malloc fence modified: %s(%d)",
275*83ee113eSDavid van Moolenbroek dp -> file, dp -> line);
276*83ee113eSDavid van Moolenbroek abort ();
277*83ee113eSDavid van Moolenbroek }
278*83ee113eSDavid van Moolenbroek }
279*83ee113eSDavid van Moolenbroek foo = (unsigned char *)dp;
280*83ee113eSDavid van Moolenbroek for (i = DMDOFFSET; i < DMDSIZE; i++) {
281*83ee113eSDavid van Moolenbroek if (foo [i + dp -> size] !=
282*83ee113eSDavid van Moolenbroek (((unsigned long)
283*83ee113eSDavid van Moolenbroek (&foo [i + dp -> size])) % 143) + 113) {
284*83ee113eSDavid van Moolenbroek log_error ("malloc fence modified: %s(%d)",
285*83ee113eSDavid van Moolenbroek dp -> file, dp -> line);
286*83ee113eSDavid van Moolenbroek abort ();
287*83ee113eSDavid van Moolenbroek }
288*83ee113eSDavid van Moolenbroek }
289*83ee113eSDavid van Moolenbroek #endif
290*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) || \
291*83ee113eSDavid van Moolenbroek defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
292*83ee113eSDavid van Moolenbroek /* Don't count data that's actually on a free list
293*83ee113eSDavid van Moolenbroek somewhere. */
294*83ee113eSDavid van Moolenbroek if (dp -> file) {
295*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
296*83ee113eSDavid van Moolenbroek int i, count, inhistory = 0, noted = 0;
297*83ee113eSDavid van Moolenbroek
298*83ee113eSDavid van Moolenbroek /* If we have the info, see if this is actually
299*83ee113eSDavid van Moolenbroek new garbage. */
300*83ee113eSDavid van Moolenbroek if (rc_history_count < RC_HISTORY_MAX) {
301*83ee113eSDavid van Moolenbroek count = rc_history_count;
302*83ee113eSDavid van Moolenbroek } else
303*83ee113eSDavid van Moolenbroek count = RC_HISTORY_MAX;
304*83ee113eSDavid van Moolenbroek i = rc_history_index - 1;
305*83ee113eSDavid van Moolenbroek if (i < 0)
306*83ee113eSDavid van Moolenbroek i += RC_HISTORY_MAX;
307*83ee113eSDavid van Moolenbroek
308*83ee113eSDavid van Moolenbroek do {
309*83ee113eSDavid van Moolenbroek if (rc_history [i].addr == dp + 1) {
310*83ee113eSDavid van Moolenbroek inhistory = 1;
311*83ee113eSDavid van Moolenbroek if (!noted) {
312*83ee113eSDavid van Moolenbroek log_info (" %s(%d): %ld", dp -> file,
313*83ee113eSDavid van Moolenbroek dp -> line, (long) dp -> size);
314*83ee113eSDavid van Moolenbroek noted = 1;
315*83ee113eSDavid van Moolenbroek }
316*83ee113eSDavid van Moolenbroek print_rc_hist_entry (i);
317*83ee113eSDavid van Moolenbroek if (!rc_history [i].refcnt)
318*83ee113eSDavid van Moolenbroek break;
319*83ee113eSDavid van Moolenbroek }
320*83ee113eSDavid van Moolenbroek if (--i < 0)
321*83ee113eSDavid van Moolenbroek i = RC_HISTORY_MAX - 1;
322*83ee113eSDavid van Moolenbroek } while (count--);
323*83ee113eSDavid van Moolenbroek if (!inhistory)
324*83ee113eSDavid van Moolenbroek #endif
325*83ee113eSDavid van Moolenbroek log_info (" %s(%d): %ld",
326*83ee113eSDavid van Moolenbroek dp -> file, dp -> line,
327*83ee113eSDavid van Moolenbroek (long) dp -> size);
328*83ee113eSDavid van Moolenbroek }
329*83ee113eSDavid van Moolenbroek #endif
330*83ee113eSDavid van Moolenbroek }
331*83ee113eSDavid van Moolenbroek if (dmalloc_list)
332*83ee113eSDavid van Moolenbroek dmalloc_cutoff_point = dmalloc_list -> generation;
333*83ee113eSDavid van Moolenbroek }
334*83ee113eSDavid van Moolenbroek #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
335*83ee113eSDavid van Moolenbroek
336*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
print_rc_hist_entry(int i)337*83ee113eSDavid van Moolenbroek static void print_rc_hist_entry (int i)
338*83ee113eSDavid van Moolenbroek {
339*83ee113eSDavid van Moolenbroek log_info (" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
340*83ee113eSDavid van Moolenbroek rc_history [i].file, rc_history [i].line,
341*83ee113eSDavid van Moolenbroek (unsigned long)rc_history [i].reference,
342*83ee113eSDavid van Moolenbroek (unsigned long)rc_history [i].addr,
343*83ee113eSDavid van Moolenbroek rc_history [i].refcnt);
344*83ee113eSDavid van Moolenbroek }
345*83ee113eSDavid van Moolenbroek
dump_rc_history(void * addr)346*83ee113eSDavid van Moolenbroek void dump_rc_history (void *addr)
347*83ee113eSDavid van Moolenbroek {
348*83ee113eSDavid van Moolenbroek int i;
349*83ee113eSDavid van Moolenbroek
350*83ee113eSDavid van Moolenbroek i = rc_history_index;
351*83ee113eSDavid van Moolenbroek if (!rc_history [i].file)
352*83ee113eSDavid van Moolenbroek i = 0;
353*83ee113eSDavid van Moolenbroek else if (rc_history_count < RC_HISTORY_MAX) {
354*83ee113eSDavid van Moolenbroek i -= rc_history_count;
355*83ee113eSDavid van Moolenbroek if (i < 0)
356*83ee113eSDavid van Moolenbroek i += RC_HISTORY_MAX;
357*83ee113eSDavid van Moolenbroek }
358*83ee113eSDavid van Moolenbroek rc_history_count = 0;
359*83ee113eSDavid van Moolenbroek
360*83ee113eSDavid van Moolenbroek while (rc_history [i].file) {
361*83ee113eSDavid van Moolenbroek if (!addr || addr == rc_history [i].addr)
362*83ee113eSDavid van Moolenbroek print_rc_hist_entry (i);
363*83ee113eSDavid van Moolenbroek ++i;
364*83ee113eSDavid van Moolenbroek if (i == RC_HISTORY_MAX)
365*83ee113eSDavid van Moolenbroek i = 0;
366*83ee113eSDavid van Moolenbroek if (i == rc_history_index)
367*83ee113eSDavid van Moolenbroek break;
368*83ee113eSDavid van Moolenbroek }
369*83ee113eSDavid van Moolenbroek }
rc_history_next(int d)370*83ee113eSDavid van Moolenbroek void rc_history_next (int d)
371*83ee113eSDavid van Moolenbroek {
372*83ee113eSDavid van Moolenbroek #if defined (RC_HISTORY_COMPRESSION)
373*83ee113eSDavid van Moolenbroek int i, j = 0, m, n = 0;
374*83ee113eSDavid van Moolenbroek void *ap, *rp;
375*83ee113eSDavid van Moolenbroek
376*83ee113eSDavid van Moolenbroek /* If we are decreasing the reference count, try to find the
377*83ee113eSDavid van Moolenbroek entry where the reference was made and eliminate it; then
378*83ee113eSDavid van Moolenbroek we can also eliminate this reference. */
379*83ee113eSDavid van Moolenbroek if (d) {
380*83ee113eSDavid van Moolenbroek m = rc_history_index - 1000;
381*83ee113eSDavid van Moolenbroek if (m < -1)
382*83ee113eSDavid van Moolenbroek m = -1;
383*83ee113eSDavid van Moolenbroek ap = rc_history [rc_history_index].addr;
384*83ee113eSDavid van Moolenbroek rp = rc_history [rc_history_index].reference;
385*83ee113eSDavid van Moolenbroek for (i = rc_history_index - 1; i > m; i--) {
386*83ee113eSDavid van Moolenbroek if (rc_history [i].addr == ap) {
387*83ee113eSDavid van Moolenbroek if (rc_history [i].reference == rp) {
388*83ee113eSDavid van Moolenbroek if (n > 10) {
389*83ee113eSDavid van Moolenbroek for (n = i; n <= rc_history_index; n++)
390*83ee113eSDavid van Moolenbroek print_rc_hist_entry (n);
391*83ee113eSDavid van Moolenbroek n = 11;
392*83ee113eSDavid van Moolenbroek }
393*83ee113eSDavid van Moolenbroek memmove (&rc_history [i],
394*83ee113eSDavid van Moolenbroek &rc_history [i + 1],
395*83ee113eSDavid van Moolenbroek (unsigned)((rc_history_index - i) *
396*83ee113eSDavid van Moolenbroek sizeof (struct rc_history_entry)));
397*83ee113eSDavid van Moolenbroek --rc_history_count;
398*83ee113eSDavid van Moolenbroek --rc_history_index;
399*83ee113eSDavid van Moolenbroek for (j = i; j < rc_history_count; j++) {
400*83ee113eSDavid van Moolenbroek if (rc_history [j].addr == ap)
401*83ee113eSDavid van Moolenbroek --rc_history [j].refcnt;
402*83ee113eSDavid van Moolenbroek }
403*83ee113eSDavid van Moolenbroek if (n > 10) {
404*83ee113eSDavid van Moolenbroek for (n = i; n <= rc_history_index; n++)
405*83ee113eSDavid van Moolenbroek print_rc_hist_entry (n);
406*83ee113eSDavid van Moolenbroek n = 11;
407*83ee113eSDavid van Moolenbroek exit (0);
408*83ee113eSDavid van Moolenbroek }
409*83ee113eSDavid van Moolenbroek return;
410*83ee113eSDavid van Moolenbroek }
411*83ee113eSDavid van Moolenbroek }
412*83ee113eSDavid van Moolenbroek }
413*83ee113eSDavid van Moolenbroek }
414*83ee113eSDavid van Moolenbroek #endif
415*83ee113eSDavid van Moolenbroek if (++rc_history_index == RC_HISTORY_MAX)
416*83ee113eSDavid van Moolenbroek rc_history_index = 0;
417*83ee113eSDavid van Moolenbroek ++rc_history_count;
418*83ee113eSDavid van Moolenbroek }
419*83ee113eSDavid van Moolenbroek #endif /* DEBUG_RC_HISTORY */
420*83ee113eSDavid van Moolenbroek
421*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
422*83ee113eSDavid van Moolenbroek defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
423*83ee113eSDavid van Moolenbroek struct caller {
424*83ee113eSDavid van Moolenbroek struct dmalloc_preamble *dp;
425*83ee113eSDavid van Moolenbroek int count;
426*83ee113eSDavid van Moolenbroek };
427*83ee113eSDavid van Moolenbroek
dmalloc_find_entry(struct dmalloc_preamble * dp,struct caller * array,int min,int max)428*83ee113eSDavid van Moolenbroek static int dmalloc_find_entry (struct dmalloc_preamble *dp,
429*83ee113eSDavid van Moolenbroek struct caller *array,
430*83ee113eSDavid van Moolenbroek int min, int max)
431*83ee113eSDavid van Moolenbroek {
432*83ee113eSDavid van Moolenbroek int middle;
433*83ee113eSDavid van Moolenbroek
434*83ee113eSDavid van Moolenbroek middle = (min + max) / 2;
435*83ee113eSDavid van Moolenbroek if (middle == min)
436*83ee113eSDavid van Moolenbroek return middle;
437*83ee113eSDavid van Moolenbroek if (array [middle].dp -> file == dp -> file) {
438*83ee113eSDavid van Moolenbroek if (array [middle].dp -> line == dp -> line)
439*83ee113eSDavid van Moolenbroek return middle;
440*83ee113eSDavid van Moolenbroek else if (array [middle].dp -> line < dp -> line)
441*83ee113eSDavid van Moolenbroek return dmalloc_find_entry (dp, array, middle, max);
442*83ee113eSDavid van Moolenbroek else
443*83ee113eSDavid van Moolenbroek return dmalloc_find_entry (dp, array, 0, middle);
444*83ee113eSDavid van Moolenbroek } else if (array [middle].dp -> file < dp -> file)
445*83ee113eSDavid van Moolenbroek return dmalloc_find_entry (dp, array, middle, max);
446*83ee113eSDavid van Moolenbroek else
447*83ee113eSDavid van Moolenbroek return dmalloc_find_entry (dp, array, 0, middle);
448*83ee113eSDavid van Moolenbroek }
449*83ee113eSDavid van Moolenbroek
omapi_print_dmalloc_usage_by_caller()450*83ee113eSDavid van Moolenbroek void omapi_print_dmalloc_usage_by_caller ()
451*83ee113eSDavid van Moolenbroek {
452*83ee113eSDavid van Moolenbroek struct dmalloc_preamble *dp;
453*83ee113eSDavid van Moolenbroek int ccur, cmax, i;
454*83ee113eSDavid van Moolenbroek struct caller cp [1024];
455*83ee113eSDavid van Moolenbroek
456*83ee113eSDavid van Moolenbroek cmax = 1024;
457*83ee113eSDavid van Moolenbroek ccur = 0;
458*83ee113eSDavid van Moolenbroek
459*83ee113eSDavid van Moolenbroek memset (cp, 0, sizeof cp);
460*83ee113eSDavid van Moolenbroek for (dp = dmalloc_list; dp; dp = dp -> prev) {
461*83ee113eSDavid van Moolenbroek i = dmalloc_find_entry (dp, cp, 0, ccur);
462*83ee113eSDavid van Moolenbroek if ((i == ccur ||
463*83ee113eSDavid van Moolenbroek cp [i].dp -> file != dp -> file ||
464*83ee113eSDavid van Moolenbroek cp [i].dp -> line != dp -> line) &&
465*83ee113eSDavid van Moolenbroek ccur == cmax) {
466*83ee113eSDavid van Moolenbroek log_error ("no space for memory usage summary.");
467*83ee113eSDavid van Moolenbroek return;
468*83ee113eSDavid van Moolenbroek }
469*83ee113eSDavid van Moolenbroek if (i == ccur) {
470*83ee113eSDavid van Moolenbroek cp [ccur++].dp = dp;
471*83ee113eSDavid van Moolenbroek cp [i].count = 1;
472*83ee113eSDavid van Moolenbroek } else if (cp [i].dp -> file < dp -> file ||
473*83ee113eSDavid van Moolenbroek (cp [i].dp -> file == dp -> file &&
474*83ee113eSDavid van Moolenbroek cp [i].dp -> line < dp -> line)) {
475*83ee113eSDavid van Moolenbroek if (i + 1 != ccur)
476*83ee113eSDavid van Moolenbroek memmove (cp + i + 2, cp + i + 1,
477*83ee113eSDavid van Moolenbroek (ccur - i) * sizeof *cp);
478*83ee113eSDavid van Moolenbroek cp [i + 1].dp = dp;
479*83ee113eSDavid van Moolenbroek cp [i + 1].count = 1;
480*83ee113eSDavid van Moolenbroek ccur++;
481*83ee113eSDavid van Moolenbroek } else if (cp [i].dp -> file != dp -> file ||
482*83ee113eSDavid van Moolenbroek cp [i].dp -> line != dp -> line) {
483*83ee113eSDavid van Moolenbroek memmove (cp + i + 1,
484*83ee113eSDavid van Moolenbroek cp + i, (ccur - i) * sizeof *cp);
485*83ee113eSDavid van Moolenbroek cp [i].dp = dp;
486*83ee113eSDavid van Moolenbroek cp [i].count = 1;
487*83ee113eSDavid van Moolenbroek ccur++;
488*83ee113eSDavid van Moolenbroek } else
489*83ee113eSDavid van Moolenbroek cp [i].count++;
490*83ee113eSDavid van Moolenbroek #if 0
491*83ee113eSDavid van Moolenbroek printf ("%d\t%s:%d\n", i, dp -> file, dp -> line);
492*83ee113eSDavid van Moolenbroek dump_rc_history (dp + 1);
493*83ee113eSDavid van Moolenbroek #endif
494*83ee113eSDavid van Moolenbroek }
495*83ee113eSDavid van Moolenbroek for (i = 0; i < ccur; i++) {
496*83ee113eSDavid van Moolenbroek printf ("%d\t%s:%d\t%d\n", i,
497*83ee113eSDavid van Moolenbroek cp [i].dp -> file, cp [i].dp -> line, cp [i].count);
498*83ee113eSDavid van Moolenbroek #if defined(DUMP_RC_HISTORY)
499*83ee113eSDavid van Moolenbroek dump_rc_history (cp [i].dp + 1);
500*83ee113eSDavid van Moolenbroek #endif
501*83ee113eSDavid van Moolenbroek }
502*83ee113eSDavid van Moolenbroek }
503*83ee113eSDavid van Moolenbroek #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
504*83ee113eSDavid van Moolenbroek
omapi_object_allocate(omapi_object_t ** o,omapi_object_type_t * type,size_t size,const char * file,int line)505*83ee113eSDavid van Moolenbroek isc_result_t omapi_object_allocate (omapi_object_t **o,
506*83ee113eSDavid van Moolenbroek omapi_object_type_t *type,
507*83ee113eSDavid van Moolenbroek size_t size,
508*83ee113eSDavid van Moolenbroek const char *file, int line)
509*83ee113eSDavid van Moolenbroek {
510*83ee113eSDavid van Moolenbroek size_t tsize;
511*83ee113eSDavid van Moolenbroek omapi_object_t *foo;
512*83ee113eSDavid van Moolenbroek isc_result_t status;
513*83ee113eSDavid van Moolenbroek
514*83ee113eSDavid van Moolenbroek if (type -> allocator) {
515*83ee113eSDavid van Moolenbroek foo = (omapi_object_t *)0;
516*83ee113eSDavid van Moolenbroek status = (*type -> allocator) (&foo, file, line);
517*83ee113eSDavid van Moolenbroek tsize = type -> size;
518*83ee113eSDavid van Moolenbroek } else {
519*83ee113eSDavid van Moolenbroek status = ISC_R_NOMEMORY;
520*83ee113eSDavid van Moolenbroek tsize = 0;
521*83ee113eSDavid van Moolenbroek }
522*83ee113eSDavid van Moolenbroek
523*83ee113eSDavid van Moolenbroek if (status == ISC_R_NOMEMORY) {
524*83ee113eSDavid van Moolenbroek if (type -> sizer)
525*83ee113eSDavid van Moolenbroek tsize = (*type -> sizer) (size);
526*83ee113eSDavid van Moolenbroek else
527*83ee113eSDavid van Moolenbroek tsize = type -> size;
528*83ee113eSDavid van Moolenbroek
529*83ee113eSDavid van Moolenbroek /* Sanity check. */
530*83ee113eSDavid van Moolenbroek if (tsize < sizeof (omapi_object_t))
531*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
532*83ee113eSDavid van Moolenbroek
533*83ee113eSDavid van Moolenbroek foo = dmalloc (tsize, file, line);
534*83ee113eSDavid van Moolenbroek if (!foo)
535*83ee113eSDavid van Moolenbroek return ISC_R_NOMEMORY;
536*83ee113eSDavid van Moolenbroek }
537*83ee113eSDavid van Moolenbroek
538*83ee113eSDavid van Moolenbroek status = omapi_object_initialize (foo, type, size, tsize, file, line);
539*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS) {
540*83ee113eSDavid van Moolenbroek if (type -> freer)
541*83ee113eSDavid van Moolenbroek (*type -> freer) (foo, file, line);
542*83ee113eSDavid van Moolenbroek else
543*83ee113eSDavid van Moolenbroek dfree (foo, file, line);
544*83ee113eSDavid van Moolenbroek return status;
545*83ee113eSDavid van Moolenbroek }
546*83ee113eSDavid van Moolenbroek return omapi_object_reference (o, foo, file, line);
547*83ee113eSDavid van Moolenbroek }
548*83ee113eSDavid van Moolenbroek
omapi_object_initialize(omapi_object_t * o,omapi_object_type_t * type,size_t usize,size_t psize,const char * file,int line)549*83ee113eSDavid van Moolenbroek isc_result_t omapi_object_initialize (omapi_object_t *o,
550*83ee113eSDavid van Moolenbroek omapi_object_type_t *type,
551*83ee113eSDavid van Moolenbroek size_t usize, size_t psize,
552*83ee113eSDavid van Moolenbroek const char *file, int line)
553*83ee113eSDavid van Moolenbroek {
554*83ee113eSDavid van Moolenbroek memset (o, 0, psize);
555*83ee113eSDavid van Moolenbroek o -> type = type;
556*83ee113eSDavid van Moolenbroek if (type -> initialize)
557*83ee113eSDavid van Moolenbroek (*type -> initialize) (o, file, line);
558*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
559*83ee113eSDavid van Moolenbroek }
560*83ee113eSDavid van Moolenbroek
omapi_object_reference(omapi_object_t ** r,omapi_object_t * h,const char * file,int line)561*83ee113eSDavid van Moolenbroek isc_result_t omapi_object_reference (omapi_object_t **r,
562*83ee113eSDavid van Moolenbroek omapi_object_t *h,
563*83ee113eSDavid van Moolenbroek const char *file, int line)
564*83ee113eSDavid van Moolenbroek {
565*83ee113eSDavid van Moolenbroek if (!h || !r)
566*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
567*83ee113eSDavid van Moolenbroek
568*83ee113eSDavid van Moolenbroek if (*r) {
569*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
570*83ee113eSDavid van Moolenbroek log_error ("%s(%d): reference store into non-null pointer!",
571*83ee113eSDavid van Moolenbroek file, line);
572*83ee113eSDavid van Moolenbroek abort ();
573*83ee113eSDavid van Moolenbroek #else
574*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
575*83ee113eSDavid van Moolenbroek #endif
576*83ee113eSDavid van Moolenbroek }
577*83ee113eSDavid van Moolenbroek *r = h;
578*83ee113eSDavid van Moolenbroek h -> refcnt++;
579*83ee113eSDavid van Moolenbroek rc_register (file, line, r, h, h -> refcnt, 0, h -> type -> rc_flag);
580*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
581*83ee113eSDavid van Moolenbroek }
582*83ee113eSDavid van Moolenbroek
omapi_object_dereference(omapi_object_t ** h,const char * file,int line)583*83ee113eSDavid van Moolenbroek isc_result_t omapi_object_dereference (omapi_object_t **h,
584*83ee113eSDavid van Moolenbroek const char *file, int line)
585*83ee113eSDavid van Moolenbroek {
586*83ee113eSDavid van Moolenbroek int outer_reference = 0;
587*83ee113eSDavid van Moolenbroek int inner_reference = 0;
588*83ee113eSDavid van Moolenbroek int handle_reference = 0;
589*83ee113eSDavid van Moolenbroek int extra_references;
590*83ee113eSDavid van Moolenbroek omapi_object_t *p, *hp;
591*83ee113eSDavid van Moolenbroek
592*83ee113eSDavid van Moolenbroek if (!h)
593*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
594*83ee113eSDavid van Moolenbroek
595*83ee113eSDavid van Moolenbroek if (!*h) {
596*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
597*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of null pointer!", file, line);
598*83ee113eSDavid van Moolenbroek abort ();
599*83ee113eSDavid van Moolenbroek #else
600*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
601*83ee113eSDavid van Moolenbroek #endif
602*83ee113eSDavid van Moolenbroek }
603*83ee113eSDavid van Moolenbroek
604*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt <= 0) {
605*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
606*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of pointer with refcnt of zero!",
607*83ee113eSDavid van Moolenbroek file, line);
608*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
609*83ee113eSDavid van Moolenbroek dump_rc_history (*h);
610*83ee113eSDavid van Moolenbroek #endif
611*83ee113eSDavid van Moolenbroek abort ();
612*83ee113eSDavid van Moolenbroek #else
613*83ee113eSDavid van Moolenbroek *h = 0;
614*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
615*83ee113eSDavid van Moolenbroek #endif
616*83ee113eSDavid van Moolenbroek }
617*83ee113eSDavid van Moolenbroek
618*83ee113eSDavid van Moolenbroek /* See if this object's inner object refers to it, but don't
619*83ee113eSDavid van Moolenbroek count this as a reference if we're being asked to free the
620*83ee113eSDavid van Moolenbroek reference from the inner object. */
621*83ee113eSDavid van Moolenbroek if ((*h) -> inner && (*h) -> inner -> outer &&
622*83ee113eSDavid van Moolenbroek h != &((*h) -> inner -> outer))
623*83ee113eSDavid van Moolenbroek inner_reference = 1;
624*83ee113eSDavid van Moolenbroek
625*83ee113eSDavid van Moolenbroek /* Ditto for the outer object. */
626*83ee113eSDavid van Moolenbroek if ((*h) -> outer && (*h) -> outer -> inner &&
627*83ee113eSDavid van Moolenbroek h != &((*h) -> outer -> inner))
628*83ee113eSDavid van Moolenbroek outer_reference = 1;
629*83ee113eSDavid van Moolenbroek
630*83ee113eSDavid van Moolenbroek /* Ditto for the outer object. The code below assumes that
631*83ee113eSDavid van Moolenbroek the only reason we'd get a dereference from the handle
632*83ee113eSDavid van Moolenbroek table is if this function does it - otherwise we'd have to
633*83ee113eSDavid van Moolenbroek traverse the handle table to find the address where the
634*83ee113eSDavid van Moolenbroek reference is stored and compare against that, and we don't
635*83ee113eSDavid van Moolenbroek want to do that if we can avoid it. */
636*83ee113eSDavid van Moolenbroek if ((*h) -> handle)
637*83ee113eSDavid van Moolenbroek handle_reference = 1;
638*83ee113eSDavid van Moolenbroek
639*83ee113eSDavid van Moolenbroek /* If we are getting rid of the last reference other than
640*83ee113eSDavid van Moolenbroek references to inner and outer objects, or from the handle
641*83ee113eSDavid van Moolenbroek table, then we must examine all the objects in either
642*83ee113eSDavid van Moolenbroek direction to see if they hold any non-inner, non-outer,
643*83ee113eSDavid van Moolenbroek non-handle-table references. If not, we need to free the
644*83ee113eSDavid van Moolenbroek entire chain of objects. */
645*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt ==
646*83ee113eSDavid van Moolenbroek inner_reference + outer_reference + handle_reference + 1) {
647*83ee113eSDavid van Moolenbroek if (inner_reference || outer_reference || handle_reference) {
648*83ee113eSDavid van Moolenbroek /* XXX we could check for a reference from the
649*83ee113eSDavid van Moolenbroek handle table here. */
650*83ee113eSDavid van Moolenbroek extra_references = 0;
651*83ee113eSDavid van Moolenbroek for (p = (*h) -> inner;
652*83ee113eSDavid van Moolenbroek p && !extra_references; p = p -> inner) {
653*83ee113eSDavid van Moolenbroek extra_references += p -> refcnt;
654*83ee113eSDavid van Moolenbroek if (p -> inner && p -> inner -> outer == p)
655*83ee113eSDavid van Moolenbroek --extra_references;
656*83ee113eSDavid van Moolenbroek if (p -> outer)
657*83ee113eSDavid van Moolenbroek --extra_references;
658*83ee113eSDavid van Moolenbroek if (p -> handle)
659*83ee113eSDavid van Moolenbroek --extra_references;
660*83ee113eSDavid van Moolenbroek }
661*83ee113eSDavid van Moolenbroek for (p = (*h) -> outer;
662*83ee113eSDavid van Moolenbroek p && !extra_references; p = p -> outer) {
663*83ee113eSDavid van Moolenbroek extra_references += p -> refcnt;
664*83ee113eSDavid van Moolenbroek if (p -> outer && p -> outer -> inner == p)
665*83ee113eSDavid van Moolenbroek --extra_references;
666*83ee113eSDavid van Moolenbroek if (p -> inner)
667*83ee113eSDavid van Moolenbroek --extra_references;
668*83ee113eSDavid van Moolenbroek if (p -> handle)
669*83ee113eSDavid van Moolenbroek --extra_references;
670*83ee113eSDavid van Moolenbroek }
671*83ee113eSDavid van Moolenbroek } else
672*83ee113eSDavid van Moolenbroek extra_references = 0;
673*83ee113eSDavid van Moolenbroek
674*83ee113eSDavid van Moolenbroek if (!extra_references) {
675*83ee113eSDavid van Moolenbroek hp = *h;
676*83ee113eSDavid van Moolenbroek *h = 0;
677*83ee113eSDavid van Moolenbroek hp -> refcnt--;
678*83ee113eSDavid van Moolenbroek if (inner_reference)
679*83ee113eSDavid van Moolenbroek omapi_object_dereference
680*83ee113eSDavid van Moolenbroek (&hp -> inner, file, line);
681*83ee113eSDavid van Moolenbroek if (outer_reference)
682*83ee113eSDavid van Moolenbroek omapi_object_dereference
683*83ee113eSDavid van Moolenbroek (&hp -> outer, file, line);
684*83ee113eSDavid van Moolenbroek /* if (!hp -> type -> freer) */
685*83ee113eSDavid van Moolenbroek rc_register (file, line, h, hp,
686*83ee113eSDavid van Moolenbroek 0, 1, hp -> type -> rc_flag);
687*83ee113eSDavid van Moolenbroek if (handle_reference) {
688*83ee113eSDavid van Moolenbroek if (omapi_handle_clear(hp->handle) !=
689*83ee113eSDavid van Moolenbroek ISC_R_SUCCESS) {
690*83ee113eSDavid van Moolenbroek log_debug("Attempt to clear null "
691*83ee113eSDavid van Moolenbroek "handle pointer");
692*83ee113eSDavid van Moolenbroek }
693*83ee113eSDavid van Moolenbroek }
694*83ee113eSDavid van Moolenbroek if (hp -> type -> destroy)
695*83ee113eSDavid van Moolenbroek (*(hp -> type -> destroy)) (hp, file, line);
696*83ee113eSDavid van Moolenbroek if (hp -> type -> freer)
697*83ee113eSDavid van Moolenbroek (hp -> type -> freer (hp, file, line));
698*83ee113eSDavid van Moolenbroek else
699*83ee113eSDavid van Moolenbroek dfree (hp, file, line);
700*83ee113eSDavid van Moolenbroek } else {
701*83ee113eSDavid van Moolenbroek (*h) -> refcnt--;
702*83ee113eSDavid van Moolenbroek /* if (!(*h) -> type -> freer) */
703*83ee113eSDavid van Moolenbroek rc_register (file, line,
704*83ee113eSDavid van Moolenbroek h, *h, (*h) -> refcnt, 1,
705*83ee113eSDavid van Moolenbroek (*h) -> type -> rc_flag);
706*83ee113eSDavid van Moolenbroek }
707*83ee113eSDavid van Moolenbroek } else {
708*83ee113eSDavid van Moolenbroek (*h) -> refcnt--;
709*83ee113eSDavid van Moolenbroek /* if (!(*h) -> type -> freer) */
710*83ee113eSDavid van Moolenbroek rc_register (file, line, h, *h, (*h) -> refcnt, 1,
711*83ee113eSDavid van Moolenbroek (*h) -> type -> rc_flag);
712*83ee113eSDavid van Moolenbroek }
713*83ee113eSDavid van Moolenbroek *h = 0;
714*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
715*83ee113eSDavid van Moolenbroek }
716*83ee113eSDavid van Moolenbroek
omapi_buffer_new(omapi_buffer_t ** h,const char * file,int line)717*83ee113eSDavid van Moolenbroek isc_result_t omapi_buffer_new (omapi_buffer_t **h,
718*83ee113eSDavid van Moolenbroek const char *file, int line)
719*83ee113eSDavid van Moolenbroek {
720*83ee113eSDavid van Moolenbroek omapi_buffer_t *t;
721*83ee113eSDavid van Moolenbroek isc_result_t status;
722*83ee113eSDavid van Moolenbroek
723*83ee113eSDavid van Moolenbroek t = (omapi_buffer_t *)dmalloc (sizeof *t, file, line);
724*83ee113eSDavid van Moolenbroek if (!t)
725*83ee113eSDavid van Moolenbroek return ISC_R_NOMEMORY;
726*83ee113eSDavid van Moolenbroek memset (t, 0, sizeof *t);
727*83ee113eSDavid van Moolenbroek status = omapi_buffer_reference (h, t, file, line);
728*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
729*83ee113eSDavid van Moolenbroek dfree (t, file, line);
730*83ee113eSDavid van Moolenbroek (*h) -> head = sizeof ((*h) -> buf) - 1;
731*83ee113eSDavid van Moolenbroek return status;
732*83ee113eSDavid van Moolenbroek }
733*83ee113eSDavid van Moolenbroek
omapi_buffer_reference(omapi_buffer_t ** r,omapi_buffer_t * h,const char * file,int line)734*83ee113eSDavid van Moolenbroek isc_result_t omapi_buffer_reference (omapi_buffer_t **r,
735*83ee113eSDavid van Moolenbroek omapi_buffer_t *h,
736*83ee113eSDavid van Moolenbroek const char *file, int line)
737*83ee113eSDavid van Moolenbroek {
738*83ee113eSDavid van Moolenbroek if (!h || !r)
739*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
740*83ee113eSDavid van Moolenbroek
741*83ee113eSDavid van Moolenbroek if (*r) {
742*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
743*83ee113eSDavid van Moolenbroek log_error ("%s(%d): reference store into non-null pointer!",
744*83ee113eSDavid van Moolenbroek file, line);
745*83ee113eSDavid van Moolenbroek abort ();
746*83ee113eSDavid van Moolenbroek #else
747*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
748*83ee113eSDavid van Moolenbroek #endif
749*83ee113eSDavid van Moolenbroek }
750*83ee113eSDavid van Moolenbroek *r = h;
751*83ee113eSDavid van Moolenbroek h -> refcnt++;
752*83ee113eSDavid van Moolenbroek rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
753*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
754*83ee113eSDavid van Moolenbroek }
755*83ee113eSDavid van Moolenbroek
omapi_buffer_dereference(omapi_buffer_t ** h,const char * file,int line)756*83ee113eSDavid van Moolenbroek isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
757*83ee113eSDavid van Moolenbroek const char *file, int line)
758*83ee113eSDavid van Moolenbroek {
759*83ee113eSDavid van Moolenbroek if (!h)
760*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
761*83ee113eSDavid van Moolenbroek
762*83ee113eSDavid van Moolenbroek if (!*h) {
763*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
764*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of null pointer!", file, line);
765*83ee113eSDavid van Moolenbroek abort ();
766*83ee113eSDavid van Moolenbroek #else
767*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
768*83ee113eSDavid van Moolenbroek #endif
769*83ee113eSDavid van Moolenbroek }
770*83ee113eSDavid van Moolenbroek
771*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt <= 0) {
772*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
773*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of pointer with refcnt of zero!",
774*83ee113eSDavid van Moolenbroek file, line);
775*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
776*83ee113eSDavid van Moolenbroek dump_rc_history (*h);
777*83ee113eSDavid van Moolenbroek #endif
778*83ee113eSDavid van Moolenbroek abort ();
779*83ee113eSDavid van Moolenbroek #else
780*83ee113eSDavid van Moolenbroek *h = 0;
781*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
782*83ee113eSDavid van Moolenbroek #endif
783*83ee113eSDavid van Moolenbroek }
784*83ee113eSDavid van Moolenbroek
785*83ee113eSDavid van Moolenbroek --(*h) -> refcnt;
786*83ee113eSDavid van Moolenbroek rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
787*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt == 0)
788*83ee113eSDavid van Moolenbroek dfree (*h, file, line);
789*83ee113eSDavid van Moolenbroek *h = 0;
790*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
791*83ee113eSDavid van Moolenbroek }
792*83ee113eSDavid van Moolenbroek
omapi_typed_data_new(const char * file,int line,omapi_typed_data_t ** t,omapi_datatype_t type,...)793*83ee113eSDavid van Moolenbroek isc_result_t omapi_typed_data_new (const char *file, int line,
794*83ee113eSDavid van Moolenbroek omapi_typed_data_t **t,
795*83ee113eSDavid van Moolenbroek omapi_datatype_t type, ...)
796*83ee113eSDavid van Moolenbroek {
797*83ee113eSDavid van Moolenbroek va_list l;
798*83ee113eSDavid van Moolenbroek omapi_typed_data_t *new;
799*83ee113eSDavid van Moolenbroek unsigned len;
800*83ee113eSDavid van Moolenbroek unsigned val = 0;
801*83ee113eSDavid van Moolenbroek int intval = 0;
802*83ee113eSDavid van Moolenbroek char *s = NULL;
803*83ee113eSDavid van Moolenbroek isc_result_t status;
804*83ee113eSDavid van Moolenbroek omapi_object_t *obj = NULL;
805*83ee113eSDavid van Moolenbroek
806*83ee113eSDavid van Moolenbroek va_start (l, type);
807*83ee113eSDavid van Moolenbroek
808*83ee113eSDavid van Moolenbroek switch (type) {
809*83ee113eSDavid van Moolenbroek case omapi_datatype_int:
810*83ee113eSDavid van Moolenbroek len = OMAPI_TYPED_DATA_INT_LEN;
811*83ee113eSDavid van Moolenbroek intval = va_arg (l, int);
812*83ee113eSDavid van Moolenbroek break;
813*83ee113eSDavid van Moolenbroek case omapi_datatype_string:
814*83ee113eSDavid van Moolenbroek s = va_arg (l, char *);
815*83ee113eSDavid van Moolenbroek val = strlen (s);
816*83ee113eSDavid van Moolenbroek len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
817*83ee113eSDavid van Moolenbroek if (len < val) {
818*83ee113eSDavid van Moolenbroek va_end(l);
819*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
820*83ee113eSDavid van Moolenbroek }
821*83ee113eSDavid van Moolenbroek break;
822*83ee113eSDavid van Moolenbroek case omapi_datatype_data:
823*83ee113eSDavid van Moolenbroek val = va_arg (l, unsigned);
824*83ee113eSDavid van Moolenbroek len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
825*83ee113eSDavid van Moolenbroek if (len < val) {
826*83ee113eSDavid van Moolenbroek va_end(l);
827*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
828*83ee113eSDavid van Moolenbroek }
829*83ee113eSDavid van Moolenbroek break;
830*83ee113eSDavid van Moolenbroek case omapi_datatype_object:
831*83ee113eSDavid van Moolenbroek len = OMAPI_TYPED_DATA_OBJECT_LEN;
832*83ee113eSDavid van Moolenbroek obj = va_arg (l, omapi_object_t *);
833*83ee113eSDavid van Moolenbroek break;
834*83ee113eSDavid van Moolenbroek default:
835*83ee113eSDavid van Moolenbroek va_end (l);
836*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
837*83ee113eSDavid van Moolenbroek }
838*83ee113eSDavid van Moolenbroek va_end (l);
839*83ee113eSDavid van Moolenbroek
840*83ee113eSDavid van Moolenbroek new = dmalloc (len, file, line);
841*83ee113eSDavid van Moolenbroek if (!new)
842*83ee113eSDavid van Moolenbroek return ISC_R_NOMEMORY;
843*83ee113eSDavid van Moolenbroek memset (new, 0, len);
844*83ee113eSDavid van Moolenbroek
845*83ee113eSDavid van Moolenbroek switch (type) {
846*83ee113eSDavid van Moolenbroek case omapi_datatype_int:
847*83ee113eSDavid van Moolenbroek new -> u.integer = intval;
848*83ee113eSDavid van Moolenbroek break;
849*83ee113eSDavid van Moolenbroek case omapi_datatype_string:
850*83ee113eSDavid van Moolenbroek memcpy (new -> u.buffer.value, s, val);
851*83ee113eSDavid van Moolenbroek new -> u.buffer.len = val;
852*83ee113eSDavid van Moolenbroek break;
853*83ee113eSDavid van Moolenbroek case omapi_datatype_data:
854*83ee113eSDavid van Moolenbroek new -> u.buffer.len = val;
855*83ee113eSDavid van Moolenbroek break;
856*83ee113eSDavid van Moolenbroek case omapi_datatype_object:
857*83ee113eSDavid van Moolenbroek status = omapi_object_reference (&new -> u.object, obj,
858*83ee113eSDavid van Moolenbroek file, line);
859*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS) {
860*83ee113eSDavid van Moolenbroek dfree (new, file, line);
861*83ee113eSDavid van Moolenbroek return status;
862*83ee113eSDavid van Moolenbroek }
863*83ee113eSDavid van Moolenbroek break;
864*83ee113eSDavid van Moolenbroek }
865*83ee113eSDavid van Moolenbroek new -> type = type;
866*83ee113eSDavid van Moolenbroek
867*83ee113eSDavid van Moolenbroek return omapi_typed_data_reference (t, new, file, line);
868*83ee113eSDavid van Moolenbroek }
869*83ee113eSDavid van Moolenbroek
omapi_typed_data_reference(omapi_typed_data_t ** r,omapi_typed_data_t * h,const char * file,int line)870*83ee113eSDavid van Moolenbroek isc_result_t omapi_typed_data_reference (omapi_typed_data_t **r,
871*83ee113eSDavid van Moolenbroek omapi_typed_data_t *h,
872*83ee113eSDavid van Moolenbroek const char *file, int line)
873*83ee113eSDavid van Moolenbroek {
874*83ee113eSDavid van Moolenbroek if (!h || !r)
875*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
876*83ee113eSDavid van Moolenbroek
877*83ee113eSDavid van Moolenbroek if (*r) {
878*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
879*83ee113eSDavid van Moolenbroek log_error ("%s(%d): reference store into non-null pointer!", file, line);
880*83ee113eSDavid van Moolenbroek abort ();
881*83ee113eSDavid van Moolenbroek #else
882*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
883*83ee113eSDavid van Moolenbroek #endif
884*83ee113eSDavid van Moolenbroek }
885*83ee113eSDavid van Moolenbroek *r = h;
886*83ee113eSDavid van Moolenbroek h -> refcnt++;
887*83ee113eSDavid van Moolenbroek rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
888*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
889*83ee113eSDavid van Moolenbroek }
890*83ee113eSDavid van Moolenbroek
omapi_typed_data_dereference(omapi_typed_data_t ** h,const char * file,int line)891*83ee113eSDavid van Moolenbroek isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
892*83ee113eSDavid van Moolenbroek const char *file, int line)
893*83ee113eSDavid van Moolenbroek {
894*83ee113eSDavid van Moolenbroek if (!h)
895*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
896*83ee113eSDavid van Moolenbroek
897*83ee113eSDavid van Moolenbroek if (!*h) {
898*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
899*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of null pointer!", file, line);
900*83ee113eSDavid van Moolenbroek abort ();
901*83ee113eSDavid van Moolenbroek #else
902*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
903*83ee113eSDavid van Moolenbroek #endif
904*83ee113eSDavid van Moolenbroek }
905*83ee113eSDavid van Moolenbroek
906*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt <= 0) {
907*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
908*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of pointer with refcnt of zero!",
909*83ee113eSDavid van Moolenbroek file, line);
910*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
911*83ee113eSDavid van Moolenbroek dump_rc_history (*h);
912*83ee113eSDavid van Moolenbroek #endif
913*83ee113eSDavid van Moolenbroek abort ();
914*83ee113eSDavid van Moolenbroek #else
915*83ee113eSDavid van Moolenbroek *h = 0;
916*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
917*83ee113eSDavid van Moolenbroek #endif
918*83ee113eSDavid van Moolenbroek }
919*83ee113eSDavid van Moolenbroek
920*83ee113eSDavid van Moolenbroek --((*h) -> refcnt);
921*83ee113eSDavid van Moolenbroek rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
922*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt <= 0 ) {
923*83ee113eSDavid van Moolenbroek switch ((*h) -> type) {
924*83ee113eSDavid van Moolenbroek case omapi_datatype_int:
925*83ee113eSDavid van Moolenbroek case omapi_datatype_string:
926*83ee113eSDavid van Moolenbroek case omapi_datatype_data:
927*83ee113eSDavid van Moolenbroek default:
928*83ee113eSDavid van Moolenbroek break;
929*83ee113eSDavid van Moolenbroek case omapi_datatype_object:
930*83ee113eSDavid van Moolenbroek omapi_object_dereference (&(*h) -> u.object,
931*83ee113eSDavid van Moolenbroek file, line);
932*83ee113eSDavid van Moolenbroek break;
933*83ee113eSDavid van Moolenbroek }
934*83ee113eSDavid van Moolenbroek dfree (*h, file, line);
935*83ee113eSDavid van Moolenbroek }
936*83ee113eSDavid van Moolenbroek *h = 0;
937*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
938*83ee113eSDavid van Moolenbroek }
939*83ee113eSDavid van Moolenbroek
omapi_data_string_new(omapi_data_string_t ** d,unsigned len,const char * file,int line)940*83ee113eSDavid van Moolenbroek isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len,
941*83ee113eSDavid van Moolenbroek const char *file, int line)
942*83ee113eSDavid van Moolenbroek {
943*83ee113eSDavid van Moolenbroek omapi_data_string_t *new;
944*83ee113eSDavid van Moolenbroek unsigned nlen;
945*83ee113eSDavid van Moolenbroek
946*83ee113eSDavid van Moolenbroek nlen = OMAPI_DATA_STRING_EMPTY_SIZE + len;
947*83ee113eSDavid van Moolenbroek if (nlen < len)
948*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
949*83ee113eSDavid van Moolenbroek new = dmalloc (nlen, file, line);
950*83ee113eSDavid van Moolenbroek if (!new)
951*83ee113eSDavid van Moolenbroek return ISC_R_NOMEMORY;
952*83ee113eSDavid van Moolenbroek memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
953*83ee113eSDavid van Moolenbroek new -> len = len;
954*83ee113eSDavid van Moolenbroek return omapi_data_string_reference (d, new, file, line);
955*83ee113eSDavid van Moolenbroek }
956*83ee113eSDavid van Moolenbroek
omapi_data_string_reference(omapi_data_string_t ** r,omapi_data_string_t * h,const char * file,int line)957*83ee113eSDavid van Moolenbroek isc_result_t omapi_data_string_reference (omapi_data_string_t **r,
958*83ee113eSDavid van Moolenbroek omapi_data_string_t *h,
959*83ee113eSDavid van Moolenbroek const char *file, int line)
960*83ee113eSDavid van Moolenbroek {
961*83ee113eSDavid van Moolenbroek if (!h || !r)
962*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
963*83ee113eSDavid van Moolenbroek
964*83ee113eSDavid van Moolenbroek if (*r) {
965*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
966*83ee113eSDavid van Moolenbroek log_error ("%s(%d): reference store into non-null pointer!", file, line);
967*83ee113eSDavid van Moolenbroek abort ();
968*83ee113eSDavid van Moolenbroek #else
969*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
970*83ee113eSDavid van Moolenbroek #endif
971*83ee113eSDavid van Moolenbroek }
972*83ee113eSDavid van Moolenbroek *r = h;
973*83ee113eSDavid van Moolenbroek h -> refcnt++;
974*83ee113eSDavid van Moolenbroek rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
975*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
976*83ee113eSDavid van Moolenbroek }
977*83ee113eSDavid van Moolenbroek
omapi_data_string_dereference(omapi_data_string_t ** h,const char * file,int line)978*83ee113eSDavid van Moolenbroek isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
979*83ee113eSDavid van Moolenbroek const char *file, int line)
980*83ee113eSDavid van Moolenbroek {
981*83ee113eSDavid van Moolenbroek if (!h)
982*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
983*83ee113eSDavid van Moolenbroek
984*83ee113eSDavid van Moolenbroek if (!*h) {
985*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
986*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of null pointer!", file, line);
987*83ee113eSDavid van Moolenbroek abort ();
988*83ee113eSDavid van Moolenbroek #else
989*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
990*83ee113eSDavid van Moolenbroek #endif
991*83ee113eSDavid van Moolenbroek }
992*83ee113eSDavid van Moolenbroek
993*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt <= 0) {
994*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
995*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of pointer with refcnt of zero!",
996*83ee113eSDavid van Moolenbroek file, line);
997*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
998*83ee113eSDavid van Moolenbroek dump_rc_history (*h);
999*83ee113eSDavid van Moolenbroek #endif
1000*83ee113eSDavid van Moolenbroek abort ();
1001*83ee113eSDavid van Moolenbroek #else
1002*83ee113eSDavid van Moolenbroek *h = 0;
1003*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1004*83ee113eSDavid van Moolenbroek #endif
1005*83ee113eSDavid van Moolenbroek }
1006*83ee113eSDavid van Moolenbroek
1007*83ee113eSDavid van Moolenbroek --((*h) -> refcnt);
1008*83ee113eSDavid van Moolenbroek rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1009*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt <= 0 ) {
1010*83ee113eSDavid van Moolenbroek dfree (*h, file, line);
1011*83ee113eSDavid van Moolenbroek }
1012*83ee113eSDavid van Moolenbroek *h = 0;
1013*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
1014*83ee113eSDavid van Moolenbroek }
1015*83ee113eSDavid van Moolenbroek
omapi_value_new(omapi_value_t ** d,const char * file,int line)1016*83ee113eSDavid van Moolenbroek isc_result_t omapi_value_new (omapi_value_t **d,
1017*83ee113eSDavid van Moolenbroek const char *file, int line)
1018*83ee113eSDavid van Moolenbroek {
1019*83ee113eSDavid van Moolenbroek omapi_value_t *new;
1020*83ee113eSDavid van Moolenbroek
1021*83ee113eSDavid van Moolenbroek new = dmalloc (sizeof *new, file, line);
1022*83ee113eSDavid van Moolenbroek if (!new)
1023*83ee113eSDavid van Moolenbroek return ISC_R_NOMEMORY;
1024*83ee113eSDavid van Moolenbroek memset (new, 0, sizeof *new);
1025*83ee113eSDavid van Moolenbroek return omapi_value_reference (d, new, file, line);
1026*83ee113eSDavid van Moolenbroek }
1027*83ee113eSDavid van Moolenbroek
omapi_value_reference(omapi_value_t ** r,omapi_value_t * h,const char * file,int line)1028*83ee113eSDavid van Moolenbroek isc_result_t omapi_value_reference (omapi_value_t **r,
1029*83ee113eSDavid van Moolenbroek omapi_value_t *h,
1030*83ee113eSDavid van Moolenbroek const char *file, int line)
1031*83ee113eSDavid van Moolenbroek {
1032*83ee113eSDavid van Moolenbroek if (!h || !r)
1033*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1034*83ee113eSDavid van Moolenbroek
1035*83ee113eSDavid van Moolenbroek if (*r) {
1036*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
1037*83ee113eSDavid van Moolenbroek log_error ("%s(%d): reference store into non-null pointer!",
1038*83ee113eSDavid van Moolenbroek file, line);
1039*83ee113eSDavid van Moolenbroek abort ();
1040*83ee113eSDavid van Moolenbroek #else
1041*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1042*83ee113eSDavid van Moolenbroek #endif
1043*83ee113eSDavid van Moolenbroek }
1044*83ee113eSDavid van Moolenbroek *r = h;
1045*83ee113eSDavid van Moolenbroek h -> refcnt++;
1046*83ee113eSDavid van Moolenbroek rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1047*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
1048*83ee113eSDavid van Moolenbroek }
1049*83ee113eSDavid van Moolenbroek
omapi_value_dereference(omapi_value_t ** h,const char * file,int line)1050*83ee113eSDavid van Moolenbroek isc_result_t omapi_value_dereference (omapi_value_t **h,
1051*83ee113eSDavid van Moolenbroek const char *file, int line)
1052*83ee113eSDavid van Moolenbroek {
1053*83ee113eSDavid van Moolenbroek if (!h)
1054*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1055*83ee113eSDavid van Moolenbroek
1056*83ee113eSDavid van Moolenbroek if (!*h) {
1057*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
1058*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of null pointer!", file, line);
1059*83ee113eSDavid van Moolenbroek abort ();
1060*83ee113eSDavid van Moolenbroek #else
1061*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1062*83ee113eSDavid van Moolenbroek #endif
1063*83ee113eSDavid van Moolenbroek }
1064*83ee113eSDavid van Moolenbroek
1065*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt <= 0) {
1066*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
1067*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1068*83ee113eSDavid van Moolenbroek file, line);
1069*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
1070*83ee113eSDavid van Moolenbroek dump_rc_history (*h);
1071*83ee113eSDavid van Moolenbroek #endif
1072*83ee113eSDavid van Moolenbroek abort ();
1073*83ee113eSDavid van Moolenbroek #else
1074*83ee113eSDavid van Moolenbroek *h = 0;
1075*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1076*83ee113eSDavid van Moolenbroek #endif
1077*83ee113eSDavid van Moolenbroek }
1078*83ee113eSDavid van Moolenbroek
1079*83ee113eSDavid van Moolenbroek --((*h) -> refcnt);
1080*83ee113eSDavid van Moolenbroek rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1081*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt == 0) {
1082*83ee113eSDavid van Moolenbroek if ((*h) -> name)
1083*83ee113eSDavid van Moolenbroek omapi_data_string_dereference (&(*h) -> name,
1084*83ee113eSDavid van Moolenbroek file, line);
1085*83ee113eSDavid van Moolenbroek if ((*h) -> value)
1086*83ee113eSDavid van Moolenbroek omapi_typed_data_dereference (&(*h) -> value,
1087*83ee113eSDavid van Moolenbroek file, line);
1088*83ee113eSDavid van Moolenbroek dfree (*h, file, line);
1089*83ee113eSDavid van Moolenbroek }
1090*83ee113eSDavid van Moolenbroek *h = 0;
1091*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
1092*83ee113eSDavid van Moolenbroek }
1093*83ee113eSDavid van Moolenbroek
omapi_addr_list_new(omapi_addr_list_t ** d,unsigned count,const char * file,int line)1094*83ee113eSDavid van Moolenbroek isc_result_t omapi_addr_list_new (omapi_addr_list_t **d, unsigned count,
1095*83ee113eSDavid van Moolenbroek const char *file, int line)
1096*83ee113eSDavid van Moolenbroek {
1097*83ee113eSDavid van Moolenbroek omapi_addr_list_t *new;
1098*83ee113eSDavid van Moolenbroek
1099*83ee113eSDavid van Moolenbroek new = dmalloc ((count * sizeof (omapi_addr_t)) +
1100*83ee113eSDavid van Moolenbroek sizeof (omapi_addr_list_t), file, line);
1101*83ee113eSDavid van Moolenbroek if (!new)
1102*83ee113eSDavid van Moolenbroek return ISC_R_NOMEMORY;
1103*83ee113eSDavid van Moolenbroek memset (new, 0, ((count * sizeof (omapi_addr_t)) +
1104*83ee113eSDavid van Moolenbroek sizeof (omapi_addr_list_t)));
1105*83ee113eSDavid van Moolenbroek new -> count = count;
1106*83ee113eSDavid van Moolenbroek new -> addresses = (omapi_addr_t *)(new + 1);
1107*83ee113eSDavid van Moolenbroek return omapi_addr_list_reference (d, new, file, line);
1108*83ee113eSDavid van Moolenbroek }
1109*83ee113eSDavid van Moolenbroek
omapi_addr_list_reference(omapi_addr_list_t ** r,omapi_addr_list_t * h,const char * file,int line)1110*83ee113eSDavid van Moolenbroek isc_result_t omapi_addr_list_reference (omapi_addr_list_t **r,
1111*83ee113eSDavid van Moolenbroek omapi_addr_list_t *h,
1112*83ee113eSDavid van Moolenbroek const char *file, int line)
1113*83ee113eSDavid van Moolenbroek {
1114*83ee113eSDavid van Moolenbroek if (!h || !r)
1115*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1116*83ee113eSDavid van Moolenbroek
1117*83ee113eSDavid van Moolenbroek if (*r) {
1118*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
1119*83ee113eSDavid van Moolenbroek log_error ("%s(%d): reference store into non-null pointer!",
1120*83ee113eSDavid van Moolenbroek file, line);
1121*83ee113eSDavid van Moolenbroek abort ();
1122*83ee113eSDavid van Moolenbroek #else
1123*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1124*83ee113eSDavid van Moolenbroek #endif
1125*83ee113eSDavid van Moolenbroek }
1126*83ee113eSDavid van Moolenbroek *r = h;
1127*83ee113eSDavid van Moolenbroek h -> refcnt++;
1128*83ee113eSDavid van Moolenbroek rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1129*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
1130*83ee113eSDavid van Moolenbroek }
1131*83ee113eSDavid van Moolenbroek
omapi_addr_list_dereference(omapi_addr_list_t ** h,const char * file,int line)1132*83ee113eSDavid van Moolenbroek isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h,
1133*83ee113eSDavid van Moolenbroek const char *file, int line)
1134*83ee113eSDavid van Moolenbroek {
1135*83ee113eSDavid van Moolenbroek if (!h)
1136*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1137*83ee113eSDavid van Moolenbroek
1138*83ee113eSDavid van Moolenbroek if (!*h) {
1139*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
1140*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of null pointer!", file, line);
1141*83ee113eSDavid van Moolenbroek abort ();
1142*83ee113eSDavid van Moolenbroek #else
1143*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1144*83ee113eSDavid van Moolenbroek #endif
1145*83ee113eSDavid van Moolenbroek }
1146*83ee113eSDavid van Moolenbroek
1147*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt <= 0) {
1148*83ee113eSDavid van Moolenbroek #if defined (POINTER_DEBUG)
1149*83ee113eSDavid van Moolenbroek log_error ("%s(%d): dereference of pointer with zero refcnt!",
1150*83ee113eSDavid van Moolenbroek file, line);
1151*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY)
1152*83ee113eSDavid van Moolenbroek dump_rc_history (*h);
1153*83ee113eSDavid van Moolenbroek #endif
1154*83ee113eSDavid van Moolenbroek abort ();
1155*83ee113eSDavid van Moolenbroek #else
1156*83ee113eSDavid van Moolenbroek *h = 0;
1157*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
1158*83ee113eSDavid van Moolenbroek #endif
1159*83ee113eSDavid van Moolenbroek }
1160*83ee113eSDavid van Moolenbroek
1161*83ee113eSDavid van Moolenbroek --((*h) -> refcnt);
1162*83ee113eSDavid van Moolenbroek rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1163*83ee113eSDavid van Moolenbroek if ((*h) -> refcnt <= 0 ) {
1164*83ee113eSDavid van Moolenbroek dfree (*h, file, line);
1165*83ee113eSDavid van Moolenbroek }
1166*83ee113eSDavid van Moolenbroek *h = 0;
1167*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
1168*83ee113eSDavid van Moolenbroek }
1169*83ee113eSDavid van Moolenbroek
1170