Calling a function for children of a certain type is a recurring pattern in the QEMU code base. In order to avoid the need to setup the same boiler plate again and again, introduce a variant of object_child_foreach() that only considers children of the given type.
Signed-off-by: Greg Kurz <gr...@kaod.org> --- include/qom/object.h | 35 +++++++++++++++++++++++++++++++++++ qom/object.c | 30 +++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index 128d00c77fd6..e9e3c2eae8ed 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1728,6 +1728,41 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), int object_child_foreach_recursive(Object *obj, int (*fn)(Object *child, void *opaque), void *opaque); + +/** + * object_child_foreach_type: + * @obj: the object whose children will be navigated + * @typename: the type of child objects to consider + * @fn: the iterator function to be called + * @opaque: an opaque value that will be passed to the iterator + * + * This is similar to object_child_foreach, but it only calls @fn for + * child objects of the give @typename. + * + * Returns: The last value returned by @fn, or 0 if there is no child of + * the given @typename. + */ +int object_child_foreach_type(Object *obj, const char *typename, + int (*fn)(Object *child, void *opaque), + void *opaque); + +/** + * object_child_foreach_recursive_type: + * @obj: the object whose children will be navigated + * @typename: the type of child objects to consider + * @fn: the iterator function to be called + * @opaque: an opaque value that will be passed to the iterator + * + * This is similar to object_child_foreach_recursive, but it only calls + * @fn for child objects of the give @typename. + * + * Returns: The last value returned by @fn, or 0 if there is no child of + * the given @typename. + */ +int object_child_foreach_recursive_type(Object *obj, const char *typename, + int (*fn)(Object *child, void *opaque), + void *opaque); + /** * container_get: * @root: root of the #path, e.g., object_get_root() diff --git a/qom/object.c b/qom/object.c index 6fa9c619fac4..a2dec1261ff7 100644 --- a/qom/object.c +++ b/qom/object.c @@ -986,7 +986,7 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), enumerating_types = false; } -static int do_object_child_foreach(Object *obj, +static int do_object_child_foreach(Object *obj, const char *typename, int (*fn)(Object *child, void *opaque), void *opaque, bool recurse) { @@ -999,12 +999,14 @@ static int do_object_child_foreach(Object *obj, if (object_property_is_child(prop)) { Object *child = prop->opaque; - ret = fn(child, opaque); - if (ret != 0) { - break; + if (!typename || object_dynamic_cast(child, typename)) { + ret = fn(child, opaque); + if (ret != 0) { + break; + } } if (recurse) { - do_object_child_foreach(child, fn, opaque, true); + do_object_child_foreach(child, typename, fn, opaque, true); } } } @@ -1014,14 +1016,28 @@ static int do_object_child_foreach(Object *obj, int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), void *opaque) { - return do_object_child_foreach(obj, fn, opaque, false); + return do_object_child_foreach(obj, NULL, fn, opaque, false); } int object_child_foreach_recursive(Object *obj, int (*fn)(Object *child, void *opaque), void *opaque) { - return do_object_child_foreach(obj, fn, opaque, true); + return do_object_child_foreach(obj, NULL, fn, opaque, true); +} + +int object_child_foreach_type(Object *obj, const char *typename, + int (*fn)(Object *child, void *opaque), + void *opaque) +{ + return do_object_child_foreach(obj, typename, fn, opaque, false); +} + +int object_child_foreach_recursive_type(Object *obj, const char *typename, + int (*fn)(Object *child, void *opaque), + void *opaque) +{ + return do_object_child_foreach(obj, typename, fn, opaque, true); } static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)