From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list