[PATCH v2 2/8] util: Introduce and use virObjectRWLockWrite

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

 



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@xxxxxxxxxx>
---
 src/conf/virdomainobjlist.c |  8 ++++----
 src/libvirt_private.syms    |  1 +
 src/util/virobject.c        | 33 ++++++++++++++++++++++++++++++++-
 src/util/virobject.h        |  4 ++++
 4 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c
index 9bc6603..573032f 100644
--- a/src/conf/virdomainobjlist.c
+++ b/src/conf/virdomainobjlist.c
@@ -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;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 99302d2..7f2f6d6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2309,6 +2309,7 @@ virObjectNew;
 virObjectRef;
 virObjectRWLockableNew;
 virObjectRWLockRead;
+virObjectRWLockWrite;
 virObjectUnlock;
 virObjectUnref;
 
diff --git a/src/util/virobject.c b/src/util/virobject.c
index b97f251..f49af62 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -430,11 +430,42 @@ 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)
diff --git a/src/util/virobject.h b/src/util/virobject.h
index e7ca983..24ee6dd 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -129,6 +129,10 @@ virObjectRWLockRead(void *lockableobj)
     ATTRIBUTE_NONNULL(1);
 
 void
+virObjectRWLockWrite(void *lockableobj)
+    ATTRIBUTE_NONNULL(1);
+
+void
 virObjectUnlock(void *lockableobj)
     ATTRIBUTE_NONNULL(1);
 
-- 
2.9.4

--
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