From: Liu Ping Fan <pingf...@linux.vnet.ibm.com> Some func should be called after iteration over object's children, for example, func will put ref of object.
Signed-off-by: Liu Ping Fan <pingf...@linux.vnet.ibm.com> --- hw/qdev.c | 30 ++++++++++++++++++++++-------- hw/qdev.h | 4 ++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index b5b74b9..ad618dd 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -230,13 +230,13 @@ static int qbus_reset_one(BusState *bus, void *opaque) void qdev_reset_all(DeviceState *dev) { - qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL); + qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, 0); } void qbus_reset_all_fn(void *opaque) { BusState *bus = opaque; - qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL); + qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, 0); } /* can be used as ->unplug() callback for the simple cases */ @@ -342,12 +342,12 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name) } int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, - qbus_walkerfn *busfn, void *opaque) + qbus_walkerfn *busfn, void *opaque, int after) { BusChild *kid; int err; - if (busfn) { + if ((after == 0) && busfn) { err = busfn(bus, opaque); if (err) { return err; @@ -355,22 +355,29 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, } QTAILQ_FOREACH(kid, &bus->children, sibling) { - err = qdev_walk_children(kid->child, devfn, busfn, opaque); + err = qdev_walk_children(kid->child, devfn, busfn, opaque, after); if (err < 0) { return err; } } + if ((after != 0) && busfn) { + err = busfn(bus, opaque); + if (err) { + return err; + } + } + return 0; } int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, - qbus_walkerfn *busfn, void *opaque) + qbus_walkerfn *busfn, void *opaque, int after) { BusState *bus; int err; - if (devfn) { + if ((after == 0) && devfn) { err = devfn(dev, opaque); if (err) { return err; @@ -378,12 +385,19 @@ int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, } QLIST_FOREACH(bus, &dev->child_bus, sibling) { - err = qbus_walk_children(bus, devfn, busfn, opaque); + err = qbus_walk_children(bus, devfn, busfn, opaque, after); if (err < 0) { return err; } } + if ((after != 0) && devfn) { + err = devfn(dev, opaque); + if (err) { + return err; + } + } + return 0; } diff --git a/hw/qdev.h b/hw/qdev.h index d699194..9fc8b46 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -195,9 +195,9 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam * < 0 if either devfn or busfn terminate walk somewhere in cursion, * 0 otherwise. */ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, - qbus_walkerfn *busfn, void *opaque); + qbus_walkerfn *busfn, void *opaque, int after); int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, - qbus_walkerfn *busfn, void *opaque); + qbus_walkerfn *busfn, void *opaque, int after); void qdev_reset_all(DeviceState *dev); void qbus_reset_all_fn(void *opaque); -- 1.7.4.4