@@ -1517,6 +1517,7 @@ static int pci_unplug_device(DeviceState *qdev)
qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev)));
return -1;
}
+ object_unparent(OBJECT(dev));
return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
PCI_HOTPLUG_DISABLED);
}
@@ -222,6 +222,7 @@ void qbus_reset_all_fn(void *opaque)
int qdev_simple_unplug_cb(DeviceState *dev)
{
/* just zap it */
+ object_unparent(OBJECT(dev));
qdev_free(dev);
return 0;
}
@@ -524,7 +524,9 @@ void object_property_add(Object *obj, const char *name, const char *type,
ObjectPropertyRelease *release,
void *opaque, struct Error **errp);
-void object_property_del(Object *obj, const char *name, Error **errp);
+void object_property_del(Object *obj, const char *name, struct Error **errp);
+
+void object_unparent(Object *obj);
/**
* object_property_get:
@@ -304,6 +304,13 @@ static void object_property_del_child(Object *obj, Object *child, Error **errp)
}
}
+void object_unparent(Object *obj)
+{
+ if (obj->parent) {
+ object_property_del_child(obj->parent, obj, NULL);
+ }
+}
+
static void object_deinit(Object *obj, TypeImpl *type)
{
if (type->instance_finalize) {
@@ -319,9 +326,8 @@ static void object_deinit(Object *obj, TypeImpl *type)
if (type_has_parent(type)) {
object_deinit(obj, type_get_parent(type));
}
- if (obj->parent) {
- object_property_del_child(obj->parent, obj, NULL);
- }
+
+ object_unparent(obj);
}
void object_finalize(void *data)
@@ -557,6 +563,7 @@ void object_unref(Object *obj)
g_assert(obj->ref > 0);
obj->ref--;
+ /* parent always holds a reference to its children */
if (obj->ref == 0) {
object_finalize(obj);
}