Coverage report for src/hash.c.gcov

        -:    0:Source:hash.c
        -:    0:Graph:./libvirt_la-hash.gcno
        -:    0:Data:./libvirt_la-hash.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:/*
        -:    2: * hash.c: chained hash tables for domain and domain/connection deallocations
        -:    3: *
        -:    4: * Reference: Your favorite introductory book on algorithms
        -:    5: *
        -:    6: * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
        -:    7: *
        -:    8: * Permission to use, copy, modify, and distribute this software for any
        -:    9: * purpose with or without fee is hereby granted, provided that the above
        -:   10: * copyright notice and this permission notice appear in all copies.
        -:   11: *
        -:   12: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        -:   13: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        -:   14: * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
        -:   15: * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
        -:   16: *
        -:   17: * Author: breese@users.sourceforge.net
        -:   18: *         Daniel Veillard <veillard@redhat.com>
        -:   19: */
        -:   20:
        -:   21:#include <string.h>
        -:   22:#include <stdlib.h>
        -:   23:#include <libxml/threads.h>
        -:   24:#include "internal.h"
        -:   25:#include "hash.h"
        -:   26:
        -:   27:#define MAX_HASH_LEN 8
        -:   28:
        -:   29:/* #define DEBUG_GROW */
        -:   30:
        -:   31:/*
        -:   32: * A single entry in the hash table
        -:   33: */
        -:   34:typedef struct _virHashEntry virHashEntry;
        -:   35:typedef virHashEntry *virHashEntryPtr;
        -:   36:struct _virHashEntry {
        -:   37:    struct _virHashEntry *next;
        -:   38:    char *name;
        -:   39:    void *payload;
        -:   40:    int valid;
        -:   41:};
        -:   42:
        -:   43:/*
        -:   44: * The entire hash table
        -:   45: */
        -:   46:struct _virHashTable {
        -:   47:    struct _virHashEntry *table;
        -:   48:    int size;
        -:   49:    int nbElems;
        -:   50:};
        -:   51:
        -:   52:/*
        -:   53: * virHashComputeKey:
        -:   54: * Calculate the hash key
        -:   55: */
        -:   56:static unsigned long
        -:   57:virHashComputeKey(virHashTablePtr table, const char *name)
function virHashComputeKey called 0 returned 0% blocks executed 0%
    #####:   58:{
    #####:   59:    unsigned long value = 0L;
        -:   60:    char ch;
        -:   61:
    #####:   62:    if (name != NULL) {
branch  0 never executed
branch  1 never executed
    #####:   63:        value += 30 * (*name);
    #####:   64:        while ((ch = *name++) != 0) {
branch  0 never executed
branch  1 never executed
    #####:   65:            value =
        -:   66:                value ^ ((value << 5) + (value >> 3) + (unsigned long) ch);
        -:   67:        }
        -:   68:    }
    #####:   69:    return (value % table->size);
        -:   70:}
        -:   71:
        -:   72:/**
        -:   73: * virHashCreate:
        -:   74: * @size: the size of the hash table
        -:   75: *
        -:   76: * Create a new virHashTablePtr.
        -:   77: *
        -:   78: * Returns the newly created object, or NULL if an error occured.
        -:   79: */
        -:   80:virHashTablePtr
        -:   81:virHashCreate(int size)
function virHashCreate called 0 returned 0% blocks executed 0%
    #####:   82:{
        -:   83:    virHashTablePtr table;
        -:   84:
    #####:   85:    if (size <= 0)
branch  0 never executed
branch  1 never executed
    #####:   86:        size = 256;
        -:   87:
    #####:   88:    table = malloc(sizeof(virHashTable));
call    0 never executed
    #####:   89:    if (table) {
branch  0 never executed
branch  1 never executed
    #####:   90:        table->size = size;
    #####:   91:        table->nbElems = 0;
    #####:   92:        table->table = malloc(size * sizeof(virHashEntry));
call    0 never executed
    #####:   93:        if (table->table) {
branch  0 never executed
branch  1 never executed
    #####:   94:            memset(table->table, 0, size * sizeof(virHashEntry));
call    0 never executed
    #####:   95:            return (table);
        -:   96:        }
    #####:   97:        free(table);
call    0 never executed
        -:   98:    }
    #####:   99:    return (NULL);
        -:  100:}
        -:  101:
        -:  102:/**
        -:  103: * virHashGrow:
        -:  104: * @table: the hash table
        -:  105: * @size: the new size of the hash table
        -:  106: *
        -:  107: * resize the hash table
        -:  108: *
        -:  109: * Returns 0 in case of success, -1 in case of failure
        -:  110: */
        -:  111:static int
        -:  112:virHashGrow(virHashTablePtr table, int size)
function virHashGrow called 0 returned 0% blocks executed 0%
    #####:  113:{
        -:  114:    unsigned long key;
        -:  115:    int oldsize, i;
        -:  116:    virHashEntryPtr iter, next;
        -:  117:    struct _virHashEntry *oldtable;
        -:  118:
        -:  119:#ifdef DEBUG_GROW
        -:  120:    unsigned long nbElem = 0;
        -:  121:#endif
        -:  122:
    #####:  123:    if (table == NULL)
branch  0 never executed
branch  1 never executed
    #####:  124:        return (-1);
    #####:  125:    if (size < 8)
branch  0 never executed
branch  1 never executed
    #####:  126:        return (-1);
    #####:  127:    if (size > 8 * 2048)
branch  0 never executed
branch  1 never executed
    #####:  128:        return (-1);
        -:  129:
    #####:  130:    oldsize = table->size;
    #####:  131:    oldtable = table->table;
    #####:  132:    if (oldtable == NULL)
branch  0 never executed
branch  1 never executed
    #####:  133:        return (-1);
        -:  134:
    #####:  135:    table->table = malloc(size * sizeof(virHashEntry));
call    0 never executed
    #####:  136:    if (table->table == NULL) {
branch  0 never executed
branch  1 never executed
    #####:  137:        table->table = oldtable;
    #####:  138:        return (-1);
        -:  139:    }
    #####:  140:    memset(table->table, 0, size * sizeof(virHashEntry));
call    0 never executed
    #####:  141:    table->size = size;
        -:  142:
        -:  143:    /*  If the two loops are merged, there would be situations where
        -:  144:     * a new entry needs to allocated and data copied into it from 
        -:  145:     * the main table. So instead, we run through the array twice, first
        -:  146:     * copying all the elements in the main array (where we can't get
        -:  147:     * conflicts) and then the rest, so we only free (and don't allocate)
        -:  148:     */
    #####:  149:    for (i = 0; i < oldsize; i++) {
branch  0 never executed
branch  1 never executed
    #####:  150:        if (oldtable[i].valid == 0)
branch  0 never executed
branch  1 never executed
    #####:  151:            continue;
    #####:  152:        key = virHashComputeKey(table, oldtable[i].name);
call    0 never executed
    #####:  153:        memcpy(&(table->table[key]), &(oldtable[i]), sizeof(virHashEntry));
call    0 never executed
    #####:  154:        table->table[key].next = NULL;
        -:  155:    }
        -:  156:
    #####:  157:    for (i = 0; i < oldsize; i++) {
branch  0 never executed
branch  1 never executed
    #####:  158:        iter = oldtable[i].next;
    #####:  159:        while (iter) {
branch  0 never executed
branch  1 never executed
    #####:  160:            next = iter->next;
        -:  161:
        -:  162:            /*
        -:  163:             * put back the entry in the new table
        -:  164:             */
        -:  165:
    #####:  166:            key = virHashComputeKey(table, iter->name);
call    0 never executed
    #####:  167:            if (table->table[key].valid == 0) {
branch  0 never executed
branch  1 never executed
    #####:  168:                memcpy(&(table->table[key]), iter, sizeof(virHashEntry));
call    0 never executed
    #####:  169:                table->table[key].next = NULL;
    #####:  170:                free(iter);
call    0 never executed
        -:  171:            } else {
    #####:  172:                iter->next = table->table[key].next;
    #####:  173:                table->table[key].next = iter;
        -:  174:            }
        -:  175:
        -:  176:#ifdef DEBUG_GROW
        -:  177:            nbElem++;
        -:  178:#endif
        -:  179:
    #####:  180:            iter = next;
        -:  181:        }
        -:  182:    }
        -:  183:
    #####:  184:    free(oldtable);
call    0 never executed
        -:  185:
        -:  186:#ifdef DEBUG_GROW
        -:  187:    xmlGenericError(xmlGenericErrorContext,
        -:  188:                    "virHashGrow : from %d to %d, %d elems\n", oldsize,
        -:  189:                    size, nbElem);
        -:  190:#endif
        -:  191:
    #####:  192:    return (0);
        -:  193:}
        -:  194:
        -:  195:/**
        -:  196: * virHashFree:
        -:  197: * @table: the hash table
        -:  198: * @f:  the deallocator function for items in the hash
        -:  199: *
        -:  200: * Free the hash @table and its contents. The userdata is
        -:  201: * deallocated with @f if provided.
        -:  202: */
        -:  203:void
        -:  204:virHashFree(virHashTablePtr table, virHashDeallocator f)
function virHashFree called 0 returned 0% blocks executed 0%
    #####:  205:{
        -:  206:    int i;
        -:  207:    virHashEntryPtr iter;
        -:  208:    virHashEntryPtr next;
    #####:  209:    int inside_table = 0;
        -:  210:    int nbElems;
        -:  211:
    #####:  212:    if (table == NULL)
branch  0 never executed
branch  1 never executed
    #####:  213:        return;
    #####:  214:    if (table->table) {
branch  0 never executed
branch  1 never executed
    #####:  215:        nbElems = table->nbElems;
    #####:  216:        for (i = 0; (i < table->size) && (nbElems > 0); i++) {
branch  0 never executed
branch  1 never executed
    #####:  217:            iter = &(table->table[i]);
    #####:  218:            if (iter->valid == 0)
branch  0 never executed
branch  1 never executed
    #####:  219:                continue;
    #####:  220:            inside_table = 1;
    #####:  221:            while (iter) {
branch  0 never executed
branch  1 never executed
    #####:  222:                next = iter->next;
    #####:  223:                if ((f != NULL) && (iter->payload != NULL))
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
    #####:  224:                    f(iter->payload, iter->name);
call    0 never executed
    #####:  225:                if (iter->name)
branch  0 never executed
branch  1 never executed
    #####:  226:                    free(iter->name);
call    0 never executed
    #####:  227:                iter->payload = NULL;
    #####:  228:                if (!inside_table)
branch  0 never executed
branch  1 never executed
    #####:  229:                    free(iter);
call    0 never executed
    #####:  230:                nbElems--;
    #####:  231:                inside_table = 0;
    #####:  232:                iter = next;
        -:  233:            }
    #####:  234:            inside_table = 0;
        -:  235:        }
    #####:  236:        free(table->table);
call    0 never executed
        -:  237:    }
    #####:  238:    free(table);
call    0 never executed
        -:  239:}
        -:  240:
        -:  241:/**
        -:  242: * virHashAddEntry3:
        -:  243: * @table: the hash table
        -:  244: * @name: the name of the userdata
        -:  245: * @userdata: a pointer to the userdata
        -:  246: *
        -:  247: * Add the @userdata to the hash @table. This can later be retrieved
        -:  248: * by using @name. Duplicate entries generate errors.
        -:  249: *
        -:  250: * Returns 0 the addition succeeded and -1 in case of error.
        -:  251: */
        -:  252:int
        -:  253:virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
function virHashAddEntry called 0 returned 0% blocks executed 0%
    #####:  254:{
    #####:  255:    unsigned long key, len = 0;
        -:  256:    virHashEntryPtr entry;
        -:  257:    virHashEntryPtr insert;
        -:  258:
    #####:  259:    if ((table == NULL) || (name == NULL))
branch  0 never executed
branch  1 never executed
    #####:  260:        return (-1);
        -:  261:
        -:  262:    /*
        -:  263:     * Check for duplicate and insertion location.
        -:  264:     */
    #####:  265:    key = virHashComputeKey(table, name);
call    0 never executed
    #####:  266:    if (table->table[key].valid == 0) {
branch  0 never executed
branch  1 never executed
    #####:  267:        insert = NULL;
        -:  268:    } else {
    #####:  269:        for (insert = &(table->table[key]); insert->next != NULL;
branch  0 never executed
branch  1 never executed
    #####:  270:             insert = insert->next) {
    #####:  271:            if (!strcmp(insert->name, name))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  272:                return (-1);
    #####:  273:            len++;
        -:  274:        }
    #####:  275:        if (!strcmp(insert->name, name))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  276:            return (-1);
        -:  277:    }
        -:  278:
    #####:  279:    if (insert == NULL) {
branch  0 never executed
branch  1 never executed
    #####:  280:        entry = &(table->table[key]);
        -:  281:    } else {
    #####:  282:        entry = malloc(sizeof(virHashEntry));
call    0 never executed
    #####:  283:        if (entry == NULL)
branch  0 never executed
branch  1 never executed
    #####:  284:            return (-1);
        -:  285:    }
        -:  286:
    #####:  287:    entry->name = strdup(name);
call    0 never executed
    #####:  288:    entry->payload = userdata;
    #####:  289:    entry->next = NULL;
    #####:  290:    entry->valid = 1;
        -:  291:
        -:  292:
    #####:  293:    if (insert != NULL)
branch  0 never executed
branch  1 never executed
    #####:  294:        insert->next = entry;
        -:  295:
    #####:  296:    table->nbElems++;
        -:  297:
    #####:  298:    if (len > MAX_HASH_LEN)
branch  0 never executed
branch  1 never executed
    #####:  299:        virHashGrow(table, MAX_HASH_LEN * table->size);
call    0 never executed
        -:  300:
    #####:  301:    return (0);
        -:  302:}
        -:  303:
        -:  304:/**
        -:  305: * virHashUpdateEntry:
        -:  306: * @table: the hash table
        -:  307: * @name: the name of the userdata
        -:  308: * @userdata: a pointer to the userdata
        -:  309: * @f: the deallocator function for replaced item (if any)
        -:  310: *
        -:  311: * Add the @userdata to the hash @table. This can later be retrieved
        -:  312: * by using @name. Existing entry for this tuple
        -:  313: * will be removed and freed with @f if found.
        -:  314: *
        -:  315: * Returns 0 the addition succeeded and -1 in case of error.
        -:  316: */
        -:  317:int
        -:  318:virHashUpdateEntry(virHashTablePtr table, const char *name,
        -:  319:                   void *userdata, virHashDeallocator f)
function virHashUpdateEntry called 0 returned 0% blocks executed 0%
    #####:  320:{
        -:  321:    unsigned long key;
        -:  322:    virHashEntryPtr entry;
        -:  323:    virHashEntryPtr insert;
        -:  324:
    #####:  325:    if ((table == NULL) || name == NULL)
branch  0 never executed
branch  1 never executed
    #####:  326:        return (-1);
        -:  327:
        -:  328:    /*
        -:  329:     * Check for duplicate and insertion location.
        -:  330:     */
    #####:  331:    key = virHashComputeKey(table, name);
call    0 never executed
    #####:  332:    if (table->table[key].valid == 0) {
branch  0 never executed
branch  1 never executed
    #####:  333:        insert = NULL;
        -:  334:    } else {
    #####:  335:        for (insert = &(table->table[key]); insert->next != NULL;
branch  0 never executed
branch  1 never executed
    #####:  336:             insert = insert->next) {
    #####:  337:            if (!strcmp(insert->name, name)) {
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  338:                if (f)
branch  0 never executed
branch  1 never executed
    #####:  339:                    f(insert->payload, insert->name);
call    0 never executed
    #####:  340:                insert->payload = userdata;
    #####:  341:                return (0);
        -:  342:            }
        -:  343:        }
    #####:  344:        if (!strcmp(insert->name, name)) {
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  345:            if (f)
branch  0 never executed
branch  1 never executed
    #####:  346:                f(insert->payload, insert->name);
call    0 never executed
    #####:  347:            insert->payload = userdata;
    #####:  348:            return (0);
        -:  349:        }
        -:  350:    }
        -:  351:
    #####:  352:    if (insert == NULL) {
branch  0 never executed
branch  1 never executed
    #####:  353:        entry = &(table->table[key]);
        -:  354:    } else {
    #####:  355:        entry = malloc(sizeof(virHashEntry));
call    0 never executed
    #####:  356:        if (entry == NULL)
branch  0 never executed
branch  1 never executed
    #####:  357:            return (-1);
        -:  358:    }
        -:  359:
    #####:  360:    entry->name = strdup(name);
call    0 never executed
    #####:  361:    entry->payload = userdata;
    #####:  362:    entry->next = NULL;
    #####:  363:    entry->valid = 1;
    #####:  364:    table->nbElems++;
        -:  365:
        -:  366:
    #####:  367:    if (insert != NULL) {
branch  0 never executed
branch  1 never executed
    #####:  368:        insert->next = entry;
        -:  369:    }
    #####:  370:    return (0);
        -:  371:}
        -:  372:
        -:  373:/**
        -:  374: * virHashLookup:
        -:  375: * @table: the hash table
        -:  376: * @name: the name of the userdata
        -:  377: *
        -:  378: * Find the userdata specified by the (@name, @name2, @name3) tuple.
        -:  379: *
        -:  380: * Returns the a pointer to the userdata
        -:  381: */
        -:  382:void *
        -:  383:virHashLookup(virHashTablePtr table, const char *name)
function virHashLookup called 0 returned 0% blocks executed 0%
    #####:  384:{
        -:  385:    unsigned long key;
        -:  386:    virHashEntryPtr entry;
        -:  387:
    #####:  388:    if (table == NULL)
branch  0 never executed
branch  1 never executed
    #####:  389:        return (NULL);
    #####:  390:    if (name == NULL)
branch  0 never executed
branch  1 never executed
    #####:  391:        return (NULL);
    #####:  392:    key = virHashComputeKey(table, name);
call    0 never executed
    #####:  393:    if (table->table[key].valid == 0)
branch  0 never executed
branch  1 never executed
    #####:  394:        return (NULL);
    #####:  395:    for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
branch  0 never executed
branch  1 never executed
    #####:  396:        if (!strcmp(entry->name, name))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  397:            return (entry->payload);
        -:  398:    }
    #####:  399:    return (NULL);
        -:  400:}
        -:  401:
        -:  402:/**
        -:  403: * virHashSize:
        -:  404: * @table: the hash table
        -:  405: *
        -:  406: * Query the number of elements installed in the hash @table.
        -:  407: *
        -:  408: * Returns the number of elements in the hash table or
        -:  409: * -1 in case of error
        -:  410: */
        -:  411:int
        -:  412:virHashSize(virHashTablePtr table)
function virHashSize called 0 returned 0% blocks executed 0%
    #####:  413:{
    #####:  414:    if (table == NULL)
branch  0 never executed
branch  1 never executed
    #####:  415:        return (-1);
    #####:  416:    return (table->nbElems);
        -:  417:}
        -:  418:
        -:  419:/**
        -:  420: * virHashRemoveEntry:
        -:  421: * @table: the hash table
        -:  422: * @name: the name of the userdata
        -:  423: * @f: the deallocator function for removed item (if any)
        -:  424: *
        -:  425: * Find the userdata specified by the @name and remove
        -:  426: * it from the hash @table. Existing userdata for this tuple will be removed
        -:  427: * and freed with @f.
        -:  428: *
        -:  429: * Returns 0 if the removal succeeded and -1 in case of error or not found.
        -:  430: */
        -:  431:int
        -:  432:virHashRemoveEntry(virHashTablePtr table, const char *name,
        -:  433:                   virHashDeallocator f)
function virHashRemoveEntry called 0 returned 0% blocks executed 0%
    #####:  434:{
        -:  435:    unsigned long key;
        -:  436:    virHashEntryPtr entry;
    #####:  437:    virHashEntryPtr prev = NULL;
        -:  438:
    #####:  439:    if (table == NULL || name == NULL)
branch  0 never executed
branch  1 never executed
    #####:  440:        return (-1);
        -:  441:
    #####:  442:    key = virHashComputeKey(table, name);
call    0 never executed
    #####:  443:    if (table->table[key].valid == 0) {
branch  0 never executed
branch  1 never executed
    #####:  444:        return (-1);
        -:  445:    } else {
    #####:  446:        for (entry = &(table->table[key]); entry != NULL;
branch  0 never executed
branch  1 never executed
    #####:  447:             entry = entry->next) {
    #####:  448:            if (!strcmp(entry->name, name)) {
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  449:                if ((f != NULL) && (entry->payload != NULL))
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
    #####:  450:                    f(entry->payload, entry->name);
call    0 never executed
    #####:  451:                entry->payload = NULL;
    #####:  452:                if (entry->name)
branch  0 never executed
branch  1 never executed
    #####:  453:                    free(entry->name);
call    0 never executed
    #####:  454:                if (prev) {
branch  0 never executed
branch  1 never executed
    #####:  455:                    prev->next = entry->next;
    #####:  456:                    free(entry);
call    0 never executed
        -:  457:                } else {
    #####:  458:                    if (entry->next == NULL) {
branch  0 never executed
branch  1 never executed
    #####:  459:                        entry->valid = 0;
        -:  460:                    } else {
    #####:  461:                        entry = entry->next;
    #####:  462:                        memcpy(&(table->table[key]), entry,
call    0 never executed
        -:  463:                               sizeof(virHashEntry));
    #####:  464:                        free(entry);
call    0 never executed
        -:  465:                    }
        -:  466:                }
    #####:  467:                table->nbElems--;
    #####:  468:                return (0);
        -:  469:            }
    #####:  470:            prev = entry;
        -:  471:        }
    #####:  472:        return (-1);
        -:  473:    }
        -:  474:}
        -:  475:
        -:  476:/************************************************************************
        -:  477: *									*
        -:  478: *			Domain and Connections allocations		*
        -:  479: *									*
        -:  480: ************************************************************************/
        -:  481:
        -:  482:/**
        -:  483: * virHashError:
        -:  484: * @conn: the connection if available
        -:  485: * @error: the error noumber
        -:  486: * @info: extra information string
        -:  487: *
        -:  488: * Handle an error at the connection level
        -:  489: */
        -:  490:static void
        -:  491:virHashError(virConnectPtr conn, virErrorNumber error, const char *info)
function virHashError called 0 returned 0% blocks executed 0%
    #####:  492:{
        -:  493:    const char *errmsg;
        -:  494:
    #####:  495:    if (error == VIR_ERR_OK)
branch  0 never executed
branch  1 never executed
    #####:  496:        return;
        -:  497:
    #####:  498:    errmsg = __virErrorMsg(error, info);
call    0 never executed
    #####:  499:    __virRaiseError(conn, NULL, VIR_FROM_NONE, error, VIR_ERR_ERROR,
call    0 never executed
        -:  500:                    errmsg, info, NULL, 0, 0, errmsg, info);
        -:  501:}
        -:  502:
        -:  503:
        -:  504:/**
        -:  505: * virDomainFreeName:
        -:  506: * @domain: a domain object
        -:  507: *
        -:  508: * Destroy the domain object, this is just used by the domain hash callback.
        -:  509: *
        -:  510: * Returns 0 in case of success and -1 in case of failure.
        -:  511: */
        -:  512:static int
        -:  513:virDomainFreeName(virDomainPtr domain, const char *name ATTRIBUTE_UNUSED)
function virDomainFreeName called 0 returned 0% blocks executed 0%
    #####:  514:{
    #####:  515:    return (virDomainFree(domain));
call    0 never executed
        -:  516:}
        -:  517:
        -:  518:/**
        -:  519: * virGetConnect:
        -:  520: *
        -:  521: * Allocates a new hypervisor connection structure
        -:  522: *
        -:  523: * Returns a new pointer or NULL in case of error.
        -:  524: */
        -:  525:virConnectPtr
function virGetConnect called 0 returned 0% blocks executed 0%
    #####:  526:virGetConnect(void) {
        -:  527:    virConnectPtr ret;
        -:  528:
    #####:  529:    ret = (virConnectPtr) malloc(sizeof(virConnect));
call    0 never executed
    #####:  530:    if (ret == NULL) {
branch  0 never executed
branch  1 never executed
    #####:  531:        virHashError(NULL, VIR_ERR_NO_MEMORY, "Allocating connection");
call    0 never executed
    #####:  532:        goto failed;
        -:  533:    }
    #####:  534:    memset(ret, 0, sizeof(virConnect));
call    0 never executed
    #####:  535:    ret->magic = VIR_CONNECT_MAGIC;
    #####:  536:    ret->nb_drivers = 0;
    #####:  537:    ret->domains = virHashCreate(20);
call    0 never executed
    #####:  538:    if (ret->domains == NULL)
branch  0 never executed
branch  1 never executed
    #####:  539:        goto failed;
    #####:  540:    ret->domains_mux = xmlNewMutex();
call    0 never executed
    #####:  541:    if (ret->domains_mux == NULL)
branch  0 never executed
branch  1 never executed
    #####:  542:        goto failed;
        -:  543:
    #####:  544:    ret->uses = 1;
    #####:  545:    return(ret);
        -:  546:
    #####:  547:failed:
    #####:  548:    if (ret != NULL) {
branch  0 never executed
branch  1 never executed
    #####:  549:	if (ret->domains != NULL)
branch  0 never executed
branch  1 never executed
    #####:  550:	    virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
call    0 never executed
    #####:  551:	if (ret->domains_mux != NULL)
branch  0 never executed
branch  1 never executed
    #####:  552:	    xmlFreeMutex(ret->domains_mux);
call    0 never executed
    #####:  553:        free(ret);
call    0 never executed
        -:  554:    }
    #####:  555:    return(NULL);
        -:  556:}
        -:  557:
        -:  558:/**
        -:  559: * virFreeConnect:
        -:  560: * @conn: the hypervisor connection
        -:  561: *
        -:  562: * Release the connection. if the use count drops to zero, the structure is
        -:  563: * actually freed.
        -:  564: *
        -:  565: * Returns the reference count or -1 in case of failure.
        -:  566: */
        -:  567:int	
function virFreeConnect called 0 returned 0% blocks executed 0%
    #####:  568:virFreeConnect(virConnectPtr conn) {
        -:  569:    int ret;
        -:  570:
    #####:  571:    if ((!VIR_IS_CONNECT(conn)) || (conn->domains_mux == NULL)) {
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
branch  4 never executed
branch  5 never executed
    #####:  572:        virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
call    0 never executed
    #####:  573:        return(-1);
        -:  574:    }
    #####:  575:    xmlMutexLock(conn->domains_mux);
call    0 never executed
    #####:  576:    conn->uses--;
    #####:  577:    ret = conn->uses;
    #####:  578:    if (ret > 0) {
branch  0 never executed
branch  1 never executed
    #####:  579:	xmlMutexUnlock(conn->domains_mux);
call    0 never executed
    #####:  580:	return(ret);
        -:  581:    }
        -:  582:
    #####:  583:    if (conn->domains != NULL)
branch  0 never executed
branch  1 never executed
    #####:  584:        virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
call    0 never executed
    #####:  585:    if (conn->domains_mux != NULL)
branch  0 never executed
branch  1 never executed
    #####:  586:        xmlFreeMutex(conn->domains_mux);
call    0 never executed
    #####:  587:    free(conn);
call    0 never executed
    #####:  588:    return(0);
        -:  589:}
        -:  590:
        -:  591:/**
        -:  592: * virGetDomain:
        -:  593: * @conn: the hypervisor connection
        -:  594: * @name: pointer to the domain name or NULL
        -:  595: * @uuid: pointer to the uuid or NULL
        -:  596: *
        -:  597: * Lookup if the domain is already registered for that connection,
        -:  598: * if yes return a new pointer to it, if no allocate a new structure,
        -:  599: * and register it in the table. In any case a corresponding call to
        -:  600: * virFreeDomain() is needed to not leak data.
        -:  601: *
        -:  602: * Returns a pointer to the domain, or NULL in case of failure
        -:  603: */
        -:  604:virDomainPtr
function virGetDomain called 0 returned 0% blocks executed 0%
    #####:  605:virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
    #####:  606:    virDomainPtr ret = NULL;
        -:  607:
    #####:  608:    if ((!VIR_IS_CONNECT(conn)) || ((name == NULL) && (uuid == NULL)) ||
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
branch  4 never executed
branch  5 never executed
branch  6 never executed
branch  7 never executed
        -:  609:        (conn->domains_mux == NULL)) {
    #####:  610:        virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
call    0 never executed
    #####:  611:        return(NULL);
        -:  612:    }
    #####:  613:    xmlMutexLock(conn->domains_mux);
call    0 never executed
        -:  614:
        -:  615:    /* TODO search by UUID first as they are better differenciators */
        -:  616:
    #####:  617:    ret = (virDomainPtr) virHashLookup(conn->domains, name);
call    0 never executed
    #####:  618:    if (ret != NULL) {
branch  0 never executed
branch  1 never executed
        -:  619:        /* TODO check the UUID */
    #####:  620:	goto done;
        -:  621:    }
        -:  622:
        -:  623:    /*
        -:  624:     * not found, allocate a new one
        -:  625:     */
    #####:  626:    ret = (virDomainPtr) malloc(sizeof(virDomain));
call    0 never executed
    #####:  627:    if (ret == NULL) {
branch  0 never executed
branch  1 never executed
    #####:  628:        virHashError(conn, VIR_ERR_NO_MEMORY, "Allocating domain");
call    0 never executed
    #####:  629:	goto error;
        -:  630:    }
    #####:  631:    memset(ret, 0, sizeof(virDomain));
call    0 never executed
    #####:  632:    ret->name = strdup(name);
call    0 never executed
    #####:  633:    if (ret->name == NULL) {
branch  0 never executed
branch  1 never executed
    #####:  634:        virHashError(conn, VIR_ERR_NO_MEMORY, "Allocating domain");
call    0 never executed
    #####:  635:	goto error;
        -:  636:    }
    #####:  637:    ret->magic = VIR_DOMAIN_MAGIC;
    #####:  638:    ret->conn = conn;
    #####:  639:    ret->handle = -1;
    #####:  640:    if (uuid != NULL)
branch  0 never executed
branch  1 never executed
    #####:  641:        memcpy(&(ret->uuid[0]), uuid, 16);
call    0 never executed
        -:  642:
    #####:  643:    if (virHashAddEntry(conn->domains, name, ret) < 0) {
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  644:        virHashError(conn, VIR_ERR_INTERNAL_ERROR,
call    0 never executed
        -:  645:	             "Failed to add domain to connectio hash table");
    #####:  646:	goto error;
        -:  647:    }
    #####:  648:    conn->uses++;
    #####:  649:done:
    #####:  650:    ret->uses++;
    #####:  651:    xmlMutexUnlock(conn->domains_mux);
call    0 never executed
    #####:  652:    return(ret);
        -:  653:
    #####:  654:error:
    #####:  655:    xmlMutexUnlock(conn->domains_mux);
call    0 never executed
    #####:  656:    if (ret != NULL) {
branch  0 never executed
branch  1 never executed
    #####:  657:	if (ret->name != NULL)
branch  0 never executed
branch  1 never executed
    #####:  658:	    free(ret->name );
call    0 never executed
    #####:  659:	free(ret);
call    0 never executed
        -:  660:    }
    #####:  661:    return(NULL);
        -:  662:}
        -:  663:
        -:  664:/**
        -:  665: * virFreeDomain:
        -:  666: * @conn: the hypervisor connection
        -:  667: * @domain: the domain to release
        -:  668: *
        -:  669: * Release the given domain, if the reference count drops to zero, then
        -:  670: * the domain is really freed.
        -:  671: *
        -:  672: * Returns the reference count or -1 in case of failure.
        -:  673: */
        -:  674:int
function virFreeDomain called 0 returned 0% blocks executed 0%
    #####:  675:virFreeDomain(virConnectPtr conn, virDomainPtr domain) {
    #####:  676:    int ret = 0;
        -:  677:
    #####:  678:    if ((!VIR_IS_CONNECT(conn)) || (!VIR_IS_CONNECTED_DOMAIN(domain)) ||
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
branch  4 never executed
branch  5 never executed
branch  6 never executed
branch  7 never executed
branch  8 never executed
branch  9 never executed
branch 10 never executed
branch 11 never executed
branch 12 never executed
branch 13 never executed
branch 14 never executed
branch 15 never executed
        -:  679:        (domain->conn != conn) || (conn->domains_mux == NULL)) {
    #####:  680:        virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
call    0 never executed
    #####:  681:        return(-1);
        -:  682:    }
    #####:  683:    xmlMutexLock(conn->domains_mux);
call    0 never executed
        -:  684:
        -:  685:    /*
        -:  686:     * decrement the count for the domain
        -:  687:     */
    #####:  688:    domain->uses--;
    #####:  689:    ret = domain->uses;
    #####:  690:    if (ret > 0)
branch  0 never executed
branch  1 never executed
    #####:  691:        goto done;
        -:  692:
        -:  693:    /* TODO search by UUID first as they are better differenciators */
        -:  694:
    #####:  695:    if (virHashRemoveEntry(conn->domains, domain->name, NULL) < 0) {
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  696:        virHashError(conn, VIR_ERR_INTERNAL_ERROR,
call    0 never executed
        -:  697:	             "domain missing from connection hash table");
    #####:  698:        goto done;
        -:  699:    }
    #####:  700:    domain->magic = -1;
    #####:  701:    domain->handle = -1;
    #####:  702:    if (domain->path != NULL)
branch  0 never executed
branch  1 never executed
    #####:  703:        free(domain->path);
call    0 never executed
    #####:  704:    if (domain->xml)
branch  0 never executed
branch  1 never executed
    #####:  705:        free(domain->xml);
call    0 never executed
    #####:  706:    if (domain->name)
branch  0 never executed
branch  1 never executed
    #####:  707:        free(domain->name);
call    0 never executed
    #####:  708:    free(domain);
call    0 never executed
        -:  709:
        -:  710:    /*
        -:  711:     * decrement the count for the connection
        -:  712:     */
    #####:  713:    conn->uses--;
    #####:  714:    if (conn->uses > 0)
branch  0 never executed
branch  1 never executed
    #####:  715:        goto done;
        -:  716:    
    #####:  717:    if (conn->domains != NULL)
branch  0 never executed
branch  1 never executed
    #####:  718:        virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
call    0 never executed
    #####:  719:    if (conn->domains_mux != NULL)
branch  0 never executed
branch  1 never executed
    #####:  720:        xmlFreeMutex(conn->domains_mux);
call    0 never executed
    #####:  721:    free(conn);
call    0 never executed
    #####:  722:    return(0);
        -:  723:
    #####:  724:done:
    #####:  725:    xmlMutexUnlock(conn->domains_mux);
call    0 never executed
    #####:  726:    return(ret);
        -:  727:}
        -:  728:
        -:  729:/**
        -:  730: * virGetDomainByID:
        -:  731: * @conn: the hypervisor connection
        -:  732: * @id: the ID number for the domain
        -:  733: *
        -:  734: * Lookup if the domain ID is already registered for that connection,
        -:  735: * if yes return a new pointer to it, if no return NULL
        -:  736: *
        -:  737: * Returns a pointer to the domain, or NULL if not found
        -:  738: */
        -:  739:virDomainPtr
function virGetDomainByID called 0 returned 0% blocks executed 0%
    #####:  740:virGetDomainByID(virConnectPtr conn, int id) {
    #####:  741:    virDomainPtr ret = NULL, cur;
        -:  742:    virHashEntryPtr iter, next;
        -:  743:    virHashTablePtr table;
        -:  744:    int key;
        -:  745:
    #####:  746:    if ((!VIR_IS_CONNECT(conn)) || (id < 0)) {
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
    #####:  747:        virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
call    0 never executed
    #####:  748:        return(NULL);
        -:  749:    }
    #####:  750:    xmlMutexLock(conn->domains_mux);
call    0 never executed
        -:  751:
    #####:  752:    table = conn->domains;
    #####:  753:    if ((table == NULL) || (table->nbElems == 0))
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
        -:  754:        goto done;
    #####:  755:    for (key = 0;key < table->size;key++) {
branch  0 never executed
branch  1 never executed
    #####:  756:        if (table->table[key].valid == 0)
branch  0 never executed
branch  1 never executed
    #####:  757:	    continue;
    #####:  758:	iter = &(table->table[key]);
    #####:  759:	while (iter != NULL) {
branch  0 never executed
branch  1 never executed
    #####:  760:	    next = iter->next;
    #####:  761:	    cur = (virDomainPtr) iter->payload;
    #####:  762:	    if ((cur != NULL) && (cur->handle == id)) {
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
    #####:  763:	        ret = cur;
    #####:  764:		goto done;
        -:  765:	    }
    #####:  766:	    iter = next;
        -:  767:	}
        -:  768:    }
    #####:  769:done:
    #####:  770:    xmlMutexUnlock(conn->domains_mux);
call    0 never executed
    #####:  771:    return(ret);
        -:  772:}