Similarly to VIR_FREE() we can set the pointer passed to virObjectUnref
to NULL in case of disposing the object. However, to avoid overwriting
nearly thousands line of code, the virObjectUnref is turned into a macro
which passes the address of pointer and calls virObjectUnrefInternal
(the modified version of original virObjectUnref).
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/libvirt_private.syms | 2 +-
src/util/viridentity.c | 2 +-
src/util/virobject.c | 13 ++++++++-----
src/util/virobject.h | 5 ++++-
4 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 76016ca..25beda2 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1551,7 +1551,7 @@ virObjectLockableNew;
virObjectNew;
virObjectRef;
virObjectUnlock;
-virObjectUnref;
+virObjectUnrefInternal;
# util/virpci.h
diff --git a/src/util/viridentity.c b/src/util/viridentity.c
index 4f5127c..ae18f7c 100644
--- a/src/util/viridentity.c
+++ b/src/util/viridentity.c
@@ -60,7 +60,7 @@ static int virIdentityOnceInit(void)
return -1;
if (virThreadLocalInit(&virIdentityCurrent,
- (virThreadLocalCleanup)virObjectUnref) < 0) {
+ (virThreadLocalCleanup)virObjectUnrefInternal) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot initialize thread local for current
identity"));
return -1;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 61b5413..dab2500 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -235,23 +235,25 @@ static void virObjectLockableDispose(void *anyobj)
}
/**
- * virObjectUnref:
+ * virObjectUnrefInternal:
* @anyobj: any instance of virObjectPtr
*
* Decrement the reference count on @anyobj and if
* it hits zero, runs the "dispose" callback associated
- * with the object class and frees @anyobj.
+ * with the object class, frees @anyobj and set it to NULL.
*
* Returns true if the remaining reference count is
* non-zero, false if the object was disposed of
*/
-bool virObjectUnref(void *anyobj)
+bool virObjectUnrefInternal(void **anyobj)
{
- virObjectPtr obj = anyobj;
+ virObjectPtr obj;
- if (!obj)
+ if (!anyobj || !*anyobj)
return false;
+ obj = *anyobj;
+
bool lastRef = virAtomicIntDecAndTest(&obj->refs);
PROBE(OBJECT_UNREF, "obj=%p", obj);
if (lastRef) {
@@ -268,6 +270,7 @@ bool virObjectUnref(void *anyobj)
obj->magic = 0xDEADBEEF;
obj->klass = (void*)0xDEADBEEF;
VIR_FREE(obj);
+ *anyobj = NULL;
}
return !lastRef;
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 3a08f10..8dc50ba 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -69,7 +69,10 @@ bool virClassIsDerivedFrom(virClassPtr klass,
void *virObjectNew(virClassPtr klass)
ATTRIBUTE_NONNULL(1);
-bool virObjectUnref(void *obj);
+
+# define virObjectUnref(ptr) \
+ virObjectUnrefInternal((void *) (1 ? (const void *) &(ptr) : (ptr)))
+bool virObjectUnrefInternal(void **obj);
void *virObjectRef(void *obj);
bool virObjectIsClass(void *obj,
--
1.8.1.5