[RFC PATCH v2 003/137] qdev: Reintroduce qdev_new() with a mandatory QOM parent

Alexander Graf <[email protected]>
Newsgroups org.nongnu.qemu-arm,org.nongnu.qemu-devel,org.nongnu.qemu-riscv
Message-ID <[email protected]>
The previous commit vacated the qdev_new()/qdev_try_new() names.
Reintroduce them with the signature we actually want:

  DeviceState *qdev_new(Object *parent, const char *id,
                        const char *type);

which is the qdev-layer, heap-allocated dual of
object_initialize_child(): the returned device is created and
immediately added to the QOM composition tree as a child of @parent
under @id.

Refcount contract: the initial reference is transferred to the
child<> property of @parent, so on return the caller does not hold a
reference.  Pair with qdev_realize() (not qdev_realize_and_unref()),
matching object_initialize_child()'s convention.

qdev_new_orphan() remains for callers that set the parent themselves
before realize (notably qdev_device_add(), which parents under
/machine/peripheral via qdev_set_id()).  Later patches convert the
remaining orphan callers subsystem by subsystem.

Suggested-by: Markus Armbruster <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
AI-used-for: code (refactoring)
Signed-off-by: Alexander Graf <[email protected]>
---
 hw/core/qdev.c         | 20 ++++++++++++++++++++
 include/hw/core/qdev.h | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 8a8d206a02..947ba7db80 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -145,6 +145,26 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp)
     return true;
 }
 
+DeviceState *qdev_new(Object *parent, const char *id, const char *type)
+{
+    return DEVICE(object_new_child(parent, id, type));
+}
+
+DeviceState *qdev_try_new(Object *parent, const char *id, const char *type)
+{
+    ObjectClass *oc = module_object_class_by_name(type);
+    Object *obj;
+
+    if (!oc) {
+        return NULL;
+    }
+    obj = object_new_with_class(oc);
+    g_assert(id[0] && !strchr(id, '/'));
+    object_property_add_child(parent, id, obj);
+    object_unref(obj);
+    return DEVICE(obj);
+}
+
 DeviceState *qdev_new_orphan(const char *name)
 {
     return DEVICE(object_new(name));
diff --git a/include/hw/core/qdev.h b/include/hw/core/qdev.h
index 839c1b4147..e692a1d48e 100644
--- a/include/hw/core/qdev.h
+++ b/include/hw/core/qdev.h
@@ -406,6 +406,40 @@ struct BusState {
 
 /*** Board API.  This should go away once we have a machine config file.  ***/
 
+/**
+ * qdev_new: Create a device and parent it in the QOM composition tree
+ * @parent: the QOM parent (usually the machine or containing device)
+ * @id: child<> property name; the device's canonical QOM path becomes
+ *      @parent's path plus "/" plus @id
+ * @type: device type to create (we assert() that this type exists)
+ *
+ * Heap-allocated counterpart to object_initialize_child().  This
+ * allocates and initializes the device state and immediately adds it
+ * as a child of @parent, ready for the caller to set properties and
+ * then realize.
+ *
+ * The reference count of the returned device is 1, held by @parent's
+ * child<> property.  The caller therefore does not hold a reference
+ * and pairs this with qdev_realize() (NOT qdev_realize_and_unref()).
+ *
+ * Return: a derived DeviceState, owned by @parent.
+ */
+DeviceState *qdev_new(Object *parent, const char *id, const char *type);
+
+/**
+ * qdev_try_new: Try to create a parented device on the heap
+ * @parent: the QOM parent
+ * @id: child<> property name
+ * @type: device type to create
+ *
+ * This is like qdev_new(), except it returns %NULL when @type does
+ * not exist, rather than asserting.
+ *
+ * Return: a derived DeviceState owned by @parent, or NULL if @type
+ * does not exist.
+ */
+DeviceState *qdev_try_new(Object *parent, const char *id, const char *type);
+
 /**
  * qdev_new_orphan: Create a device on the heap
  * @name: device type to create (we assert() that this type exists)
-- 
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.