Every API that touches internal structure of the object must lock
the object first. Not every API that has the object as an
argument needs to do that though. Some APIs just pass the object
to lower layers, which, however, must lock the object then. Look
at the code, you'll get my meaning soon.

Signed-off-by: Michal Privoznik <mpriv...@redhat.com>
---
 src/conf/network_conf.c | 39 +++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 95d8b4d..5b0f36f 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -156,31 +156,41 @@ virNetworkObjListPtr virNetworkObjListNew(void)
 virNetworkObjPtr virNetworkObjFindByUUID(virNetworkObjListPtr nets,
                                          const unsigned char *uuid)
 {
+    virNetworkObjPtr ret = NULL;
     size_t i;
 
+    virObjectLock(nets);
     for (i = 0; i < nets->count; i++) {
         virObjectLock(nets->objs[i]);
-        if (!memcmp(nets->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
-            return nets->objs[i];
+        if (!memcmp(nets->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN)) {
+            ret = nets->objs[i];
+            break;
+        }
         virObjectUnlock(nets->objs[i]);
     }
+    virObjectUnlock(nets);
 
-    return NULL;
+    return ret;
 }
 
 virNetworkObjPtr virNetworkObjFindByName(virNetworkObjListPtr nets,
                                          const char *name)
 {
+    virNetworkObjPtr ret = NULL;
     size_t i;
 
+    virObjectLock(nets);
     for (i = 0; i < nets->count; i++) {
         virObjectLock(nets->objs[i]);
-        if (STREQ(nets->objs[i]->def->name, name))
-            return nets->objs[i];
+        if (STREQ(nets->objs[i]->def->name, name)) {
+            ret = nets->objs[i];
+            break;
+        }
         virObjectUnlock(nets->objs[i]);
     }
+    virObjectUnlock(nets);
 
-    return NULL;
+    return ret;
 }
 
 bool
@@ -453,14 +463,17 @@ virNetworkAssignDef(virNetworkObjListPtr nets,
         return NULL;
     virObjectLock(network);
 
+    virObjectLock(nets);
     if (VIR_APPEND_ELEMENT_COPY(nets->objs, nets->count, network) < 0)
         goto error;
 
     network->def = def;
     network->persistent = !live;
+    virObjectUnlock(nets);
     return network;
 
  error:
+    virObjectUnlock(nets);
     virObjectUnlock(network);
     virObjectUnref(network);
     return NULL;
@@ -631,6 +644,7 @@ void virNetworkRemoveInactive(virNetworkObjListPtr nets,
     size_t i;
 
     virObjectUnlock(net);
+    virObjectLock(nets);
     for (i = 0; i < nets->count; i++) {
         virObjectLock(nets->objs[i]);
         if (nets->objs[i] == net) {
@@ -642,6 +656,7 @@ void virNetworkRemoveInactive(virNetworkObjListPtr nets,
         }
         virObjectUnlock(nets->objs[i]);
     }
+    virObjectUnlock(nets);
 }
 
 /* return ips[index], or NULL if there aren't enough ips */
@@ -3137,6 +3152,7 @@ int virNetworkBridgeInUse(virNetworkObjListPtr nets,
     size_t i;
     unsigned int ret = 0;
 
+    virObjectLock(nets);
     for (i = 0; i < nets->count; i++) {
         virObjectLock(nets->objs[i]);
         if (nets->objs[i]->def->bridge &&
@@ -3145,6 +3161,7 @@ int virNetworkBridgeInUse(virNetworkObjListPtr nets,
                 ret = 1;
         virObjectUnlock(nets->objs[i]);
     }
+    virObjectUnlock(nets);
 
     return ret;
 }
@@ -4304,6 +4321,7 @@ virNetworkObjListExport(virConnectPtr conn,
     if (nets && VIR_ALLOC_N(tmp_nets, netobjs->count + 1) < 0)
         goto cleanup;
 
+    virObjectLock(netobjs);
     for (i = 0; i < netobjs->count; i++) {
         virNetworkObjPtr netobj = netobjs->objs[i];
         virObjectLock(netobj);
@@ -4314,6 +4332,7 @@ virNetworkObjListExport(virConnectPtr conn,
                                           netobj->def->name,
                                           netobj->def->uuid))) {
                     virObjectUnlock(netobj);
+                    virObjectUnlock(netobjs);
                     goto cleanup;
                 }
                 tmp_nets[nnets] = net;
@@ -4322,6 +4341,7 @@ virNetworkObjListExport(virConnectPtr conn,
         }
         virObjectUnlock(netobj);
     }
+    virObjectUnlock(netobjs);
 
     if (tmp_nets) {
         /* trim the array to the final size */
@@ -4353,6 +4373,7 @@ virNetworkObjListForEach(virNetworkObjListPtr nets,
     /* Deliberately don't use for-loop here. We want to allow
      * @callback to remove a network object, in which case
      * nets->count is decremented. */
+    virObjectLock(nets);
     while (i < nets->count) {
         oldcount = nets->count;
         if (callback(nets->objs[i], opaque) < 0)
@@ -4360,6 +4381,7 @@ virNetworkObjListForEach(virNetworkObjListPtr nets,
         if (oldcount == nets->count)
             i++;
     }
+    virObjectUnlock(nets);
 
     return ret;
 }
@@ -4375,6 +4397,7 @@ virNetworkObjListGetNames(virNetworkObjListPtr nets,
     int got = 0;
     size_t i;
 
+    virObjectLock(nets);
     for (i = 0; i < nets->count && got < nnames; i++) {
         virNetworkObjPtr obj = nets->objs[i];
         virObjectLock(obj);
@@ -4387,12 +4410,14 @@ virNetworkObjListGetNames(virNetworkObjListPtr nets,
             (!active && !virNetworkObjIsActive(obj))) {
             if (VIR_STRDUP(names[got], obj->def->name) < 0) {
                 virObjectUnlock(obj);
+                virObjectUnlock(nets);
                 goto error;
             }
             got++;
         }
         virObjectUnlock(obj);
     }
+    virObjectUnlock(nets);
 
     return got;
 
@@ -4411,6 +4436,7 @@ virNetworkObjListNumOfNetworks(virNetworkObjListPtr nets,
     int count = 0;
     size_t i;
 
+    virObjectLock(nets);
     for (i = 0; i < nets->count; i++) {
         virNetworkObjPtr obj = nets->objs[i];
         virObjectLock(obj);
@@ -4424,6 +4450,7 @@ virNetworkObjListNumOfNetworks(virNetworkObjListPtr nets,
             count++;
         virObjectUnlock(obj);
     }
+    virObjectUnlock(nets);
 
     return count;
 }
-- 
2.0.5

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

Reply via email to