[libvirt] [PATCH] hash: make virHashFree more free-like

Eric Blake eblake at redhat.com
Fri Feb 18 21:31:36 UTC 2011


Two-argument free functions are uncommon; match the style elsewhere
by caching the callback at creation.

* src/util/hash.h (virHashCreate, virHashFree): Move deallocator
argument to creation.
* cfg.mk (useless_free_options): Add virHashFree.
* src/util/hash.c (_virHashTable): Track deallocator.
(virHashCreate, virHashFree): Update to new signature.
* src/conf/domain_conf.c (virDomainObjListDeinit)
(virDomainObjListInit, virDomainDiskDefForeachPath)
(virDomainSnapshotObjListDeinit, virDomainSnapshotObjListInit):
Update callers.
* src/conf/nwfilter_params.c (virNWFilterHashTableFree)
(virNWFilterHashTableCreate): Likewise.
* src/conf/nwfilter_conf.c (virNWFilterTriggerVMFilterRebuild):
Likewise.
* src/cpu/cpu_generic.c (genericHashFeatures, genericBaseline):
Likewise.
* src/xen/xm_internal.c (xenXMOpen, xenXMClose): Likewise.
* src/nwfilter/nwfilter_learnipaddr.c (virNWFilterLearnInit)
(virNWFilterLearnShutdown): Likewise.
* src/qemu/qemu_command.c (qemuDomainPCIAddressSetCreate)
(qemuDomainPCIAddressSetFree): Likewise.
* src/qemu/qemu_process.c (qemuProcessWaitForMonitor): Likewise.
---

Requires that this be applied first:
https://www.redhat.com/archives/libvir-list/2011-February/msg00784.html

 cfg.mk                              |    1 +
 src/conf/domain_conf.c              |   49 ++++++++++++++++++----------------
 src/conf/nwfilter_conf.c            |    6 ++--
 src/conf/nwfilter_params.c          |    5 ++-
 src/cpu/cpu_generic.c               |   10 +++---
 src/nwfilter/nwfilter_learnipaddr.c |    9 +++---
 src/qemu/qemu_command.c             |   16 ++++++-----
 src/qemu/qemu_process.c             |    4 +-
 src/util/hash.c                     |   14 +++++----
 src/util/hash.h                     |    9 +++---
 src/xen/xm_internal.c               |   12 ++++----
 11 files changed, 73 insertions(+), 62 deletions(-)

diff --git a/cfg.mk b/cfg.mk
index f870723..1bb9cbb 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -106,6 +106,7 @@ useless_free_options =				\
   --name=virDomainSoundDefFree			\
   --name=virDomainVideoDefFree			\
   --name=virDomainWatchdogDefFree		\
+  --name=virHashFree				\
   --name=virInterfaceDefFree			\
   --name=virInterfaceIpDefFree			\
   --name=virInterfaceObjFree			\
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e7c3409..b97c1f0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -391,26 +391,27 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST,
 #define VIR_DOMAIN_XML_WRITE_FLAGS  VIR_DOMAIN_XML_SECURE
 #define VIR_DOMAIN_XML_READ_FLAGS   VIR_DOMAIN_XML_INACTIVE

+static void
+virDomainObjListDeallocator(void *payload, const char *name ATTRIBUTE_UNUSED)
+{
+    virDomainObjPtr obj = payload;
+    virDomainObjLock(obj);
+    if (virDomainObjUnref(obj) > 0)
+        virDomainObjUnlock(obj);
+}
+
 int virDomainObjListInit(virDomainObjListPtr doms)
 {
-    doms->objs = virHashCreate(50);
+    doms->objs = virHashCreate(50, virDomainObjListDeallocator);
     if (!doms->objs)
         return -1;
     return 0;
 }


-static void virDomainObjListDeallocator(void *payload, const char *name ATTRIBUTE_UNUSED)
-{
-    virDomainObjPtr obj = payload;
-    virDomainObjLock(obj);
-    if (virDomainObjUnref(obj) > 0)
-        virDomainObjUnlock(obj);
-}
-
 void virDomainObjListDeinit(virDomainObjListPtr doms)
 {
-    virHashFree(doms->objs, virDomainObjListDeallocator);
+    virHashFree(doms->objs);
 }


@@ -8751,25 +8752,27 @@ virDomainSnapshotObjPtr virDomainSnapshotAssignDef(virDomainSnapshotObjListPtr s
 }

 /* Snapshot Obj List functions */
+static void
+virDomainSnapshotObjListDeallocator(void *payload,
+                                    const char *name ATTRIBUTE_UNUSED)
+{
+    virDomainSnapshotObjPtr obj = payload;
+
+    virDomainSnapshotObjUnref(obj);
+}
+
 int virDomainSnapshotObjListInit(virDomainSnapshotObjListPtr snapshots)
 {
-    snapshots->objs = virHashCreate(50);
+    snapshots->objs = virHashCreate(50, virDomainSnapshotObjListDeallocator);
     if (!snapshots->objs)
         return -1;
     return 0;
 }

-static void virDomainSnapshotObjListDeallocator(void *payload,
-                                                const char *name ATTRIBUTE_UNUSED)
-{
-    virDomainSnapshotObjPtr obj = payload;
-
-    virDomainSnapshotObjUnref(obj);
-}
-
-static void virDomainSnapshotObjListDeinit(virDomainSnapshotObjListPtr snapshots)
+static void
+virDomainSnapshotObjListDeinit(virDomainSnapshotObjListPtr snapshots)
 {
-    virHashFree(snapshots->objs, virDomainSnapshotObjListDeallocator);
+    virHashFree(snapshots->objs);
 }

 struct virDomainSnapshotNameData {
@@ -9002,7 +9005,7 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
         }
     }

-    paths = virHashCreate(5);
+    paths = virHashCreate(5, NULL);

     do {
         virStorageFileMetadata meta;
@@ -9070,7 +9073,7 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
     ret = 0;

 cleanup:
-    virHashFree(paths, NULL);
+    virHashFree(paths);
     VIR_FREE(nextpath);

     return ret;
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index c6a4d6f..1f250e9 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -2,7 +2,7 @@
  * nwfilter_conf.c: network filter XML processing
  *                  (derived from storage_conf.c)
  *
- * Copyright (C) 2006-2010 Red Hat, Inc.
+ * Copyright (C) 2006-2011 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * Copyright (C) 2010 IBM Corporation
@@ -2297,7 +2297,7 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
         .conn = conn,
         .err = 0,
         .step = STEP_APPLY_NEW,
-        .skipInterfaces = virHashCreate(0),
+        .skipInterfaces = virHashCreate(0, NULL),
     };

     if (!cb.skipInterfaces)
@@ -2328,7 +2328,7 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
                                                  &cb);
     }

-    virHashFree(cb.skipInterfaces, NULL);
+    virHashFree(cb.skipInterfaces);

     return err;
 }
diff --git a/src/conf/nwfilter_params.c b/src/conf/nwfilter_params.c
index 23423fa..cd94b30 100644
--- a/src/conf/nwfilter_params.c
+++ b/src/conf/nwfilter_params.c
@@ -1,6 +1,7 @@
 /*
  * nwfilter_params.c: parsing and data maintenance of filter parameters
  *
+ * Copyright (C) 2011 Red Hat, Inc.
  * Copyright (C) 2010 IBM Corporation
  *
  * This library is free software; you can redistribute it and/or
@@ -102,7 +103,7 @@ virNWFilterHashTableFree(virNWFilterHashTablePtr table)
     int i;
     if (!table)
         return;
-    virHashFree(table->hashTable, hashDealloc);
+    virHashFree(table->hashTable);

     for (i = 0; i < table->nNames; i++)
         VIR_FREE(table->names[i]);
@@ -119,7 +120,7 @@ virNWFilterHashTableCreate(int n) {
         virReportOOMError();
         return NULL;
     }
-    ret->hashTable = virHashCreate(n);
+    ret->hashTable = virHashCreate(n, hashDealloc);
     if (!ret->hashTable) {
         VIR_FREE(ret);
         return NULL;
diff --git a/src/cpu/cpu_generic.c b/src/cpu/cpu_generic.c
index a39f262..a98b109 100644
--- a/src/cpu/cpu_generic.c
+++ b/src/cpu/cpu_generic.c
@@ -2,7 +2,7 @@
  * cpu_generic.c: CPU manipulation driver for architectures which are not
  * handled by their own driver
  *
- * Copyright (C) 2009--2010 Red Hat, Inc.
+ * Copyright (C) 2009-2011 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -39,14 +39,14 @@ genericHashFeatures(virCPUDefPtr cpu)
     virHashTablePtr hash;
     unsigned int i;

-    if ((hash = virHashCreate(cpu->nfeatures)) == NULL)
+    if ((hash = virHashCreate(cpu->nfeatures, NULL)) == NULL)
         return NULL;

     for (i = 0; i < cpu->nfeatures; i++) {
         if (virHashAddEntry(hash,
                             cpu->features[i].name,
                             cpu->features + i)) {
-            virHashFree(hash, NULL);
+            virHashFree(hash);
             return NULL;
         }
     }
@@ -105,7 +105,7 @@ genericCompare(virCPUDefPtr host,
         ret = VIR_CPU_COMPARE_IDENTICAL;

 cleanup:
-    virHashFree(hash, NULL);
+    virHashFree(hash);
     return ret;
 }

@@ -178,7 +178,7 @@ genericBaseline(virCPUDefPtr *cpus,
             }
         }

-        virHashFree(hash, NULL);
+        virHashFree(hash);
     }

     if (VIR_ALLOC_N(cpu->features, count) < 0)
diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c
index 02af918..8bd7b50 100644
--- a/src/nwfilter/nwfilter_learnipaddr.c
+++ b/src/nwfilter/nwfilter_learnipaddr.c
@@ -2,6 +2,7 @@
  * nwfilter_learnipaddr.c: support for learning IP address used by a VM
  *                         on an interface
  *
+ * Copyright (C) 2011 Red Hat, Inc.
  * Copyright (C) 2010 IBM Corp.
  * Copyright (C) 2010 Stefan Berger
  *
@@ -822,7 +823,7 @@ virNWFilterLearnInit(void) {

     threadsTerminate = false;

-    pendingLearnReq = virHashCreate(0);
+    pendingLearnReq = virHashCreate(0, freeLearnReqEntry);
     if (!pendingLearnReq) {
         return 1;
     }
@@ -844,7 +845,7 @@ virNWFilterLearnInit(void) {
         return 1;
     }

-    ifaceLockMap = virHashCreate(0);
+    ifaceLockMap = virHashCreate(0, freeIfaceLock);
     if (!ifaceLockMap) {
         virNWFilterLearnShutdown();
         return 1;
@@ -879,12 +880,12 @@ virNWFilterLearnShutdown(void) {

     virNWFilterLearnThreadsTerminate(false);

-    virHashFree(pendingLearnReq, freeLearnReqEntry);
+    virHashFree(pendingLearnReq);
     pendingLearnReq = NULL;

     virNWFilterHashTableFree(ipAddressMap);
     ipAddressMap = NULL;

-    virHashFree(ifaceLockMap, freeIfaceLock);
+    virHashFree(ifaceLockMap);
     ifaceLockMap = NULL;
 }
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0db2843..a41859c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -745,6 +745,13 @@ cleanup:
 }


+static void
+qemuDomainPCIAddressSetFreeEntry(void *payload,
+                                 const char *name ATTRIBUTE_UNUSED)
+{
+    VIR_FREE(payload);
+}
+
 qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def)
 {
     qemuDomainPCIAddressSetPtr addrs;
@@ -752,7 +759,7 @@ qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def)
     if (VIR_ALLOC(addrs) < 0)
         goto no_memory;

-    if (!(addrs->used = virHashCreate(10)))
+    if (!(addrs->used = virHashCreate(10, qemuDomainPCIAddressSetFreeEntry)))
         goto error;

     if (virDomainDeviceInfoIterate(def, qemuCollectPCIAddress, addrs) < 0)
@@ -823,11 +830,6 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
     return ret;
 }

-static void qemuDomainPCIAddressSetFreeEntry(void *payload, const char *name ATTRIBUTE_UNUSED)
-{
-    VIR_FREE(payload);
-}
-

 int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
                                     virDomainDeviceInfoPtr dev)
@@ -852,7 +854,7 @@ void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs)
     if (!addrs)
         return;

-    virHashFree(addrs->used, qemuDomainPCIAddressSetFreeEntry);
+    virHashFree(addrs->used);
     VIR_FREE(addrs);
 }

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 31e3c60..9c5ea63 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -994,7 +994,7 @@ qemuProcessWaitForMonitor(struct qemud_driver* driver,
      * reliable if it's available.
      * Note that the monitor itself can be on a pty, so we still need to try the
      * log output method. */
-    paths = virHashCreate(0);
+    paths = virHashCreate(0, qemuProcessFreePtyPath);
     if (paths == NULL)
         goto cleanup;

@@ -1008,7 +1008,7 @@ qemuProcessWaitForMonitor(struct qemud_driver* driver,
         ret = qemuProcessFindCharDevicePTYsMonitor(vm, paths);

 cleanup:
-    virHashFree(paths, qemuProcessFreePtyPath);
+    virHashFree(paths);

     if (kill(vm->pid, 0) == -1 && errno == ESRCH) {
         /* VM is dead, any other error raised in the interim is probably
diff --git a/src/util/hash.c b/src/util/hash.c
index 9497b60..d7950b9 100644
--- a/src/util/hash.c
+++ b/src/util/hash.c
@@ -55,6 +55,7 @@ struct _virHashTable {
     struct _virHashEntry *table;
     int size;
     int nbElems;
+    virHashDeallocator f;
 };

 /*
@@ -80,13 +81,14 @@ virHashComputeKey(virHashTablePtr table, const char *name)
 /**
  * virHashCreate:
  * @size: the size of the hash table
+ * @deallocator: function to call on each entry during virHashFree
  *
  * Create a new virHashTablePtr.
  *
  * Returns the newly created object, or NULL if an error occured.
  */
 virHashTablePtr
-virHashCreate(int size)
+virHashCreate(int size, virHashDeallocator deallocator)
 {
     virHashTablePtr table = NULL;

@@ -100,6 +102,7 @@ virHashCreate(int size)

     table->size = size;
     table->nbElems = 0;
+    table->f = deallocator;
     if (VIR_ALLOC_N(table->table, size) < 0) {
         virReportOOMError();
         VIR_FREE(table);
@@ -203,13 +206,12 @@ virHashGrow(virHashTablePtr table, int size)
 /**
  * virHashFree:
  * @table: the hash table
- * @f:  the deallocator function for items in the hash
  *
  * Free the hash @table and its contents. The userdata is
- * deallocated with @f if provided.
+ * deallocated with function provided at creation time.
  */
 void
-virHashFree(virHashTablePtr table, virHashDeallocator f)
+virHashFree(virHashTablePtr table)
 {
     int i;
     virHashEntryPtr iter;
@@ -228,8 +230,8 @@ virHashFree(virHashTablePtr table, virHashDeallocator f)
             inside_table = 1;
             while (iter) {
                 next = iter->next;
-                if ((f != NULL) && (iter->payload != NULL))
-                    f(iter->payload, iter->name);
+                if ((table->f != NULL) && (iter->payload != NULL))
+                    table->f(iter->payload, iter->name);
                 VIR_FREE(iter->name);
                 iter->payload = NULL;
                 if (!inside_table)
diff --git a/src/util/hash.h b/src/util/hash.h
index b0ef441..cf08e1a 100644
--- a/src/util/hash.h
+++ b/src/util/hash.h
@@ -3,7 +3,7 @@
  * Description: This module implements the hash table and allocation and
  *              deallocation of domains and connections
  *
- * Copy: Copyright (C) 2005 Red Hat, Inc.
+ * Copy: Copyright (C) 2005, 2011 Red Hat, Inc.
  *
  * Author: Bjorn Reese <bjorn.reese at systematic.dk>
  *         Daniel Veillard <veillard at redhat.com>
@@ -49,13 +49,14 @@ typedef void (*virHashIterator) (void *payload, const char *name, void *data);
  * Returns 1 if the hash entry is desired, 0 to move
  * to next entry
  */
-typedef int (*virHashSearcher) (const void *payload, const char *name, const void *data);
+typedef int (*virHashSearcher) (const void *payload, const char *name,
+                                const void *data);

 /*
  * Constructor and destructor.
  */
-virHashTablePtr virHashCreate(int size);
-void virHashFree(virHashTablePtr table, virHashDeallocator f);
+virHashTablePtr virHashCreate(int size, virHashDeallocator f);
+void virHashFree(virHashTablePtr table);
 int virHashSize(virHashTablePtr table);

 /*
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 242a7de..bc304f0 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -1,7 +1,7 @@
 /*
  * xm_internal.h: helper routines for dealing with inactive domains
  *
- * Copyright (C) 2006-2007, 2009-2010 Red Hat, Inc.
+ * Copyright (C) 2006-2007, 2009-2011 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -587,12 +587,12 @@ xenXMOpen (virConnectPtr conn,

     priv->configDir = XM_CONFIG_DIR;

-    priv->configCache = virHashCreate(50);
+    priv->configCache = virHashCreate(50, xenXMConfigFree);
     if (!priv->configCache)
         return (-1);
-    priv->nameConfigMap = virHashCreate(50);
+    priv->nameConfigMap = virHashCreate(50, NULL);
     if (!priv->nameConfigMap) {
-        virHashFree(priv->configCache, NULL);
+        virHashFree(priv->configCache);
         priv->configCache = NULL;
         return (-1);
     }
@@ -611,8 +611,8 @@ xenXMOpen (virConnectPtr conn,
 int xenXMClose(virConnectPtr conn) {
     xenUnifiedPrivatePtr priv = conn->privateData;

-    virHashFree(priv->nameConfigMap, NULL);
-    virHashFree(priv->configCache, xenXMConfigFree);
+    virHashFree(priv->nameConfigMap);
+    virHashFree(priv->configCache);

     return (0);
 }
-- 
1.7.4




More information about the libvir-list mailing list