};
static virClassPtr virObjectClass;
+static virClassPtr virObjectLockableClass;
+
+static void virObjectLockableDispose(void *anyobj);
static int virObjectOnceInit(void)
{
NULL)))
return -1;
+ if (!(virObjectLockableClass = virClassNew(virObjectClass,
+ "virObjectLockable",
+ sizeof(virObjectLockable),
+ virObjectLockableDispose)))
+ return -1;
+
return 0;
}
}
+/**
+ * virClassForObjectLockable:
+ *
+ * Returns the class instance for the virObjectLockable type
+ */
+virClassPtr virClassForObjectLockable(void)
+{
+ if (!virObjectInitialize() < 0)
+ return NULL;
+
+ return virObjectLockableClass;
+}
+
+
/**
* virClassNew:
* @parent: the parent class
}
+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
klass = klass->parent;
}
- virMutexDestroy(&obj->lock);
-
/* Clear & poison object */
memset(obj, 0, obj->klass->objectSize);
obj->magic = 0xDEADBEEF;
}
+/**
+ * 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
# define __VIR_OBJECT_H__
# include "internal.h"
+# include "virthread.h"
typedef struct _virClass virClass;
typedef virClass *virClassPtr;
typedef struct _virObject virObject;
typedef virObject *virObjectPtr;
+typedef struct _virObjectLockable virObjectLockable;
+typedef virObjectLockable *virObjectLockablePtr;
+
typedef void (*virObjectDisposeCallback)(void *obj);
struct _virObject {
virClassPtr klass;
};
+struct _virObjectLockable {
+ virObject parent;
+ virMutex lock;
+};
+
+
virClassPtr virClassForObject(void);
+virClassPtr virClassForObjectLockable(void);
virClassPtr virClassNew(virClassPtr parent,
const char *name,
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 */