]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Add a virObjectLockable class holding a mutex
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 9 Jan 2013 17:54:07 +0000 (17:54 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 15 Jan 2013 19:21:33 +0000 (19:21 +0000)
A great many virObject instances require a mutex, so introduce
a convenient class for this which provides a mutex. This avoids
repeating the tedious init/destroy code

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/libvirt_private.syms
src/util/virobject.c
src/util/virobject.h

index 70c1591074495e856a9f66dabc52ef281922517e..1ace1a1822495209652e6f1ba4e472023738597d 100644 (file)
@@ -1770,13 +1770,17 @@ virNodeSuspendGetTargetMask;
 
 # virobject.h
 virClassForObject;
+virClassForObjectLockable;
 virClassIsDerivedFrom;
 virClassName;
 virClassNew;
 virObjectFreeCallback;
 virObjectIsClass;
+virObjectLock;
+virObjectLockableNew;
 virObjectNew;
 virObjectRef;
+virObjectUnlock;
 virObjectUnref;
 
 
index 5f44ab2d6d5b6632d61d641ae02d7ce18a482a1c..838b5cd46872c05ff18c8a77970eef1c8d49854f 100644 (file)
@@ -43,6 +43,9 @@ struct _virClass {
 };
 
 static virClassPtr virObjectClass;
+static virClassPtr virObjectLockableClass;
+
+static void virObjectLockableDispose(void *anyobj);
 
 static int virObjectOnceInit(void)
 {
@@ -52,6 +55,12 @@ static int virObjectOnceInit(void)
                                        NULL)))
         return -1;
 
+    if (!(virObjectLockableClass = virClassNew(virObjectClass,
+                                               "virObjectLockable",
+                                               sizeof(virObjectLockable),
+                                               virObjectLockableDispose)))
+        return -1;
+
     return 0;
 }
 
@@ -72,6 +81,20 @@ virClassPtr virClassForObject(void)
 }
 
 
+/**
+ * virClassForObjectLockable:
+ *
+ * Returns the class instance for the virObjectLockable type
+ */
+virClassPtr virClassForObjectLockable(void)
+{
+    if (!virObjectInitialize() < 0)
+        return NULL;
+
+    return virObjectLockableClass;
+}
+
+
 /**
  * virClassNew:
  * @parent: the parent class
@@ -180,6 +203,38 @@ void *virObjectNew(virClassPtr klass)
 }
 
 
+void *virObjectLockableNew(virClassPtr klass)
+{
+    virObjectLockablePtr obj;
+
+    if (!virClassIsDerivedFrom(klass, virClassForObjectLockable())) {
+        virReportInvalidArg(klass,
+                            _("Class %s must derive from virObjectLockable"),
+                            virClassName(klass));
+        return NULL;
+    }
+
+    if (!(obj = virObjectNew(klass)))
+        return NULL;
+
+    if (virMutexInit(&obj->lock) < 0) {
+        virReportSystemError(VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("Unable to initialize mutex"));
+        virObjectUnref(obj);
+        return NULL;
+    }
+
+    return obj;
+}
+
+
+static void virObjectLockableDispose(void *anyobj)
+{
+    virObjectLockablePtr obj = anyobj;
+
+    virMutexDestroy(&obj->lock);
+}
+
 /**
  * virObjectUnref:
  * @anyobj: any instance of virObjectPtr
@@ -209,8 +264,6 @@ bool virObjectUnref(void *anyobj)
             klass = klass->parent;
         }
 
-        virMutexDestroy(&obj->lock);
-
         /* Clear & poison object */
         memset(obj, 0, obj->klass->objectSize);
         obj->magic = 0xDEADBEEF;
@@ -243,6 +296,53 @@ void *virObjectRef(void *anyobj)
 }
 
 
+/**
+ * virObjectLock:
+ * @anyobj: any instance of virObjectLockablePtr
+ *
+ * Acquire a 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.
+ */
+void virObjectLock(void *anyobj)
+{
+    virObjectLockablePtr obj = anyobj;
+
+    if (!virObjectIsClass(obj, virObjectLockableClass)) {
+        VIR_WARN("Object %p (%s) is not a virObjectLockable instance",
+                 obj, obj ? obj->parent.klass->name : "(unknown)");
+        return;
+    }
+
+    virMutexLock(&obj->lock);
+}
+
+
+/**
+ * virObjectUnlock:
+ * @anyobj: any instance of virObjectLockablePtr
+ *
+ * Release a lock on @anyobj. The lock must have been
+ * acquired by virObjectLock.
+ */
+void virObjectUnlock(void *anyobj)
+{
+    virObjectLockablePtr obj = anyobj;
+
+    if (!virObjectIsClass(obj, virObjectLockableClass)) {
+        VIR_WARN("Object %p (%s) is not a virObjectLockable instance",
+                 obj, obj ? obj->parent.klass->name : "(unknown)");
+        return;
+    }
+
+    virMutexUnlock(&obj->lock);
+}
+
+
 /**
  * virObjectIsClass:
  * @anyobj: any instance of virObjectPtr
index afeb4f56266bb2eed7eea7bb5801e05a532a7c51..bb72a25bc37e56f20ad57289567f7fdc5e5d43d4 100644 (file)
@@ -23,6 +23,7 @@
 # define __VIR_OBJECT_H__
 
 # include "internal.h"
+# include "virthread.h"
 
 typedef struct _virClass virClass;
 typedef virClass *virClassPtr;
@@ -30,6 +31,9 @@ typedef virClass *virClassPtr;
 typedef struct _virObject virObject;
 typedef virObject *virObjectPtr;
 
+typedef struct _virObjectLockable virObjectLockable;
+typedef virObjectLockable *virObjectLockablePtr;
+
 typedef void (*virObjectDisposeCallback)(void *obj);
 
 struct _virObject {
@@ -38,7 +42,14 @@ struct _virObject {
     virClassPtr klass;
 };
 
+struct _virObjectLockable {
+    virObject parent;
+    virMutex lock;
+};
+
+
 virClassPtr virClassForObject(void);
+virClassPtr virClassForObjectLockable(void);
 
 virClassPtr virClassNew(virClassPtr parent,
                         const char *name,
@@ -64,4 +75,13 @@ bool virObjectIsClass(void *obj,
 
 void virObjectFreeCallback(void *opaque);
 
+void *virObjectLockableNew(virClassPtr klass)
+    ATTRIBUTE_NONNULL(1);
+
+void virObjectLock(void *lockableobj)
+    ATTRIBUTE_NONNULL(1);
+void virObjectUnlock(void *lockableobj)
+    ATTRIBUTE_NONNULL(1);
+
+
 #endif /* __VIR_OBJECT_H */