]> git.proxmox.com Git - mirror_qemu.git/commitdiff
qdev: move bus removal to object_unparent
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 23 Nov 2012 08:47:13 +0000 (09:47 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Mon, 26 Nov 2012 19:41:00 +0000 (13:41 -0600)
Add an ObjectClass method that is done at object_unparent time.  It
should remove any backlinks to the object in the composition tree,
so that object_delete will be able to drop the last reference and
free the object.

Use it for qdev buses.

Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
hw/qdev.c
include/qemu/object.h
qom/object.c

index 7ddcd242993df70e07f411c99c6cd890bcbcd220..f43717baa5c73b13f6b94748ac2ea48eb01ebe96 100644 (file)
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -705,9 +705,6 @@ static void device_finalize(Object *obj)
             qemu_opts_del(dev->opts);
         }
     }
-    if (dev->parent_bus) {
-        bus_remove_child(dev->parent_bus, dev);
-    }
 }
 
 static void device_class_base_init(ObjectClass *class, void *data)
@@ -720,6 +717,18 @@ static void device_class_base_init(ObjectClass *class, void *data)
     klass->props = NULL;
 }
 
+static void qdev_remove_from_bus(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+
+    bus_remove_child(dev->parent_bus, dev);
+}
+
+static void device_class_init(ObjectClass *class, void *data)
+{
+    class->unparent = qdev_remove_from_bus;
+}
+
 void device_reset(DeviceState *dev)
 {
     DeviceClass *klass = DEVICE_GET_CLASS(dev);
@@ -747,6 +756,7 @@ static TypeInfo device_type_info = {
     .instance_init = device_initfn,
     .instance_finalize = device_finalize,
     .class_base_init = device_class_base_init,
+    .class_init = device_class_init,
     .abstract = true,
     .class_size = sizeof(DeviceClass),
 };
index be707f1a36ae9d017ee2b3c206b10f5df21f16b0..232463b3c7983e7561355ccc3ea6892738dcf008 100644 (file)
@@ -229,6 +229,15 @@ typedef struct ObjectProperty
     QTAILQ_ENTRY(ObjectProperty) node;
 } ObjectProperty;
 
+/**
+ * ObjectUnparent:
+ * @obj: the object that is being removed from the composition tree
+ *
+ * Called when an object is being removed from the QOM composition tree.
+ * The function should remove any backlinks from children objects to @obj.
+ */
+typedef void (ObjectUnparent)(Object *obj);
+
 /**
  * ObjectClass:
  *
@@ -240,6 +249,8 @@ struct ObjectClass
     /*< private >*/
     Type type;
     GSList *interfaces;
+
+    ObjectUnparent *unparent;
 };
 
 /**
index 662ff7e093b80bd48f54afcba4dc1fe68ecc5d18..07495066d55a5473411de4f59ad18e21d5f1638a 100644 (file)
@@ -363,6 +363,9 @@ void object_unparent(Object *obj)
     if (obj->parent) {
         object_property_del_child(obj->parent, obj, NULL);
     }
+    if (obj->class->unparent) {
+        (obj->class->unparent)(obj);
+    }
 }
 
 static void object_deinit(Object *obj, TypeImpl *type)