Annotation of embedaddon/dhcp/omapip/alloc.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>