mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +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/virnetlink.c
|
||||
src/util/virnodesuspend.c
|
||||
src/util/virobject.c
|
||||
src/util/virpci.c
|
||||
src/util/virpidfile.c
|
||||
src/util/virprocess.c
|
||||
|
@ -700,7 +700,8 @@ static void virDomainObjDispose(void *obj);
|
||||
|
||||
static int virDomainObjOnceInit(void)
|
||||
{
|
||||
if (!(virDomainObjClass = virClassNew("virDomainObj",
|
||||
if (!(virDomainObjClass = virClassNew(virClassForObject(),
|
||||
"virDomainObj",
|
||||
sizeof(virDomainObj),
|
||||
virDomainObjDispose)))
|
||||
return -1;
|
||||
|
@ -64,7 +64,8 @@ static int
|
||||
virDataTypesOnceInit(void)
|
||||
{
|
||||
#define DECLARE_CLASS(basename) \
|
||||
if (!(basename ## Class = virClassNew(#basename, \
|
||||
if (!(basename ## Class = virClassNew(virClassForObject(), \
|
||||
#basename, \
|
||||
sizeof(basename), \
|
||||
basename ## Dispose))) \
|
||||
return -1;
|
||||
|
@ -1769,6 +1769,8 @@ virNodeSuspendGetTargetMask;
|
||||
|
||||
|
||||
# virobject.h
|
||||
virClassForObject;
|
||||
virClassIsDerivedFrom;
|
||||
virClassName;
|
||||
virClassNew;
|
||||
virObjectFreeCallback;
|
||||
|
@ -50,7 +50,8 @@ static void virLXCMonitorDispose(void *obj);
|
||||
|
||||
static int virLXCMonitorOnceInit(void)
|
||||
{
|
||||
if (!(virLXCMonitorClass = virClassNew("virLXCMonitor",
|
||||
if (!(virLXCMonitorClass = virClassNew(virClassForObject(),
|
||||
"virLXCMonitor",
|
||||
sizeof(virLXCMonitor),
|
||||
virLXCMonitorDispose)))
|
||||
return -1;
|
||||
|
@ -121,7 +121,8 @@ static void qemuAgentDispose(void *obj);
|
||||
|
||||
static int qemuAgentOnceInit(void)
|
||||
{
|
||||
if (!(qemuAgentClass = virClassNew("qemuAgent",
|
||||
if (!(qemuAgentClass = virClassNew(virClassForObject(),
|
||||
"qemuAgent",
|
||||
sizeof(qemuAgent),
|
||||
qemuAgentDispose)))
|
||||
return -1;
|
||||
|
@ -244,7 +244,8 @@ static void qemuCapsDispose(void *obj);
|
||||
|
||||
static int qemuCapsOnceInit(void)
|
||||
{
|
||||
if (!(qemuCapsClass = virClassNew("qemuCaps",
|
||||
if (!(qemuCapsClass = virClassNew(virClassForObject(),
|
||||
"qemuCaps",
|
||||
sizeof(qemuCaps),
|
||||
qemuCapsDispose)))
|
||||
return -1;
|
||||
|
@ -86,9 +86,10 @@ static void qemuMonitorDispose(void *obj);
|
||||
|
||||
static int qemuMonitorOnceInit(void)
|
||||
{
|
||||
if (!(qemuMonitorClass = virClassNew("qemuMonitor",
|
||||
sizeof(qemuMonitor),
|
||||
qemuMonitorDispose)))
|
||||
if (!(qemuMonitorClass = virClassNew(virClassForObject(),
|
||||
"qemuMonitor",
|
||||
sizeof(qemuMonitor),
|
||||
qemuMonitorDispose)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
@ -58,7 +58,8 @@ static void virKeepAliveDispose(void *obj);
|
||||
|
||||
static int virKeepAliveOnceInit(void)
|
||||
{
|
||||
if (!(virKeepAliveClass = virClassNew("virKeepAlive",
|
||||
if (!(virKeepAliveClass = virClassNew(virClassForObject(),
|
||||
"virKeepAlive",
|
||||
sizeof(virKeepAlive),
|
||||
virKeepAliveDispose)))
|
||||
return -1;
|
||||
|
@ -117,7 +117,8 @@ static void virNetClientDispose(void *obj);
|
||||
|
||||
static int virNetClientOnceInit(void)
|
||||
{
|
||||
if (!(virNetClientClass = virClassNew("virNetClient",
|
||||
if (!(virNetClientClass = virClassNew(virClassForObject(),
|
||||
"virNetClient",
|
||||
sizeof(virNetClient),
|
||||
virNetClientDispose)))
|
||||
return -1;
|
||||
|
@ -52,7 +52,8 @@ static void virNetClientProgramDispose(void *obj);
|
||||
|
||||
static int virNetClientProgramOnceInit(void)
|
||||
{
|
||||
if (!(virNetClientProgramClass = virClassNew("virNetClientProgram",
|
||||
if (!(virNetClientProgramClass = virClassNew(virClassForObject(),
|
||||
"virNetClientProgram",
|
||||
sizeof(virNetClientProgram),
|
||||
virNetClientProgramDispose)))
|
||||
return -1;
|
||||
|
@ -68,7 +68,8 @@ static void virNetClientStreamDispose(void *obj);
|
||||
|
||||
static int virNetClientStreamOnceInit(void)
|
||||
{
|
||||
if (!(virNetClientStreamClass = virClassNew("virNetClientStream",
|
||||
if (!(virNetClientStreamClass = virClassNew(virClassForObject(),
|
||||
"virNetClientStream",
|
||||
sizeof(virNetClientStream),
|
||||
virNetClientStreamDispose)))
|
||||
return -1;
|
||||
|
@ -55,12 +55,14 @@ static void virNetSASLSessionDispose(void *obj);
|
||||
|
||||
static int virNetSASLContextOnceInit(void)
|
||||
{
|
||||
if (!(virNetSASLContextClass = virClassNew("virNetSASLContext",
|
||||
if (!(virNetSASLContextClass = virClassNew(virClassForObject(),
|
||||
"virNetSASLContext",
|
||||
sizeof(virNetSASLContext),
|
||||
virNetSASLContextDispose)))
|
||||
return -1;
|
||||
|
||||
if (!(virNetSASLSessionClass = virClassNew("virNetSASLSession",
|
||||
if (!(virNetSASLSessionClass = virClassNew(virClassForObject(),
|
||||
"virNetSASLSession",
|
||||
sizeof(virNetSASLSession),
|
||||
virNetSASLSessionDispose)))
|
||||
return -1;
|
||||
|
@ -119,7 +119,8 @@ static void virNetServerDispose(void *obj);
|
||||
|
||||
static int virNetServerOnceInit(void)
|
||||
{
|
||||
if (!(virNetServerClass = virClassNew("virNetServer",
|
||||
if (!(virNetServerClass = virClassNew(virClassForObject(),
|
||||
"virNetServer",
|
||||
sizeof(virNetServer),
|
||||
virNetServerDispose)))
|
||||
return -1;
|
||||
|
@ -112,7 +112,8 @@ static void virNetServerClientDispose(void *obj);
|
||||
|
||||
static int virNetServerClientOnceInit(void)
|
||||
{
|
||||
if (!(virNetServerClientClass = virClassNew("virNetServerClient",
|
||||
if (!(virNetServerClientClass = virClassNew(virClassForObject(),
|
||||
"virNetServerClient",
|
||||
sizeof(virNetServerClient),
|
||||
virNetServerClientDispose)))
|
||||
return -1;
|
||||
|
@ -49,7 +49,8 @@ static void virNetServerProgramDispose(void *obj);
|
||||
|
||||
static int virNetServerProgramOnceInit(void)
|
||||
{
|
||||
if (!(virNetServerProgramClass = virClassNew("virNetServerProgram",
|
||||
if (!(virNetServerProgramClass = virClassNew(virClassForObject(),
|
||||
"virNetServerProgram",
|
||||
sizeof(virNetServerProgram),
|
||||
virNetServerProgramDispose)))
|
||||
return -1;
|
||||
|
@ -55,7 +55,8 @@ static void virNetServerServiceDispose(void *obj);
|
||||
|
||||
static int virNetServerServiceOnceInit(void)
|
||||
{
|
||||
if (!(virNetServerServiceClass = virClassNew("virNetServerService",
|
||||
if (!(virNetServerServiceClass = virClassNew(virClassForObject(),
|
||||
"virNetServerService",
|
||||
sizeof(virNetServerService),
|
||||
virNetServerServiceDispose)))
|
||||
return -1;
|
||||
|
@ -104,7 +104,8 @@ static void virNetSocketDispose(void *obj);
|
||||
|
||||
static int virNetSocketOnceInit(void)
|
||||
{
|
||||
if (!(virNetSocketClass = virClassNew("virNetSocket",
|
||||
if (!(virNetSocketClass = virClassNew(virClassForObject(),
|
||||
"virNetSocket",
|
||||
sizeof(virNetSocket),
|
||||
virNetSocketDispose)))
|
||||
return -1;
|
||||
|
@ -161,7 +161,8 @@ static virClassPtr virNetSSHSessionClass;
|
||||
static int
|
||||
virNetSSHSessionOnceInit(void)
|
||||
{
|
||||
if (!(virNetSSHSessionClass = virClassNew("virNetSSHSession",
|
||||
if (!(virNetSSHSessionClass = virClassNew(virClassForObject(),
|
||||
"virNetSSHSession",
|
||||
sizeof(virNetSSHSession),
|
||||
virNetSSHSessionDispose)))
|
||||
return -1;
|
||||
|
@ -85,12 +85,14 @@ static void virNetTLSSessionDispose(void *obj);
|
||||
|
||||
static int virNetTLSContextOnceInit(void)
|
||||
{
|
||||
if (!(virNetTLSContextClass = virClassNew("virNetTLSContext",
|
||||
if (!(virNetTLSContextClass = virClassNew(virClassForObject(),
|
||||
"virNetTLSContext",
|
||||
sizeof(virNetTLSContext),
|
||||
virNetTLSContextDispose)))
|
||||
return -1;
|
||||
|
||||
if (!(virNetTLSSessionClass = virClassNew("virNetTLSSession",
|
||||
if (!(virNetTLSSessionClass = virClassNew(virClassForObject(),
|
||||
"virNetTLSSession",
|
||||
sizeof(virNetTLSSession),
|
||||
virNetTLSSessionDispose)))
|
||||
return -1;
|
||||
|
@ -628,7 +628,8 @@ dnsmasqCapsDispose(void *obj)
|
||||
|
||||
static int dnsmasqCapsOnceInit(void)
|
||||
{
|
||||
if (!(dnsmasqCapsClass = virClassNew("dnsmasqCaps",
|
||||
if (!(dnsmasqCapsClass = virClassNew(virClassForObject(),
|
||||
"dnsmasqCaps",
|
||||
sizeof(dnsmasqCaps),
|
||||
dnsmasqCapsDispose))) {
|
||||
return -1;
|
||||
|
@ -33,6 +33,8 @@
|
||||
static unsigned int magicCounter = 0xCAFE0000;
|
||||
|
||||
struct _virClass {
|
||||
virClassPtr parent;
|
||||
|
||||
unsigned int magic;
|
||||
const char *name;
|
||||
size_t objectSize;
|
||||
@ -40,9 +42,39 @@ struct _virClass {
|
||||
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:
|
||||
* @parent: the parent class
|
||||
* @name: the class name
|
||||
* @objectSize: total size of the object struct
|
||||
* @dispose: callback to run to free object fields
|
||||
@ -56,15 +88,29 @@ struct _virClass {
|
||||
*
|
||||
* Returns a new class instance
|
||||
*/
|
||||
virClassPtr virClassNew(const char *name,
|
||||
virClassPtr virClassNew(virClassPtr parent,
|
||||
const char *name,
|
||||
size_t objectSize,
|
||||
virObjectDisposeCallback dispose)
|
||||
{
|
||||
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)
|
||||
goto no_memory;
|
||||
|
||||
klass->parent = parent;
|
||||
if (!(klass->name = strdup(name)))
|
||||
goto no_memory;
|
||||
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:
|
||||
* @klass: the klass of object to create
|
||||
@ -135,8 +202,14 @@ bool virObjectUnref(void *anyobj)
|
||||
PROBE(OBJECT_UNREF, "obj=%p", obj);
|
||||
if (lastRef) {
|
||||
PROBE(OBJECT_DISPOSE, "obj=%p", obj);
|
||||
if (obj->klass->dispose)
|
||||
obj->klass->dispose(obj);
|
||||
virClassPtr klass = obj->klass;
|
||||
while (klass) {
|
||||
if (klass->dispose)
|
||||
klass->dispose(obj);
|
||||
klass = klass->parent;
|
||||
}
|
||||
|
||||
virMutexDestroy(&obj->lock);
|
||||
|
||||
/* Clear & poison object */
|
||||
memset(obj, 0, obj->klass->objectSize);
|
||||
@ -184,7 +257,10 @@ bool virObjectIsClass(void *anyobj,
|
||||
virClassPtr klass)
|
||||
{
|
||||
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 virClassNew(const char *name,
|
||||
virClassPtr virClassForObject(void);
|
||||
|
||||
virClassPtr virClassNew(virClassPtr parent,
|
||||
const char *name,
|
||||
size_t objectSize,
|
||||
virObjectDisposeCallback dispose)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
@ -46,6 +49,10 @@ virClassPtr virClassNew(const char *name,
|
||||
const char *virClassName(virClassPtr klass)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
|
||||
bool virClassIsDerivedFrom(virClassPtr klass,
|
||||
virClassPtr parent)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
|
||||
void *virObjectNew(virClassPtr klass)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
bool virObjectUnref(void *obj);
|
||||
|
Loading…
Reference in New Issue
Block a user