From: "Daniel P. Berrange" <berrange(a)redhat.com>
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
---
src/libvirt_private.syms | 4 +++
src/util/virobject.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++--
src/util/virobject.h | 20 +++++++++++
3 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 092cb59..f02aee4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1768,13 +1768,17 @@ virNodeSuspendGetTargetMask;
# virobject.h
virClassForObject;
+virClassForObjectLockable;
virClassIsDerivedFrom;
virClassName;
virClassNew;
virObjectFreeCallback;
virObjectIsClass;
+virObjectLock;
+virObjectLockableNew;
virObjectNew;
virObjectRef;
+virObjectUnlock;
virObjectUnref;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 5f44ab2..d5bef11 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -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;
}
@@ -73,6 +82,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
* @name: the class name
@@ -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;
@@ -244,6 +297,36 @@ void *virObjectRef(void *anyobj)
/**
+ * virObjectLock:
+ * @anyobj: any instance of virObjectLockablePtr
+ *
+ * Acquire a lock on @anyobj. The lock must be
+ * released by virObjectUnlock.
+ */
+void virObjectLock(void *anyobj)
+{
+ virObjectLockablePtr obj = anyobj;
+
+ 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;
+
+ virMutexUnlock(&obj->lock);
+}
+
+
+/**
* virObjectIsClass:
* @anyobj: any instance of virObjectPtr
* @klass: the class to check
diff --git a/src/util/virobject.h b/src/util/virobject.h
index afeb4f5..bb72a25 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -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 */
--
1.8.0.1