mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 11:01:19 +00:00
Allow for multi-level inheritance of virObject classes
Currently all classes must directly inherit from virObject. This allows for arbitrarily deep hierarchy. There's not much to this aside from chaining up the 'dispose' handlers from each class & providing APIs to check types. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
e397f658b0
commit
69218922e8
@ -165,6 +165,7 @@ src/util/virnetdevtap.c
|
|||||||
src/util/virnetdevvportprofile.c
|
src/util/virnetdevvportprofile.c
|
||||||
src/util/virnetlink.c
|
src/util/virnetlink.c
|
||||||
src/util/virnodesuspend.c
|
src/util/virnodesuspend.c
|
||||||
|
src/util/virobject.c
|
||||||
src/util/virpci.c
|
src/util/virpci.c
|
||||||
src/util/virpidfile.c
|
src/util/virpidfile.c
|
||||||
src/util/virprocess.c
|
src/util/virprocess.c
|
||||||
|
@ -700,7 +700,8 @@ static void virDomainObjDispose(void *obj);
|
|||||||
|
|
||||||
static int virDomainObjOnceInit(void)
|
static int virDomainObjOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virDomainObjClass = virClassNew("virDomainObj",
|
if (!(virDomainObjClass = virClassNew(virClassForObject(),
|
||||||
|
"virDomainObj",
|
||||||
sizeof(virDomainObj),
|
sizeof(virDomainObj),
|
||||||
virDomainObjDispose)))
|
virDomainObjDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -64,7 +64,8 @@ static int
|
|||||||
virDataTypesOnceInit(void)
|
virDataTypesOnceInit(void)
|
||||||
{
|
{
|
||||||
#define DECLARE_CLASS(basename) \
|
#define DECLARE_CLASS(basename) \
|
||||||
if (!(basename ## Class = virClassNew(#basename, \
|
if (!(basename ## Class = virClassNew(virClassForObject(), \
|
||||||
|
#basename, \
|
||||||
sizeof(basename), \
|
sizeof(basename), \
|
||||||
basename ## Dispose))) \
|
basename ## Dispose))) \
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1769,6 +1769,8 @@ virNodeSuspendGetTargetMask;
|
|||||||
|
|
||||||
|
|
||||||
# virobject.h
|
# virobject.h
|
||||||
|
virClassForObject;
|
||||||
|
virClassIsDerivedFrom;
|
||||||
virClassName;
|
virClassName;
|
||||||
virClassNew;
|
virClassNew;
|
||||||
virObjectFreeCallback;
|
virObjectFreeCallback;
|
||||||
|
@ -50,7 +50,8 @@ static void virLXCMonitorDispose(void *obj);
|
|||||||
|
|
||||||
static int virLXCMonitorOnceInit(void)
|
static int virLXCMonitorOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virLXCMonitorClass = virClassNew("virLXCMonitor",
|
if (!(virLXCMonitorClass = virClassNew(virClassForObject(),
|
||||||
|
"virLXCMonitor",
|
||||||
sizeof(virLXCMonitor),
|
sizeof(virLXCMonitor),
|
||||||
virLXCMonitorDispose)))
|
virLXCMonitorDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -121,7 +121,8 @@ static void qemuAgentDispose(void *obj);
|
|||||||
|
|
||||||
static int qemuAgentOnceInit(void)
|
static int qemuAgentOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(qemuAgentClass = virClassNew("qemuAgent",
|
if (!(qemuAgentClass = virClassNew(virClassForObject(),
|
||||||
|
"qemuAgent",
|
||||||
sizeof(qemuAgent),
|
sizeof(qemuAgent),
|
||||||
qemuAgentDispose)))
|
qemuAgentDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -244,7 +244,8 @@ static void qemuCapsDispose(void *obj);
|
|||||||
|
|
||||||
static int qemuCapsOnceInit(void)
|
static int qemuCapsOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(qemuCapsClass = virClassNew("qemuCaps",
|
if (!(qemuCapsClass = virClassNew(virClassForObject(),
|
||||||
|
"qemuCaps",
|
||||||
sizeof(qemuCaps),
|
sizeof(qemuCaps),
|
||||||
qemuCapsDispose)))
|
qemuCapsDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -86,9 +86,10 @@ static void qemuMonitorDispose(void *obj);
|
|||||||
|
|
||||||
static int qemuMonitorOnceInit(void)
|
static int qemuMonitorOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(qemuMonitorClass = virClassNew("qemuMonitor",
|
if (!(qemuMonitorClass = virClassNew(virClassForObject(),
|
||||||
sizeof(qemuMonitor),
|
"qemuMonitor",
|
||||||
qemuMonitorDispose)))
|
sizeof(qemuMonitor),
|
||||||
|
qemuMonitorDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -58,7 +58,8 @@ static void virKeepAliveDispose(void *obj);
|
|||||||
|
|
||||||
static int virKeepAliveOnceInit(void)
|
static int virKeepAliveOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virKeepAliveClass = virClassNew("virKeepAlive",
|
if (!(virKeepAliveClass = virClassNew(virClassForObject(),
|
||||||
|
"virKeepAlive",
|
||||||
sizeof(virKeepAlive),
|
sizeof(virKeepAlive),
|
||||||
virKeepAliveDispose)))
|
virKeepAliveDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -117,7 +117,8 @@ static void virNetClientDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetClientOnceInit(void)
|
static int virNetClientOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetClientClass = virClassNew("virNetClient",
|
if (!(virNetClientClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetClient",
|
||||||
sizeof(virNetClient),
|
sizeof(virNetClient),
|
||||||
virNetClientDispose)))
|
virNetClientDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -52,7 +52,8 @@ static void virNetClientProgramDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetClientProgramOnceInit(void)
|
static int virNetClientProgramOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetClientProgramClass = virClassNew("virNetClientProgram",
|
if (!(virNetClientProgramClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetClientProgram",
|
||||||
sizeof(virNetClientProgram),
|
sizeof(virNetClientProgram),
|
||||||
virNetClientProgramDispose)))
|
virNetClientProgramDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -68,7 +68,8 @@ static void virNetClientStreamDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetClientStreamOnceInit(void)
|
static int virNetClientStreamOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetClientStreamClass = virClassNew("virNetClientStream",
|
if (!(virNetClientStreamClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetClientStream",
|
||||||
sizeof(virNetClientStream),
|
sizeof(virNetClientStream),
|
||||||
virNetClientStreamDispose)))
|
virNetClientStreamDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -55,12 +55,14 @@ static void virNetSASLSessionDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetSASLContextOnceInit(void)
|
static int virNetSASLContextOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetSASLContextClass = virClassNew("virNetSASLContext",
|
if (!(virNetSASLContextClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetSASLContext",
|
||||||
sizeof(virNetSASLContext),
|
sizeof(virNetSASLContext),
|
||||||
virNetSASLContextDispose)))
|
virNetSASLContextDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(virNetSASLSessionClass = virClassNew("virNetSASLSession",
|
if (!(virNetSASLSessionClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetSASLSession",
|
||||||
sizeof(virNetSASLSession),
|
sizeof(virNetSASLSession),
|
||||||
virNetSASLSessionDispose)))
|
virNetSASLSessionDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -119,7 +119,8 @@ static void virNetServerDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetServerOnceInit(void)
|
static int virNetServerOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetServerClass = virClassNew("virNetServer",
|
if (!(virNetServerClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetServer",
|
||||||
sizeof(virNetServer),
|
sizeof(virNetServer),
|
||||||
virNetServerDispose)))
|
virNetServerDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -112,7 +112,8 @@ static void virNetServerClientDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetServerClientOnceInit(void)
|
static int virNetServerClientOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetServerClientClass = virClassNew("virNetServerClient",
|
if (!(virNetServerClientClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetServerClient",
|
||||||
sizeof(virNetServerClient),
|
sizeof(virNetServerClient),
|
||||||
virNetServerClientDispose)))
|
virNetServerClientDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -49,7 +49,8 @@ static void virNetServerProgramDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetServerProgramOnceInit(void)
|
static int virNetServerProgramOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetServerProgramClass = virClassNew("virNetServerProgram",
|
if (!(virNetServerProgramClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetServerProgram",
|
||||||
sizeof(virNetServerProgram),
|
sizeof(virNetServerProgram),
|
||||||
virNetServerProgramDispose)))
|
virNetServerProgramDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -55,7 +55,8 @@ static void virNetServerServiceDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetServerServiceOnceInit(void)
|
static int virNetServerServiceOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetServerServiceClass = virClassNew("virNetServerService",
|
if (!(virNetServerServiceClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetServerService",
|
||||||
sizeof(virNetServerService),
|
sizeof(virNetServerService),
|
||||||
virNetServerServiceDispose)))
|
virNetServerServiceDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -104,7 +104,8 @@ static void virNetSocketDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetSocketOnceInit(void)
|
static int virNetSocketOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetSocketClass = virClassNew("virNetSocket",
|
if (!(virNetSocketClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetSocket",
|
||||||
sizeof(virNetSocket),
|
sizeof(virNetSocket),
|
||||||
virNetSocketDispose)))
|
virNetSocketDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -161,7 +161,8 @@ static virClassPtr virNetSSHSessionClass;
|
|||||||
static int
|
static int
|
||||||
virNetSSHSessionOnceInit(void)
|
virNetSSHSessionOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetSSHSessionClass = virClassNew("virNetSSHSession",
|
if (!(virNetSSHSessionClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetSSHSession",
|
||||||
sizeof(virNetSSHSession),
|
sizeof(virNetSSHSession),
|
||||||
virNetSSHSessionDispose)))
|
virNetSSHSessionDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -85,12 +85,14 @@ static void virNetTLSSessionDispose(void *obj);
|
|||||||
|
|
||||||
static int virNetTLSContextOnceInit(void)
|
static int virNetTLSContextOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(virNetTLSContextClass = virClassNew("virNetTLSContext",
|
if (!(virNetTLSContextClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetTLSContext",
|
||||||
sizeof(virNetTLSContext),
|
sizeof(virNetTLSContext),
|
||||||
virNetTLSContextDispose)))
|
virNetTLSContextDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(virNetTLSSessionClass = virClassNew("virNetTLSSession",
|
if (!(virNetTLSSessionClass = virClassNew(virClassForObject(),
|
||||||
|
"virNetTLSSession",
|
||||||
sizeof(virNetTLSSession),
|
sizeof(virNetTLSSession),
|
||||||
virNetTLSSessionDispose)))
|
virNetTLSSessionDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -628,7 +628,8 @@ dnsmasqCapsDispose(void *obj)
|
|||||||
|
|
||||||
static int dnsmasqCapsOnceInit(void)
|
static int dnsmasqCapsOnceInit(void)
|
||||||
{
|
{
|
||||||
if (!(dnsmasqCapsClass = virClassNew("dnsmasqCaps",
|
if (!(dnsmasqCapsClass = virClassNew(virClassForObject(),
|
||||||
|
"dnsmasqCaps",
|
||||||
sizeof(dnsmasqCaps),
|
sizeof(dnsmasqCaps),
|
||||||
dnsmasqCapsDispose))) {
|
dnsmasqCapsDispose))) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
static unsigned int magicCounter = 0xCAFE0000;
|
static unsigned int magicCounter = 0xCAFE0000;
|
||||||
|
|
||||||
struct _virClass {
|
struct _virClass {
|
||||||
|
virClassPtr parent;
|
||||||
|
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
const char *name;
|
const char *name;
|
||||||
size_t objectSize;
|
size_t objectSize;
|
||||||
@ -40,9 +42,39 @@ struct _virClass {
|
|||||||
virObjectDisposeCallback dispose;
|
virObjectDisposeCallback dispose;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static virClassPtr virObjectClass;
|
||||||
|
|
||||||
|
static int virObjectOnceInit(void)
|
||||||
|
{
|
||||||
|
if (!(virObjectClass = virClassNew(NULL,
|
||||||
|
"virObject",
|
||||||
|
sizeof(virObject),
|
||||||
|
NULL)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_ONCE_GLOBAL_INIT(virObject);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virClassForObject:
|
||||||
|
*
|
||||||
|
* Returns the class instance for the base virObject type
|
||||||
|
*/
|
||||||
|
virClassPtr virClassForObject(void)
|
||||||
|
{
|
||||||
|
if (!virObjectInitialize() < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return virObjectClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virClassNew:
|
* virClassNew:
|
||||||
|
* @parent: the parent class
|
||||||
* @name: the class name
|
* @name: the class name
|
||||||
* @objectSize: total size of the object struct
|
* @objectSize: total size of the object struct
|
||||||
* @dispose: callback to run to free object fields
|
* @dispose: callback to run to free object fields
|
||||||
@ -56,15 +88,29 @@ struct _virClass {
|
|||||||
*
|
*
|
||||||
* Returns a new class instance
|
* Returns a new class instance
|
||||||
*/
|
*/
|
||||||
virClassPtr virClassNew(const char *name,
|
virClassPtr virClassNew(virClassPtr parent,
|
||||||
|
const char *name,
|
||||||
size_t objectSize,
|
size_t objectSize,
|
||||||
virObjectDisposeCallback dispose)
|
virObjectDisposeCallback dispose)
|
||||||
{
|
{
|
||||||
virClassPtr klass;
|
virClassPtr klass;
|
||||||
|
|
||||||
|
if (parent == NULL &&
|
||||||
|
STRNEQ(name, "virObject")) {
|
||||||
|
virReportInvalidNonNullArg(parent);
|
||||||
|
return NULL;
|
||||||
|
} else if (parent &&
|
||||||
|
objectSize <= parent->objectSize) {
|
||||||
|
virReportInvalidArg(objectSize,
|
||||||
|
_("object size %zu of %s is smaller than parent class %zu"),
|
||||||
|
objectSize, name, parent->objectSize);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(klass) < 0)
|
if (VIR_ALLOC(klass) < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
|
klass->parent = parent;
|
||||||
if (!(klass->name = strdup(name)))
|
if (!(klass->name = strdup(name)))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
klass->magic = virAtomicIntInc(&magicCounter);
|
klass->magic = virAtomicIntInc(&magicCounter);
|
||||||
@ -80,6 +126,27 @@ no_memory:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virClassIsDerivedFrom:
|
||||||
|
* @klass: the klass to check
|
||||||
|
* @parent: the possible parent class
|
||||||
|
*
|
||||||
|
* Determine if @klass is derived from @parent
|
||||||
|
*
|
||||||
|
* Return true if @klass is derived from @parent, false otherwise
|
||||||
|
*/
|
||||||
|
bool virClassIsDerivedFrom(virClassPtr klass,
|
||||||
|
virClassPtr parent)
|
||||||
|
{
|
||||||
|
while (klass) {
|
||||||
|
if (klass->magic == parent->magic)
|
||||||
|
return true;
|
||||||
|
klass = klass->parent;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virObjectNew:
|
* virObjectNew:
|
||||||
* @klass: the klass of object to create
|
* @klass: the klass of object to create
|
||||||
@ -135,8 +202,14 @@ bool virObjectUnref(void *anyobj)
|
|||||||
PROBE(OBJECT_UNREF, "obj=%p", obj);
|
PROBE(OBJECT_UNREF, "obj=%p", obj);
|
||||||
if (lastRef) {
|
if (lastRef) {
|
||||||
PROBE(OBJECT_DISPOSE, "obj=%p", obj);
|
PROBE(OBJECT_DISPOSE, "obj=%p", obj);
|
||||||
if (obj->klass->dispose)
|
virClassPtr klass = obj->klass;
|
||||||
obj->klass->dispose(obj);
|
while (klass) {
|
||||||
|
if (klass->dispose)
|
||||||
|
klass->dispose(obj);
|
||||||
|
klass = klass->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
virMutexDestroy(&obj->lock);
|
||||||
|
|
||||||
/* Clear & poison object */
|
/* Clear & poison object */
|
||||||
memset(obj, 0, obj->klass->objectSize);
|
memset(obj, 0, obj->klass->objectSize);
|
||||||
@ -184,7 +257,10 @@ bool virObjectIsClass(void *anyobj,
|
|||||||
virClassPtr klass)
|
virClassPtr klass)
|
||||||
{
|
{
|
||||||
virObjectPtr obj = anyobj;
|
virObjectPtr obj = anyobj;
|
||||||
return obj != NULL && (obj->magic == klass->magic) && (obj->klass == klass);
|
if (!obj)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return virClassIsDerivedFrom(obj->klass, klass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,10 @@ struct _virObject {
|
|||||||
virClassPtr klass;
|
virClassPtr klass;
|
||||||
};
|
};
|
||||||
|
|
||||||
virClassPtr virClassNew(const char *name,
|
virClassPtr virClassForObject(void);
|
||||||
|
|
||||||
|
virClassPtr virClassNew(virClassPtr parent,
|
||||||
|
const char *name,
|
||||||
size_t objectSize,
|
size_t objectSize,
|
||||||
virObjectDisposeCallback dispose)
|
virObjectDisposeCallback dispose)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
@ -46,6 +49,10 @@ virClassPtr virClassNew(const char *name,
|
|||||||
const char *virClassName(virClassPtr klass)
|
const char *virClassName(virClassPtr klass)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
|
bool virClassIsDerivedFrom(virClassPtr klass,
|
||||||
|
virClassPtr parent)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
void *virObjectNew(virClassPtr klass)
|
void *virObjectNew(virClassPtr klass)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
bool virObjectUnref(void *obj);
|
bool virObjectUnref(void *obj);
|
||||||
|
Loading…
Reference in New Issue
Block a user