[libvirt] [PATCH 1/2] virObjectUnref: Set pointer to NULL on dispose

Michal Privoznik mprivozn at redhat.com
Thu Nov 7 10:39:27 UTC 2013


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 at 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




More information about the libvir-list mailing list