[RFC PATCH v2 001/137] qom: Introduce object_new_child()

Alexander Graf <[email protected]>
Newsgroups org.nongnu.qemu-arm,org.nongnu.qemu-devel,org.nongnu.qemu-riscv
Message-ID <[email protected]>
We already have two ways of creating a QOM object with a parent set
from birth: object_initialize_child() for objects embedded in the
parent struct, and object_new_with_props() for heap-allocated objects
that also want a list of string properties applied.  What we do not
have is the plain heap-allocated dual of object_initialize_child():
create the object, add it as a child<> of a given parent under a given
name, and hand the reference to the parent.

Board and composite-device code that heap-allocates children today
therefore either open-codes object_new()+object_property_add_child()
+object_unref(), or skips the parenting step entirely and lets
device_set_realized() dump the object into /machine/unattached.

Add object_new_child(parent, id, typename) as that missing primitive.
The reference created by object_new() is transferred to the parent's
child<> property, so on return the sole reference is held by @parent
and the caller does not need to unref.  Later patches build the qdev
and per-bus creation helpers on top of this.

@id must be a valid QOM child<> property name: non-empty and
without the "/" QOM path separator.  It may contain the "[*]"
auto-index suffix; the qdev id_wellformed() grammar does not apply
here.  The compiler enforces non-NULL arguments via
__attribute__((nonnull)) instead of runtime asserts, as suggested by
Richard and Peter.

Link: https://lore.kernel.org/qemu-devel/[email protected]/
Suggested-by: Markus Armbruster <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
AI-used-for: code (refactoring)
Signed-off-by: Alexander Graf <[email protected]>
---
 include/qom/object.h | 32 ++++++++++++++++++++++++++++++++
 qom/object.c         | 12 ++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index 11f55613fc..299673d040 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -632,6 +632,38 @@ Object *object_new_with_class(ObjectClass *klass);
  */
 Object *object_new(const char *typename);
 
+/**
+ * object_new_child:
+ * @parent: the QOM composition-tree parent
+ * @id: the child<> property name; the object's canonical QOM path
+ *      becomes @parent's path plus "/" plus @id
+ * @typename: the name of the type of the object to instantiate
+ *
+ * Create a heap-allocated object and immediately add it to the QOM
+ * composition tree as a child of @parent.
+ *
+ * This is the heap-allocated dual of object_initialize_child(): use
+ * this when the child is a pointer member of the parent, and use
+ * object_initialize_child() when the child is embedded in the parent
+ * struct.  See also object_new_with_props() for the variant that
+ * additionally sets a list of properties.
+ *
+ * The reference returned by object_new() is transferred to the child<>
+ * property of @parent, so the object has a reference count of 1 held
+ * by @parent, and the caller does not need to unref.
+ *
+ * The @id assert is a sanity check on the caller's string literal;
+ * the authoritative uniqueness check is object_property_add_child(),
+ * which will error_abort() on a duplicate @id under @parent.  Use
+ * the "[*]" auto-index suffix when multiple children of the same
+ * kind may be created.
+ *
+ * Returns: the newly allocated, instantiated and parented object.
+ */
+Object *object_new_child(Object *parent, const char *id,
+                         const char *typename)
+    __attribute__((nonnull(1, 2, 3), returns_nonnull));
+
 /**
  * object_new_with_props:
  * @typename:  The name of the type of the object to instantiate.
diff --git a/qom/object.c b/qom/object.c
index f79b2cf361..64b0faf1f5 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -718,6 +718,18 @@ Object *object_new(const char *typename)
     return object_new_with_type(ti);
 }
 
+Object *object_new_child(Object *parent, const char *id,
+                         const char *typename)
+{
+    Object *obj;
+
+    g_assert(id[0] && !strchr(id, '/'));
+
+    obj = object_new(typename);
+    object_property_add_child(parent, id, obj);
+    object_unref(obj);
+    return obj;
+}
 
 Object *object_new_with_props(const char *typename,
                               Object *parent,
-- 
2.47.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.