]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: Introduce and use virObjectRWLockWrite
authorJohn Ferlan <jferlan@redhat.com>
Fri, 28 Jul 2017 14:06:55 +0000 (10:06 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Tue, 15 Aug 2017 01:41:59 +0000 (21:41 -0400)
Instead of making virObjectLock be the entry point for two
different types of locks, let's create a virObjectRWLockWrite API
which will only handle the virObjectRWLockableClass objects.

Use the new virObjectRWLockWrite for the virdomainobjlist code
in order to handle the Add, Remove, Rename, and Load operations
that need to be very synchronous.

Signed-off-by: John Ferlan <jferlan@redhat.com>
src/conf/virdomainobjlist.c
src/libvirt_private.syms
src/util/virobject.c
src/util/virobject.h

index 9bc6603353b9eb4b58aa5834dbdd9c9369ebaf12..573032f14be5dc37d815b584b41125f5a0164bc3 100644 (file)
@@ -327,7 +327,7 @@ virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms,
 {
     virDomainObjPtr ret;
 
-    virObjectLock(doms);
+    virObjectRWLockWrite(doms);
     ret = virDomainObjListAddLocked(doms, def, xmlopt, flags, oldDef);
     virObjectUnlock(doms);
     return ret;
@@ -349,7 +349,7 @@ void virDomainObjListRemove(virDomainObjListPtr doms,
     virObjectRef(dom);
     virObjectUnlock(dom);
 
-    virObjectLock(doms);
+    virObjectRWLockWrite(doms);
     virObjectLock(dom);
     virHashRemoveEntry(doms->objs, uuidstr);
     virHashRemoveEntry(doms->objsName, dom->def->name);
@@ -394,7 +394,7 @@ virDomainObjListRename(virDomainObjListPtr doms,
      * hold a lock on dom but not refcount it. */
     virObjectRef(dom);
     virObjectUnlock(dom);
-    virObjectLock(doms);
+    virObjectRWLockWrite(doms);
     virObjectLock(dom);
     virObjectUnref(dom);
 
@@ -573,7 +573,7 @@ virDomainObjListLoadAllConfigs(virDomainObjListPtr doms,
     if ((rc = virDirOpenIfExists(&dir, configDir)) <= 0)
         return rc;
 
-    virObjectLock(doms);
+    virObjectRWLockWrite(doms);
 
     while ((ret = virDirRead(dir, &entry, configDir)) > 0) {
         virDomainObjPtr dom;
index b5fc31a64f6f0a9a9af920c0a6988bec12a42097..01a2f3a814db23de89060b8c3e3fbd97f83e867c 100644 (file)
@@ -2312,6 +2312,7 @@ virObjectNew;
 virObjectRef;
 virObjectRWLockableNew;
 virObjectRWLockRead;
+virObjectRWLockWrite;
 virObjectUnlock;
 virObjectUnref;
 
index b97f251afd0670f591ca720263b538f0a87d5c3d..f49af62c81f52096574ae1ece311a2957495dc7c 100644 (file)
@@ -429,12 +429,43 @@ virObjectRWLockRead(void *anyobj)
 }
 
 
+/**
+ * virObjectRWLockWrite:
+ * @anyobj: any instance of virObjectRWLockable
+ *
+ * Acquire a write lock on @anyobj. The lock must be
+ * released by virObjectUnlock.
+ *
+ * The caller is expected to have acquired a reference
+ * on the object before locking it (eg virObjectRef).
+ * The object must be unlocked before releasing this
+ * reference.
+ *
+ * NB: It's possible to return without the lock if
+ *     @anyobj was invalid - this has been considered
+ *     a programming error rather than something that
+ *     should be checked.
+ */
+void
+virObjectRWLockWrite(void *anyobj)
+{
+    if (virObjectIsClass(anyobj, virObjectRWLockableClass)) {
+        virObjectRWLockablePtr obj = anyobj;
+        virRWLockWrite(&obj->lock);
+    } else {
+        virObjectPtr obj = anyobj;
+        VIR_WARN("Object %p (%s) is not a virObjectRWLockable instance",
+                 anyobj, obj ? obj->klass->name : "(unknown)");
+    }
+}
+
+
 /**
  * virObjectUnlock:
  * @anyobj: any instance of virObjectLockable or virObjectRWLockable
  *
  * Release a lock on @anyobj. The lock must have been acquired by
- * virObjectLock or virObjectRWLockRead.
+ * virObjectLock, virObjectRWLockRead, or virObjectRWLockWrite.
  */
 void
 virObjectUnlock(void *anyobj)
index e7ca983921f38522aa96083dd938e9a900f9c094..24ee6dda8b2a35bca5e386cfbb4ea0769ce53225 100644 (file)
@@ -128,6 +128,10 @@ void
 virObjectRWLockRead(void *lockableobj)
     ATTRIBUTE_NONNULL(1);
 
+void
+virObjectRWLockWrite(void *lockableobj)
+    ATTRIBUTE_NONNULL(1);
+
 void
 virObjectUnlock(void *lockableobj)
     ATTRIBUTE_NONNULL(1);