From a5e89ae16e8098e9b77a98517f2d10a5d60e7737 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 29 Apr 2015 11:54:58 +0200
Subject: [PATCH] util: Make the virDomainListFree helper more universal

Extend it to a universal helper used for clearing lists of any objects.
Note that the argument type is specifically void * to allow implicit
typecasting.

Additionally add a helper that works on non-NULL terminated arrays once
we know the length.
---
 daemon/remote.c              |  2 +-
 src/conf/domain_conf.c       | 24 +--------------------
 src/conf/domain_conf.h       |  2 --
 src/libvirt_private.syms     |  3 ++-
 src/qemu/qemu_driver.c       |  2 +-
 src/util/virobject.c         | 41 ++++++++++++++++++++++++++++++++++++
 src/util/virobject.h         |  2 ++
 tools/virsh-domain-monitor.c |  2 +-
 8 files changed, 49 insertions(+), 29 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 3a3f1683e9..e259a763b5 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -6382,7 +6382,7 @@ remoteDispatchConnectGetAllDomainStats(virNetServerPtr server ATTRIBUTE_UNUSED,
         virNetMessageSaveError(rerr);
 
     virDomainStatsRecordListFree(retStats);
-    virDomainListFree(doms);
+    virObjectListFree(doms);
 
     return rv;
 }
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4cd36a1066..0c3851321f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -23071,28 +23071,6 @@ virDomainListPopulate(void *payload,
 #undef MATCH
 
 
-/**
- * virDomainListFree:
- * @list: list of domains to free
- *
- * Frees a NULL-terminated list of domains without messing with currently
- * set libvirt errors.
- */
-void
-virDomainListFree(virDomainPtr *list)
-{
-    virDomainPtr *next;
-
-    if (!list)
-        return;
-
-    for (next = list; *next; next++)
-        virObjectUnref(*next);
-
-    VIR_FREE(list);
-}
-
-
 int
 virDomainObjListExport(virDomainObjListPtr doms,
                        virConnectPtr conn,
@@ -23128,7 +23106,7 @@ virDomainObjListExport(virDomainObjListPtr doms,
     ret = data.ndomains;
 
  cleanup:
-    virDomainListFree(data.domains);
+    virObjectListFree(data.domains);
     virObjectUnlock(doms);
     return ret;
 }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 087d282e28..345f882891 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3057,8 +3057,6 @@ int virDomainObjListExport(virDomainObjListPtr doms,
                            virDomainObjListFilter filter,
                            unsigned int flags);
 
-void virDomainListFree(virDomainPtr *list);
-
 int
 virDomainDefMaybeAddController(virDomainDefPtr def,
                                int type,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c8e6fb4d55..d7cac20902 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -341,7 +341,6 @@ virDomainLifecycleCrashTypeFromString;
 virDomainLifecycleCrashTypeToString;
 virDomainLifecycleTypeFromString;
 virDomainLifecycleTypeToString;
-virDomainListFree;
 virDomainLiveConfigHelperMethod;
 virDomainLoaderDefFree;
 virDomainLoaderTypeFromString;
@@ -1881,6 +1880,8 @@ virClassNew;
 virObjectFreeCallback;
 virObjectFreeHashData;
 virObjectIsClass;
+virObjectListFree;
+virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
 virObjectNew;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f40ccae179..bd0ae3d795 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19901,7 +19901,7 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
     virDomainObjEndAPI(&dom);
 
     virDomainStatsRecordListFree(tmpstats);
-    virDomainListFree(domlist);
+    virObjectListFree(domlist);
 
     return ret;
 }
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 9ccd310498..51876b971a 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -405,3 +405,44 @@ void virObjectFreeHashData(void *opaque, const void *name ATTRIBUTE_UNUSED)
 {
     virObjectUnref(opaque);
 }
+
+
+/**
+ * virObjectListFree:
+ * @list: A pointer to a NULL-terminated list of object pointers to free
+ *
+ * Unrefs all members of @list and frees the list itself.
+ */
+void virObjectListFree(void *list)
+{
+    void **next;
+
+    if (!list)
+        return;
+
+    for (next = (void **) list; *next; next++)
+        virObjectUnref(*next);
+
+    VIR_FREE(list);
+}
+
+
+/**
+ * virObjectListFreeCount:
+ * @list: A pointer to a list of object pointers to freea
+ * @count: Number of elements in the list.
+ *
+ * Unrefs all members of @list and frees the list itself.
+ */
+void virObjectListFreeCount(void *list, size_t count)
+{
+    size_t i;
+
+    if (!list)
+        return;
+
+    for (i = 0; i < count; i++)
+        virObjectUnref(((void **)list)[i]);
+
+    VIR_FREE(list);
+}
diff --git a/src/util/virobject.h b/src/util/virobject.h
index ad1f0c1d2c..c3ecc1ef67 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -99,5 +99,7 @@ void virObjectLock(void *lockableobj)
 void virObjectUnlock(void *lockableobj)
     ATTRIBUTE_NONNULL(1);
 
+void virObjectListFree(void *list);
+void virObjectListFreeCount(void *list, size_t count);
 
 #endif /* __VIR_OBJECT_H */
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 96865311a9..91c57e200a 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -2193,7 +2193,7 @@ cmdDomstats(vshControl *ctl, const vshCmd *cmd)
     ret = true;
  cleanup:
     virDomainStatsRecordListFree(records);
-    virDomainListFree(domlist);
+    virObjectListFree(domlist);
 
     return ret;
 }