提交 b545f65d 编写于 作者: D Daniel P. Berrange

Add a virObjectLockable class holding a mutex

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: NDaniel P. Berrange <berrange@redhat.com>
上级 69218922
...@@ -1770,13 +1770,17 @@ virNodeSuspendGetTargetMask; ...@@ -1770,13 +1770,17 @@ virNodeSuspendGetTargetMask;
# virobject.h # virobject.h
virClassForObject; virClassForObject;
virClassForObjectLockable;
virClassIsDerivedFrom; virClassIsDerivedFrom;
virClassName; virClassName;
virClassNew; virClassNew;
virObjectFreeCallback; virObjectFreeCallback;
virObjectIsClass; virObjectIsClass;
virObjectLock;
virObjectLockableNew;
virObjectNew; virObjectNew;
virObjectRef; virObjectRef;
virObjectUnlock;
virObjectUnref; virObjectUnref;
......
...@@ -43,6 +43,9 @@ struct _virClass { ...@@ -43,6 +43,9 @@ struct _virClass {
}; };
static virClassPtr virObjectClass; static virClassPtr virObjectClass;
static virClassPtr virObjectLockableClass;
static void virObjectLockableDispose(void *anyobj);
static int virObjectOnceInit(void) static int virObjectOnceInit(void)
{ {
...@@ -52,6 +55,12 @@ static int virObjectOnceInit(void) ...@@ -52,6 +55,12 @@ static int virObjectOnceInit(void)
NULL))) NULL)))
return -1; return -1;
if (!(virObjectLockableClass = virClassNew(virObjectClass,
"virObjectLockable",
sizeof(virObjectLockable),
virObjectLockableDispose)))
return -1;
return 0; return 0;
} }
...@@ -72,6 +81,20 @@ virClassPtr virClassForObject(void) ...@@ -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: * virClassNew:
* @parent: the parent class * @parent: the parent class
...@@ -180,6 +203,38 @@ void *virObjectNew(virClassPtr klass) ...@@ -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: * virObjectUnref:
* @anyobj: any instance of virObjectPtr * @anyobj: any instance of virObjectPtr
...@@ -209,8 +264,6 @@ bool virObjectUnref(void *anyobj) ...@@ -209,8 +264,6 @@ bool virObjectUnref(void *anyobj)
klass = klass->parent; klass = klass->parent;
} }
virMutexDestroy(&obj->lock);
/* Clear & poison object */ /* Clear & poison object */
memset(obj, 0, obj->klass->objectSize); memset(obj, 0, obj->klass->objectSize);
obj->magic = 0xDEADBEEF; obj->magic = 0xDEADBEEF;
...@@ -243,6 +296,53 @@ void *virObjectRef(void *anyobj) ...@@ -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: * virObjectIsClass:
* @anyobj: any instance of virObjectPtr * @anyobj: any instance of virObjectPtr
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
# define __VIR_OBJECT_H__ # define __VIR_OBJECT_H__
# include "internal.h" # include "internal.h"
# include "virthread.h"
typedef struct _virClass virClass; typedef struct _virClass virClass;
typedef virClass *virClassPtr; typedef virClass *virClassPtr;
...@@ -30,6 +31,9 @@ typedef virClass *virClassPtr; ...@@ -30,6 +31,9 @@ typedef virClass *virClassPtr;
typedef struct _virObject virObject; typedef struct _virObject virObject;
typedef virObject *virObjectPtr; typedef virObject *virObjectPtr;
typedef struct _virObjectLockable virObjectLockable;
typedef virObjectLockable *virObjectLockablePtr;
typedef void (*virObjectDisposeCallback)(void *obj); typedef void (*virObjectDisposeCallback)(void *obj);
struct _virObject { struct _virObject {
...@@ -38,7 +42,14 @@ struct _virObject { ...@@ -38,7 +42,14 @@ struct _virObject {
virClassPtr klass; virClassPtr klass;
}; };
struct _virObjectLockable {
virObject parent;
virMutex lock;
};
virClassPtr virClassForObject(void); virClassPtr virClassForObject(void);
virClassPtr virClassForObjectLockable(void);
virClassPtr virClassNew(virClassPtr parent, virClassPtr virClassNew(virClassPtr parent,
const char *name, const char *name,
...@@ -64,4 +75,13 @@ bool virObjectIsClass(void *obj, ...@@ -64,4 +75,13 @@ bool virObjectIsClass(void *obj,
void virObjectFreeCallback(void *opaque); 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 */ #endif /* __VIR_OBJECT_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册