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

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: NDaniel P. Berrange <berrange@redhat.com>
上级 e397f658
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册