Re: [PATCH 5/6] nwfilter: Convert _virNWFilterObjList to use virObjectRWLockable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 02/12/2018 05:52 AM, Michal Privoznik wrote:


@@ -430,31 +552,64 @@ virNWFilterObjListGetNames(virNWFilterObjListPtr nwfilters,
                             char **const names,
                             int maxnames)
  {
-    int nnames = 0;
+    struct virNWFilterNameData data = {filter, conn, 0, 0, maxnames, names};


Here you don't user .filter = filter while further below you.

The rest looks all good to me.

      size_t i;
-    virNWFilterDefPtr def;
-
-    for (i = 0; i < nwfilters->count && nnames < maxnames; i++) {
-        virNWFilterObjPtr obj = nwfilters->objs[i];
-        virObjectLock(obj);
-        def = obj->def;
-        if (!filter || filter(conn, def)) {
-            if (VIR_STRDUP(names[nnames], def->name) < 0) {
-                virObjectUnlock(obj);
-                goto failure;
-            }
-            nnames++;
-        }
-        virObjectUnlock(obj);
+
+    virObjectRWLockRead(nwfilters);
+    virHashForEach(nwfilters->objs, virNWFilterObjListCopyNames, &data);
+    virObjectRWUnlock(nwfilters);
+    if (data.oom) {
+        for (i = 0; i < data.numnames; i++)
+            VIR_FREE(data.names[i]);
+        return -1;
+    }
+
+    return data.numnames;
+}
+
+
+struct virNWFilterListData {
+    virConnectPtr conn;
+    virNWFilterPtr *nwfilters;
+    virNWFilterObjListFilter filter;
+    int nnwfilters;
+    bool error;
+};
+
+
+static int
+virNWFilterObjListPopulate(void *payload,
+                           const void *name ATTRIBUTE_UNUSED,
+                           void *opaque)
+{
+    struct virNWFilterListData *data = opaque;
+    virNWFilterObjPtr obj = payload;
+    virNWFilterPtr nwfilter = NULL;
+
+    if (data->error)
+        return 0;
+
+    virObjectLock(obj);
+
+    if (data->filter &&
+        !data->filter(data->conn, obj->def))
+        goto cleanup;
+
+    if (!data->nwfilters) {
+        data->nnwfilters++;
+        goto cleanup;
      }

-    return nnames;
+    if (!(nwfilter = virGetNWFilter(data->conn, obj->def->name, obj->def->uuid))) {
+        data->error = true;
+        goto cleanup;
+    }

- failure:
-    while (--nnames >= 0)
-        VIR_FREE(names[nnames]);
+    data->nwfilters[data->nnwfilters++] = nwfilter;

-    return -1;
+ cleanup:
+    virObjectUnlock(obj);
+    return 0;
  }


@@ -464,47 +619,33 @@ virNWFilterObjListExport(virConnectPtr conn,
                           virNWFilterPtr **filters,
                           virNWFilterObjListFilter filter)
  {
-    virNWFilterPtr *tmp_filters = NULL;
-    int nfilters = 0;
-    virNWFilterPtr nwfilter = NULL;
-    virNWFilterObjPtr obj = NULL;
-    virNWFilterDefPtr def;
-    size_t i;
      int ret = -1;
+    struct virNWFilterListData data = {.conn = conn, .nwfilters = NULL,
+        .filter = filter, .nnwfilters = 0, .error = false};

-    if (!filters) {
-        ret = nwfilters->count;
+    virObjectRWLockRead(nwfilters);
+    if (filters && VIR_ALLOC_N(data.nwfilters, virHashSize(nwfilters->objs) + 1) < 0)
          goto cleanup;
-    }

-    if (VIR_ALLOC_N(tmp_filters, nwfilters->count + 1) < 0)
+    virHashForEach(nwfilters->objs, virNWFilterObjListPopulate, &data);
+
+    if (data.error)
          goto cleanup;

-    for (i = 0; i < nwfilters->count; i++) {
-        obj = nwfilters->objs[i];
-        virObjectLock(obj);
-        def = obj->def;
-        if (!filter || filter(conn, def)) {
-            if (!(nwfilter = virGetNWFilter(conn, def->name, def->uuid))) {
-                virObjectUnlock(obj);
-                goto cleanup;
-            }
-            tmp_filters[nfilters++] = nwfilter;
-        }
-        virObjectUnlock(obj);
+    if (data.nnwfilters) {
+        /* trim the array to the final size */
+        ignore_value(VIR_REALLOC_N(data.nwfilters, data.nnwfilters + 1));
+        *filters = data.nwfilters;
+        data.nwfilters = NULL;
      }

-    *filters = tmp_filters;
-    tmp_filters = NULL;
-    ret = nfilters;
-
+    ret = data.nnwfilters;
   cleanup:
-    if (tmp_filters) {
-        for (i = 0; i < nfilters; i ++)
-            virObjectUnref(tmp_filters[i]);
-    }
-    VIR_FREE(tmp_filters);
+    virObjectRWUnlock(nwfilters);
+    while (data.nwfilters && data.nnwfilters)
+        virObjectUnref(data.nwfilters[--data.nnwfilters]);

+    VIR_FREE(data.nwfilters);
      return ret;
  }

diff --git a/src/conf/virnwfilterobj.h b/src/conf/virnwfilterobj.h
index 0281bc5f5..caff76e9a 100644
--- a/src/conf/virnwfilterobj.h
+++ b/src/conf/virnwfilterobj.h
@@ -56,9 +56,6 @@ virNWFilterObjWantRemoved(virNWFilterObjPtr obj);
  virNWFilterObjListPtr
  virNWFilterObjListNew(void);

-void
-virNWFilterObjListFree(virNWFilterObjListPtr nwfilters);
-
  void
  virNWFilterObjListRemove(virNWFilterObjListPtr nwfilters,
                           virNWFilterObjPtr obj);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index edda56f80..fe63defb3 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1047,7 +1047,6 @@ virNWFilterObjListExport;
  virNWFilterObjListFindByName;
  virNWFilterObjListFindByUUID;
  virNWFilterObjListFindInstantiateFilter;
-virNWFilterObjListFree;
  virNWFilterObjListGetNames;
  virNWFilterObjListLoadAllConfigs;
  virNWFilterObjListNew;
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index c9bbae422..093844c9e 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -270,7 +270,7 @@ nwfilterStateInitialize(bool privileged,
      virNWFilterIPAddrMapShutdown();

   err_free_driverstate:
-    virNWFilterObjListFree(driver->nwfilters);
+    virObjectUnref(driver->nwfilters);
      VIR_FREE(driver);

      return -1;
@@ -354,7 +354,7 @@ nwfilterStateCleanup(void)
      }

      /* free inactive nwfilters */
-    virNWFilterObjListFree(driver->nwfilters);
+    virObjectUnref(driver->nwfilters);

      virMutexDestroy(&driver->lock);
      VIR_FREE(driver);



--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux