qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 21/23] object: sure up reference counting


From: Anthony Liguori
Subject: [Qemu-devel] [PATCH 21/23] object: sure up reference counting
Date: Mon, 30 Jan 2012 15:08:59 -0600

Now we have the following behavior:

1) object_new() returns an object with ref = 1
2) object_initialize() does not increase the reference count (ref may be 0).
3) object_deref() will finalize the object when ref = 0.  it does not free the
   memory associated with the object.
4) both link and child properties correctly set the reference count.

The expected usage is the following:

1) child devices should generally be created via object_initialize() using
   memory from the parent device.  Adding the object as a child property will
   take ownership of the object and tie the child's life cycle to the parent.

2) If a child device is created via qdev_create() or some other form of
   object_new(), there must be an object_delete() call in the parent device's
   finalize function.

Signed-off-by: Anthony Liguori <address@hidden>
---
 qom/object.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index 4c3ff83..1941adb 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -331,6 +331,8 @@ void object_finalize(void *data)
 
     object_deinit(obj, ti);
     object_property_del_all(obj);
+
+    g_assert(obj->ref == 0);
 }
 
 Object *object_new_with_type(Type type)
@@ -341,6 +343,7 @@ Object *object_new_with_type(Type type)
 
     obj = g_malloc(type->instance_size);
     object_initialize_with_type(obj, type);
+    object_ref(obj);
 
     return obj;
 }
@@ -354,7 +357,8 @@ Object *object_new(const char *typename)
 
 void object_delete(Object *obj)
 {
-    object_finalize(obj);
+    object_unref(obj);
+    g_assert(obj->ref == 0);
     g_free(obj);
 }
 
@@ -552,6 +556,10 @@ void object_unref(Object *obj)
 {
     g_assert(obj->ref > 0);
     obj->ref--;
+
+    if (obj->ref == 0) {
+        object_finalize(obj);
+    }
 }
 
 void object_property_add(Object *obj, const char *name, const char *type,
@@ -668,6 +676,14 @@ static void object_get_child_property(Object *obj, Visitor 
*v, void *opaque,
     g_free(path);
 }
 
+static void object_finalize_child_property(Object *obj, const char *name,
+                                           void *opaque)
+{
+    Object *child = opaque;
+
+    object_unref(child);
+}
+
 void object_property_add_child(Object *obj, const char *name,
                                Object *child, Error **errp)
 {
@@ -676,7 +692,7 @@ void object_property_add_child(Object *obj, const char 
*name,
     type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
 
     object_property_add(obj, name, type, object_get_child_property,
-                        NULL, NULL, child, errp);
+                        NULL, object_finalize_child_property, child, errp);
 
     object_ref(child);
     g_assert(child->parent == NULL);
-- 
1.7.4.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]