Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
/*
|
|
|
|
* virobject.c: libvirt reference counted object
|
|
|
|
*
|
2014-04-04 23:36:25 +00:00
|
|
|
* Copyright (C) 2012-2014 Red Hat, Inc.
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2013-01-22 17:13:01 +00:00
|
|
|
#define VIR_PARENT_REQUIRED /* empty, to allow virObject to have no parent */
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
#include "virobject.h"
|
2012-12-13 15:49:48 +00:00
|
|
|
#include "virthread.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2014-02-27 13:41:11 +00:00
|
|
|
#include "virprobe.h"
|
2013-05-24 07:19:51 +00:00
|
|
|
#include "virstring.h"
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
|
2014-02-28 12:16:17 +00:00
|
|
|
VIR_LOG_INIT("util.object");
|
|
|
|
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
static unsigned int magicCounter = 0xCAFE0000;
|
|
|
|
|
|
|
|
struct _virClass {
|
2013-01-09 17:37:27 +00:00
|
|
|
virClassPtr parent;
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
GType type;
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
unsigned int magic;
|
2013-05-24 07:19:51 +00:00
|
|
|
char *name;
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
size_t objectSize;
|
|
|
|
|
|
|
|
virObjectDisposeCallback dispose;
|
|
|
|
};
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
typedef struct _virObjectPrivate virObjectPrivate;
|
|
|
|
struct _virObjectPrivate {
|
|
|
|
virClassPtr klass;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE(virObject, vir_object, G_TYPE_OBJECT)
|
|
|
|
|
|
|
|
#define VIR_OBJECT_NOTVALID(obj) (!obj || !VIR_IS_OBJECT(obj))
|
util: Add magic number check for object validity
The virObjectIsClass API has only ever checked object validity
based on if the @obj is not NULL and it was derived from some class.
While this has worked well in general, there is one additional
check that could be made prior to calling virClassIsDerivedFrom
which loops through the classes checking the magic number against
the klass expected magic number.
If by chance a non virObject is passed, rather than assuming the
void * @obj is a _virObject and thus offsetting to obj->klass,
obj->magic, and obj->parent, let's check that the void * @obj
has at least the "base part" of the magic number in the right
place and generate a more specific VIR_WARN message if not.
There are many consumers to virObjectIsClass, include the locking
primitives virObject{Lock|Unlock}, virObjectRWLock{Read|Write},
and virObjectRWUnlock. For those callers, the locking call will
not fail, but it also will not attempt a virMutex* call which
will "most likely" fail since the &obj->lock is used.
In order to avoid some possible future wrap on the 0xCAFExxxx
value, add a check during initialization that some new class
won't cause the wrap. Should be good for a few years at least!
It is still left up to the caller to handle the failed API calls
just as it would be if it passed a NULL opaque pointer anyobj.
2017-07-31 22:58:55 +00:00
|
|
|
|
2017-11-03 12:09:47 +00:00
|
|
|
#define VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, objclass) \
|
|
|
|
do { \
|
|
|
|
virObjectPtr obj = anyobj; \
|
2020-05-19 15:15:51 +00:00
|
|
|
if (!obj) \
|
|
|
|
VIR_WARN("Object cannot be NULL"); \
|
|
|
|
if (VIR_OBJECT_NOTVALID(obj)) \
|
2017-11-03 12:09:47 +00:00
|
|
|
VIR_WARN("Object %p (%s) is not a %s instance", \
|
2020-05-19 15:15:51 +00:00
|
|
|
anyobj, g_type_name_from_instance((void*)anyobj), #objclass); \
|
2017-07-28 15:09:31 +00:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
static virClassPtr virObjectClassImpl;
|
2013-01-09 17:54:07 +00:00
|
|
|
static virClassPtr virObjectLockableClass;
|
2017-07-19 07:31:50 +00:00
|
|
|
static virClassPtr virObjectRWLockableClass;
|
2013-01-09 17:54:07 +00:00
|
|
|
|
|
|
|
static void virObjectLockableDispose(void *anyobj);
|
2017-07-19 07:31:50 +00:00
|
|
|
static void virObjectRWLockableDispose(void *anyobj);
|
2013-01-09 17:37:27 +00:00
|
|
|
|
2017-03-28 19:09:55 +00:00
|
|
|
static int
|
|
|
|
virObjectOnceInit(void)
|
2013-01-09 17:37:27 +00:00
|
|
|
{
|
2020-05-19 15:15:51 +00:00
|
|
|
if (!(virObjectClassImpl = virClassNew(NULL,
|
|
|
|
"virObject",
|
|
|
|
sizeof(virObject),
|
|
|
|
0,
|
|
|
|
NULL)))
|
2013-01-09 17:37:27 +00:00
|
|
|
return -1;
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
if (!VIR_CLASS_NEW(virObjectLockable, virObjectClassImpl))
|
2013-01-09 17:54:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
if (!VIR_CLASS_NEW(virObjectRWLockable, virObjectClassImpl))
|
2017-07-19 07:31:50 +00:00
|
|
|
return -1;
|
|
|
|
|
2013-01-09 17:37:27 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_ONCE_GLOBAL_INIT(virObject);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virClassForObject:
|
|
|
|
*
|
|
|
|
* Returns the class instance for the base virObject type
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
virClassPtr
|
|
|
|
virClassForObject(void)
|
2013-01-09 17:37:27 +00:00
|
|
|
{
|
2013-01-17 19:17:14 +00:00
|
|
|
if (virObjectInitialize() < 0)
|
2013-01-09 17:37:27 +00:00
|
|
|
return NULL;
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
return virObjectClassImpl;
|
2013-01-09 17:37:27 +00:00
|
|
|
}
|
|
|
|
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
|
2013-01-09 17:54:07 +00:00
|
|
|
/**
|
|
|
|
* virClassForObjectLockable:
|
|
|
|
*
|
|
|
|
* Returns the class instance for the virObjectLockable type
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
virClassPtr
|
|
|
|
virClassForObjectLockable(void)
|
2013-01-09 17:54:07 +00:00
|
|
|
{
|
2013-01-17 19:17:14 +00:00
|
|
|
if (virObjectInitialize() < 0)
|
2013-01-09 17:54:07 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return virObjectLockableClass;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-19 07:31:50 +00:00
|
|
|
/**
|
|
|
|
* virClassForObjectRWLockable:
|
|
|
|
*
|
|
|
|
* Returns the class instance for the virObjectRWLockable type
|
|
|
|
*/
|
|
|
|
virClassPtr
|
|
|
|
virClassForObjectRWLockable(void)
|
|
|
|
{
|
|
|
|
if (virObjectInitialize() < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return virObjectRWLockableClass;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
static void virClassDummyInit(void *klass G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void virObjectDummyInit(void *obj G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
/**
|
|
|
|
* virClassNew:
|
2013-01-09 17:37:27 +00:00
|
|
|
* @parent: the parent class
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
* @name: the class name
|
|
|
|
* @objectSize: total size of the object struct
|
|
|
|
* @dispose: callback to run to free object fields
|
|
|
|
*
|
|
|
|
* Register a new object class with @name. The @objectSize
|
|
|
|
* should give the total size of the object struct, which
|
2019-03-15 04:14:41 +00:00
|
|
|
* is expected to have a 'virObject parent;' field as (or
|
|
|
|
* contained in) its first member. When the last reference
|
|
|
|
* on the object is released, the @dispose callback will be
|
|
|
|
* invoked to free memory of the local object fields, as
|
|
|
|
* well as the dispose callbacks of the parent classes.
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
*
|
|
|
|
* Returns a new class instance
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
virClassPtr
|
|
|
|
virClassNew(virClassPtr parent,
|
|
|
|
const char *name,
|
|
|
|
size_t objectSize,
|
2019-03-15 14:41:18 +00:00
|
|
|
size_t parentSize,
|
2017-03-28 19:09:55 +00:00
|
|
|
virObjectDisposeCallback dispose)
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
{
|
|
|
|
virClassPtr klass;
|
|
|
|
|
2013-01-09 17:37:27 +00:00
|
|
|
if (parent == NULL &&
|
|
|
|
STRNEQ(name, "virObject")) {
|
|
|
|
virReportInvalidNonNullArg(parent);
|
|
|
|
return NULL;
|
2019-03-15 14:41:18 +00:00
|
|
|
} else if (objectSize <= parentSize ||
|
|
|
|
parentSize != (parent ? parent->objectSize : 0)) {
|
|
|
|
sa_assert(parent);
|
2013-01-09 17:37:27 +00:00
|
|
|
virReportInvalidArg(objectSize,
|
2019-03-15 14:41:18 +00:00
|
|
|
_("object size %zu of %s is not larger than parent class %zu"),
|
2013-01-09 17:37:27 +00:00
|
|
|
objectSize, name, parent->objectSize);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
klass = g_new0(virClass, 1);
|
2013-01-09 17:37:27 +00:00
|
|
|
klass->parent = parent;
|
2020-01-31 16:04:24 +00:00
|
|
|
klass->magic = g_atomic_int_add(&magicCounter, 1);
|
2019-10-20 11:49:46 +00:00
|
|
|
klass->name = g_strdup(name);
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
klass->objectSize = objectSize;
|
2020-05-19 15:15:51 +00:00
|
|
|
if (parent == NULL) {
|
|
|
|
klass->type = vir_object_get_type();
|
|
|
|
} else {
|
|
|
|
klass->type =
|
|
|
|
g_type_register_static_simple(parent->type,
|
|
|
|
name,
|
|
|
|
sizeof(virObjectClass),
|
|
|
|
(GClassInitFunc)virClassDummyInit,
|
|
|
|
objectSize,
|
|
|
|
(GInstanceInitFunc)virObjectDummyInit,
|
|
|
|
0);
|
|
|
|
}
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
klass->dispose = dispose;
|
|
|
|
|
|
|
|
return klass;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-09 17:37:27 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
bool
|
|
|
|
virClassIsDerivedFrom(virClassPtr klass,
|
|
|
|
virClassPtr parent)
|
2013-01-09 17:37:27 +00:00
|
|
|
{
|
|
|
|
while (klass) {
|
|
|
|
if (klass->magic == parent->magic)
|
|
|
|
return true;
|
|
|
|
klass = klass->parent;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
/**
|
|
|
|
* virObjectNew:
|
|
|
|
* @klass: the klass of object to create
|
|
|
|
*
|
|
|
|
* Allocates a new object of type @klass. The returned
|
|
|
|
* object will be an instance of "virObjectPtr", which
|
|
|
|
* can be cast to the struct associated with @klass.
|
|
|
|
*
|
|
|
|
* The initial reference count of the object will be 1.
|
|
|
|
*
|
|
|
|
* Returns the new object
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
void *
|
|
|
|
virObjectNew(virClassPtr klass)
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
{
|
|
|
|
virObjectPtr obj = NULL;
|
2020-05-19 15:15:51 +00:00
|
|
|
virObjectPrivate *priv;
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
obj = g_object_new(klass->type, NULL);
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
priv = vir_object_get_instance_private(obj);
|
|
|
|
priv->klass = klass;
|
|
|
|
PROBE(OBJECT_NEW, "obj=%p classname=%s", obj, priv->klass->name);
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-28 19:09:55 +00:00
|
|
|
void *
|
|
|
|
virObjectLockableNew(virClassPtr klass)
|
2013-01-09 17:54:07 +00:00
|
|
|
{
|
|
|
|
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) {
|
2014-11-28 08:37:42 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Unable to initialize mutex"));
|
2013-01-09 17:54:07 +00:00
|
|
|
virObjectUnref(obj);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-19 07:31:50 +00:00
|
|
|
void *
|
|
|
|
virObjectRWLockableNew(virClassPtr klass)
|
|
|
|
{
|
|
|
|
virObjectRWLockablePtr obj;
|
|
|
|
|
|
|
|
if (!virClassIsDerivedFrom(klass, virClassForObjectRWLockable())) {
|
|
|
|
virReportInvalidArg(klass,
|
|
|
|
_("Class %s must derive from virObjectRWLockable"),
|
|
|
|
virClassName(klass));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(obj = virObjectNew(klass)))
|
|
|
|
return NULL;
|
|
|
|
|
2017-07-25 08:31:54 +00:00
|
|
|
if (virRWLockInit(&obj->lock) < 0) {
|
2017-07-19 07:31:50 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Unable to initialize RW lock"));
|
|
|
|
virObjectUnref(obj);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
static void vir_object_finalize(GObject *gobj)
|
|
|
|
{
|
|
|
|
virObjectPtr obj = VIR_OBJECT(gobj);
|
|
|
|
virObjectPrivate *priv = vir_object_get_instance_private(obj);
|
|
|
|
virClassPtr klass = priv->klass;
|
2020-08-03 15:28:06 +00:00
|
|
|
|
|
|
|
PROBE(OBJECT_DISPOSE, "obj=%p", gobj);
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
while (klass) {
|
|
|
|
if (klass->dispose)
|
|
|
|
klass->dispose(obj);
|
|
|
|
klass = klass->parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
G_OBJECT_CLASS(vir_object_parent_class)->finalize(gobj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vir_object_init(virObject *obj G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void vir_object_class_init(virObjectClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *obj = G_OBJECT_CLASS(klass);
|
|
|
|
|
|
|
|
obj->finalize = vir_object_finalize;
|
|
|
|
}
|
2017-07-19 07:31:50 +00:00
|
|
|
|
2017-03-28 19:09:55 +00:00
|
|
|
static void
|
|
|
|
virObjectLockableDispose(void *anyobj)
|
2013-01-09 17:54:07 +00:00
|
|
|
{
|
|
|
|
virObjectLockablePtr obj = anyobj;
|
|
|
|
|
|
|
|
virMutexDestroy(&obj->lock);
|
|
|
|
}
|
|
|
|
|
2017-03-28 19:09:55 +00:00
|
|
|
|
2017-07-19 07:31:50 +00:00
|
|
|
static void
|
|
|
|
virObjectRWLockableDispose(void *anyobj)
|
|
|
|
{
|
|
|
|
virObjectRWLockablePtr obj = anyobj;
|
|
|
|
|
|
|
|
virRWLockDestroy(&obj->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
/**
|
|
|
|
* virObjectUnref:
|
|
|
|
* @anyobj: any instance of virObjectPtr
|
|
|
|
*
|
|
|
|
* Decrement the reference count on @anyobj and if
|
2019-03-15 04:14:41 +00:00
|
|
|
* it hits zero, runs the "dispose" callbacks associated
|
|
|
|
* with the object class and its parents before freeing
|
|
|
|
* @anyobj.
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
*/
|
2020-05-15 15:36:00 +00:00
|
|
|
void
|
2017-03-28 19:09:55 +00:00
|
|
|
virObjectUnref(void *anyobj)
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
{
|
|
|
|
virObjectPtr obj = anyobj;
|
|
|
|
|
2017-03-31 15:35:05 +00:00
|
|
|
if (VIR_OBJECT_NOTVALID(obj))
|
2020-05-15 15:36:00 +00:00
|
|
|
return;
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
g_object_unref(anyobj);
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
PROBE(OBJECT_UNREF, "obj=%p", obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virObjectRef:
|
|
|
|
* @anyobj: any instance of virObjectPtr
|
|
|
|
*
|
|
|
|
* Increment the reference count on @anyobj and return
|
|
|
|
* the same pointer
|
|
|
|
*
|
|
|
|
* Returns @anyobj
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
void *
|
|
|
|
virObjectRef(void *anyobj)
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
{
|
|
|
|
virObjectPtr obj = anyobj;
|
|
|
|
|
2017-03-31 15:35:05 +00:00
|
|
|
if (VIR_OBJECT_NOTVALID(obj))
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
return NULL;
|
2020-05-19 15:15:51 +00:00
|
|
|
|
|
|
|
g_object_ref(obj);
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
PROBE(OBJECT_REF, "obj=%p", obj);
|
|
|
|
return anyobj;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-28 14:14:40 +00:00
|
|
|
static virObjectLockablePtr
|
|
|
|
virObjectGetLockableObj(void *anyobj)
|
|
|
|
{
|
|
|
|
if (virObjectIsClass(anyobj, virObjectLockableClass))
|
|
|
|
return anyobj;
|
|
|
|
|
2017-07-28 15:09:31 +00:00
|
|
|
VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, virObjectLockable);
|
2017-07-28 14:14:40 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-28 14:27:11 +00:00
|
|
|
static virObjectRWLockablePtr
|
|
|
|
virObjectGetRWLockableObj(void *anyobj)
|
|
|
|
{
|
|
|
|
if (virObjectIsClass(anyobj, virObjectRWLockableClass))
|
|
|
|
return anyobj;
|
|
|
|
|
2017-07-28 15:09:31 +00:00
|
|
|
VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, virObjectRWLockable);
|
2017-07-28 14:27:11 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-19 07:31:50 +00:00
|
|
|
/**
|
|
|
|
* virObjectLock:
|
2018-05-11 17:48:26 +00:00
|
|
|
* @anyobj: any instance of virObjectLockable
|
2017-07-19 07:31:50 +00:00
|
|
|
*
|
|
|
|
* Acquire a lock on @anyobj. The lock must be released by
|
2017-07-28 14:14:40 +00:00
|
|
|
* virObjectUnlock.
|
2017-07-19 07:31:50 +00:00
|
|
|
*
|
|
|
|
* 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)
|
2017-03-29 20:21:31 +00:00
|
|
|
{
|
2017-07-28 14:14:40 +00:00
|
|
|
virObjectLockablePtr obj = virObjectGetLockableObj(anyobj);
|
|
|
|
|
|
|
|
if (!obj)
|
|
|
|
return;
|
|
|
|
|
|
|
|
virMutexLock(&obj->lock);
|
2017-03-29 20:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-09 17:54:07 +00:00
|
|
|
/**
|
2017-07-28 13:57:04 +00:00
|
|
|
* virObjectRWLockRead:
|
2017-07-19 07:31:50 +00:00
|
|
|
* @anyobj: any instance of virObjectRWLockable
|
2013-01-09 17:54:07 +00:00
|
|
|
*
|
2017-07-19 07:31:50 +00:00
|
|
|
* Acquire a read lock on @anyobj. The lock must be
|
2017-07-28 16:03:50 +00:00
|
|
|
* released by virObjectRWUnlock.
|
2013-01-09 17:54:07 +00:00
|
|
|
*
|
|
|
|
* 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.
|
2017-07-28 13:57:04 +00:00
|
|
|
*
|
|
|
|
* NB: It's possible to return without the lock if
|
|
|
|
* @anyobj was invalid - this has been considered
|
|
|
|
* a programming error rather than something that
|
|
|
|
* should be checked.
|
2013-01-09 17:54:07 +00:00
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
void
|
2017-07-28 13:57:04 +00:00
|
|
|
virObjectRWLockRead(void *anyobj)
|
2013-01-09 17:54:07 +00:00
|
|
|
{
|
2017-07-28 14:27:11 +00:00
|
|
|
virObjectRWLockablePtr obj = virObjectGetRWLockableObj(anyobj);
|
|
|
|
|
|
|
|
if (!obj)
|
|
|
|
return;
|
|
|
|
|
|
|
|
virRWLockRead(&obj->lock);
|
2013-01-09 17:54:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-28 14:06:55 +00:00
|
|
|
/**
|
|
|
|
* virObjectRWLockWrite:
|
|
|
|
* @anyobj: any instance of virObjectRWLockable
|
|
|
|
*
|
|
|
|
* Acquire a write lock on @anyobj. The lock must be
|
2017-07-28 16:03:50 +00:00
|
|
|
* released by virObjectRWUnlock.
|
2017-07-28 14:06:55 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* NB: It's possible to return without the lock if
|
|
|
|
* @anyobj was invalid - this has been considered
|
|
|
|
* a programming error rather than something that
|
|
|
|
* should be checked.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
virObjectRWLockWrite(void *anyobj)
|
|
|
|
{
|
2017-07-28 14:27:11 +00:00
|
|
|
virObjectRWLockablePtr obj = virObjectGetRWLockableObj(anyobj);
|
|
|
|
|
|
|
|
if (!obj)
|
|
|
|
return;
|
|
|
|
|
|
|
|
virRWLockWrite(&obj->lock);
|
2017-07-28 14:06:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-09 17:54:07 +00:00
|
|
|
/**
|
|
|
|
* virObjectUnlock:
|
2017-07-28 16:03:50 +00:00
|
|
|
* @anyobj: any instance of virObjectLockable
|
2013-01-09 17:54:07 +00:00
|
|
|
*
|
2017-07-19 07:31:50 +00:00
|
|
|
* Release a lock on @anyobj. The lock must have been acquired by
|
2017-07-28 16:03:50 +00:00
|
|
|
* virObjectLock.
|
2013-01-09 17:54:07 +00:00
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
void
|
|
|
|
virObjectUnlock(void *anyobj)
|
2013-01-09 17:54:07 +00:00
|
|
|
{
|
2017-07-28 16:03:50 +00:00
|
|
|
virObjectLockablePtr obj = virObjectGetLockableObj(anyobj);
|
|
|
|
|
|
|
|
if (!obj)
|
|
|
|
return;
|
|
|
|
|
|
|
|
virMutexUnlock(&obj->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virObjectRWUnlock:
|
|
|
|
* @anyobj: any instance of virObjectRWLockable
|
|
|
|
*
|
|
|
|
* Release a lock on @anyobj. The lock must have been acquired by
|
|
|
|
* virObjectRWLockRead or virObjectRWLockWrite.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
virObjectRWUnlock(void *anyobj)
|
|
|
|
{
|
|
|
|
virObjectRWLockablePtr obj = virObjectGetRWLockableObj(anyobj);
|
|
|
|
|
|
|
|
if (!obj)
|
|
|
|
return;
|
|
|
|
|
|
|
|
virRWLockUnlock(&obj->lock);
|
2013-01-09 17:54:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
/**
|
|
|
|
* virObjectIsClass:
|
|
|
|
* @anyobj: any instance of virObjectPtr
|
|
|
|
* @klass: the class to check
|
|
|
|
*
|
|
|
|
* Checks whether @anyobj is an instance of
|
|
|
|
* @klass
|
|
|
|
*
|
|
|
|
* Returns true if @anyobj is an instance of @klass
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
bool
|
|
|
|
virObjectIsClass(void *anyobj,
|
|
|
|
virClassPtr klass)
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
{
|
|
|
|
virObjectPtr obj = anyobj;
|
2020-05-19 15:15:51 +00:00
|
|
|
virObjectPrivate *priv;
|
|
|
|
|
util: Add magic number check for object validity
The virObjectIsClass API has only ever checked object validity
based on if the @obj is not NULL and it was derived from some class.
While this has worked well in general, there is one additional
check that could be made prior to calling virClassIsDerivedFrom
which loops through the classes checking the magic number against
the klass expected magic number.
If by chance a non virObject is passed, rather than assuming the
void * @obj is a _virObject and thus offsetting to obj->klass,
obj->magic, and obj->parent, let's check that the void * @obj
has at least the "base part" of the magic number in the right
place and generate a more specific VIR_WARN message if not.
There are many consumers to virObjectIsClass, include the locking
primitives virObject{Lock|Unlock}, virObjectRWLock{Read|Write},
and virObjectRWUnlock. For those callers, the locking call will
not fail, but it also will not attempt a virMutex* call which
will "most likely" fail since the &obj->lock is used.
In order to avoid some possible future wrap on the 0xCAFExxxx
value, add a check during initialization that some new class
won't cause the wrap. Should be good for a few years at least!
It is still left up to the caller to handle the failed API calls
just as it would be if it passed a NULL opaque pointer anyobj.
2017-07-31 22:58:55 +00:00
|
|
|
if (VIR_OBJECT_NOTVALID(obj))
|
2013-01-09 17:37:27 +00:00
|
|
|
return false;
|
|
|
|
|
2020-05-19 15:15:51 +00:00
|
|
|
priv = vir_object_get_instance_private(obj);
|
|
|
|
return virClassIsDerivedFrom(priv->klass, klass);
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virClassName:
|
|
|
|
* @klass: the object class
|
|
|
|
*
|
|
|
|
* Returns the name of @klass
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
const char *
|
|
|
|
virClassName(virClassPtr klass)
|
Add a generic reference counted virObject type
This introduces a fairly basic reference counted virObject type
and an associated virClass type, that use atomic operations for
ref counting.
In a global initializer (recommended to be invoked using the
virOnceInit API), a virClass type must be allocated for each
object type. This requires a class name, a "dispose" callback
which will be invoked to free memory associated with the object's
fields, and the size in bytes of the object struct.
eg,
virClassPtr connclass = virClassNew("virConnect",
sizeof(virConnect),
virConnectDispose);
The struct for the object, must include 'virObject' as its
first member
eg
struct _virConnect {
virObject object;
virURIPtr uri;
};
The 'dispose' callback is only responsible for freeing
fields in the object, not the object itself. eg a suitable
impl for the above struct would be
void virConnectDispose(void *obj) {
virConnectPtr conn = obj;
virURIFree(conn->uri);
}
There is no need to reset fields to 'NULL' or '0' in the
dispose callback, since the entire object will be memset
to 0, and the klass pointer & magic integer fields will
be poisoned with 0xDEADBEEF before being free()d
When creating an instance of an object, one needs simply
pass the virClassPtr eg
virConnectPtr conn = virObjectNew(connclass);
if (!conn)
return NULL;
conn->uri = virURIParse("foo:///bar")
Object references can be manipulated with
virObjectRef(conn)
virObjectUnref(conn)
The latter returns a true value, if the object has been
freed (ie its ref count hit zero)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-11 13:35:44 +00:00
|
|
|
{
|
|
|
|
return klass->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virObjectFreeCallback:
|
|
|
|
* @opaque: a pointer to a virObject instance
|
|
|
|
*
|
|
|
|
* Provides identical functionality to virObjectUnref,
|
|
|
|
* but with the signature matching the virFreeCallback
|
|
|
|
* typedef.
|
|
|
|
*/
|
|
|
|
void virObjectFreeCallback(void *opaque)
|
|
|
|
{
|
|
|
|
virObjectUnref(opaque);
|
|
|
|
}
|
2014-04-04 23:36:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virObjectFreeHashData:
|
|
|
|
* @opaque: a pointer to a virObject instance
|
|
|
|
* @name: ignored, name of the hash key being deleted
|
|
|
|
*
|
|
|
|
* Provides identical functionality to virObjectUnref,
|
|
|
|
* but with the signature matching the virHashDataFree
|
|
|
|
* typedef.
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
void
|
2019-11-21 19:27:58 +00:00
|
|
|
virObjectFreeHashData(void *opaque)
|
2014-04-04 23:36:25 +00:00
|
|
|
{
|
|
|
|
virObjectUnref(opaque);
|
|
|
|
}
|
2015-04-29 09:54:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virObjectListFree:
|
|
|
|
* @list: A pointer to a NULL-terminated list of object pointers to free
|
|
|
|
*
|
|
|
|
* Unrefs all members of @list and frees the list itself.
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
void
|
|
|
|
virObjectListFree(void *list)
|
2015-04-29 09:54:58 +00:00
|
|
|
{
|
|
|
|
void **next;
|
|
|
|
|
|
|
|
if (!list)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (next = (void **) list; *next; next++)
|
|
|
|
virObjectUnref(*next);
|
|
|
|
|
|
|
|
VIR_FREE(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virObjectListFreeCount:
|
|
|
|
* @list: A pointer to a list of object pointers to freea
|
|
|
|
* @count: Number of elements in the list.
|
|
|
|
*
|
|
|
|
* Unrefs all members of @list and frees the list itself.
|
|
|
|
*/
|
2017-03-28 19:09:55 +00:00
|
|
|
void
|
|
|
|
virObjectListFreeCount(void *list,
|
|
|
|
size_t count)
|
2015-04-29 09:54:58 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (!list)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
virObjectUnref(((void **)list)[i]);
|
|
|
|
|
|
|
|
VIR_FREE(list);
|
|
|
|
}
|