From nobody Sat Feb 7 03:50:07 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1531470614666793.7698757350978; Fri, 13 Jul 2018 01:30:14 -0700 (PDT) Received: from localhost ([::1]:35867 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fdtSv-0003vQ-Jg for importer@patchew.org; Fri, 13 Jul 2018 04:30:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40262) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fdtQh-00029v-Bt for qemu-devel@nongnu.org; Fri, 13 Jul 2018 04:27:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fdtQg-0004E9-5Y for qemu-devel@nongnu.org; Fri, 13 Jul 2018 04:27:55 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:54408 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fdtQd-00049L-Ak; Fri, 13 Jul 2018 04:27:51 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D3ABB4075742; Fri, 13 Jul 2018 08:27:50 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-70.ams2.redhat.com [10.36.116.70]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2D1D12026D6B; Fri, 13 Jul 2018 08:27:47 +0000 (UTC) From: Thomas Huth To: qemu-devel@nongnu.org, Peter Maydell , Paolo Bonzini Date: Fri, 13 Jul 2018 10:27:29 +0200 Message-Id: <1531470464-21522-2-git-send-email-thuth@redhat.com> In-Reply-To: <1531470464-21522-1-git-send-email-thuth@redhat.com> References: <1531470464-21522-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Fri, 13 Jul 2018 08:27:50 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Fri, 13 Jul 2018 08:27:50 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v2 01/16] qom/object: Add a new function object_initialize_child() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , Alistair Francis , Markus Armbruster , Subbaraya Sundeep , Beniamino Galvani , qemu-arm@nongnu.org, "Edgar E. Iglesias" , =?UTF-8?q?Andreas=20F=C3=A4rber?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" A lot of code is using the object_initialize() function followed by a call to object_property_add_child() to add the newly initialized object as a chi= ld of the current object. Both functions increase the reference counter of the new object, but many spots that call these two functions then forget to drop one of the superfluous references. So the newly created object is often not cleaned up correctly when the parent is destroyed. In the worst case, this can cause crashes, e.g. because device objects are not correctly removed fr= om their parent_bus. Since this is a common pattern between many code spots, let's introdcue a new function that takes care of calling all three required initialization functions, first object_initialize(), then object_property_add_child() and finally object_unref(). And while we're at object.h, also fix some copy-n-paste errors in the comments there ("to store the area" --> "to store the error"). Signed-off-by: Thomas Huth Reviewed-by: Eduardo Habkost Reviewed-by: Paolo Bonzini --- include/qom/object.h | 23 +++++++++++++++++++++-- qom/object.c | 15 +++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index f3d2308..3362db0 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -749,6 +749,25 @@ int object_set_propv(Object *obj, void object_initialize(void *obj, size_t size, const char *typename); =20 /** + * object_initialize_child: + * @parentobj: The parent object to add a property to + * @propname: The name of the property + * @childobj: A pointer to the memory to be used for the object. + * @size: The maximum size available at @obj for the object. + * @type: The name of the type of the object to instantiate. + * @errp: If an error occurs, a pointer to an area to store the error + * + * This function will initialize an object. The memory for the object shou= ld + * have already been allocated. The object will then be added as child pro= perty + * to a parent with object_property_add_child() function. The returned obj= ect + * has a reference count of 1 (for the "child<...>" property from the pare= nt), + * so the object will get finalized automatically when the parent gets rem= oved. + */ +void object_initialize_child(Object *parentobj, const char *propname, + void *childobj, size_t size, const char *type, + Error **errp); + +/** * object_dynamic_cast: * @obj: The object to cast. * @typename: The @typename to cast to. @@ -1382,7 +1401,7 @@ Object *object_resolve_path_component(Object *parent,= const gchar *part); * @obj: the object to add a property to * @name: the name of the property * @child: the child object - * @errp: if an error occurs, a pointer to an area to store the area + * @errp: if an error occurs, a pointer to an area to store the error * * Child properties form the composition tree. All objects need to be a c= hild * of another object. Objects can only be a child of one object. @@ -1420,7 +1439,7 @@ void object_property_allow_set_link(const Object *, c= onst char *, * @child: a pointer to where the link object reference is stored * @check: callback to veto setting or NULL if the property is read-only * @flags: additional options for the link - * @errp: if an error occurs, a pointer to an area to store the area + * @errp: if an error occurs, a pointer to an area to store the error * * Links establish relationships between objects. Links are unidirectional * although two links can be combined to form a bidirectional relationship diff --git a/qom/object.c b/qom/object.c index 4609e34..7be7638 100644 --- a/qom/object.c +++ b/qom/object.c @@ -392,6 +392,21 @@ void object_initialize(void *data, size_t size, const = char *typename) object_initialize_with_type(data, size, type); } =20 +void object_initialize_child(Object *parentobj, const char *propname, + void *childobj, size_t size, const char *type, + Error **errp) +{ + object_initialize(childobj, size, type); + object_property_add_child(parentobj, propname, OBJECT(childobj), errp); + /* + * Since object_property_add_child added a reference to the child obje= ct, + * we can drop the reference added by object_initialize(), so the child + * property will own the only reference to the object. + */ + object_unref(OBJECT(childobj)); +} + + static inline bool object_property_is_child(ObjectProperty *prop) { return strstart(prop->type, "child<", NULL); --=20 1.8.3.1