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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list