From nobody Sun Feb 8 21:26:31 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) client-ip=207.211.31.81; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1589910492; cv=none; d=zohomail.com; s=zohoarc; b=QJRM5MHU+LTTe3brgYHnGZus6Wba8xWpfBCUoJhom8IqGQdUWfLT6qk6pVvorNnFueohdOv7GBVPVK81C8e3GzlDQQFQJ8jMXpaDUjMPkXWIopxySDM90oD/HojPaj0oQxMpgnuDaXsWV7wG/QZ60uwuuXpoIzDoTNLMufp5NFw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589910492; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=KC0a1zybnr6TqD/D9zvC8kVqJ4QGu8XL1o92Wzmpg/w=; b=LuZpfPyWgvngtfmZK5QPWGl1TuZLWfe7mqcH/Zz0CGfbFrGN6UQZqmzTIqWpEJ04yFar7AKevjyTHs+XEP2NnZsnQd2wqau/WvybZr7Aliw4PF6sppGu9ksNID9XI2jugVTikvNNhwYFGfNdX0eVp/No7VSuzemvQciR1wdKhqM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) by mx.zohomail.com with SMTPS id 1589910492090712.852659672668; Tue, 19 May 2020 10:48:12 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-357-s7Y_-tt9NsW6obWCoIx1CA-1; Tue, 19 May 2020 13:48:08 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E518F100CCC1; Tue, 19 May 2020 17:48:02 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C0A6560C84; Tue, 19 May 2020 17:48:02 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 8F945180954D; Tue, 19 May 2020 17:48:02 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 04JHljg4014525 for ; Tue, 19 May 2020 13:47:45 -0400 Received: by smtp.corp.redhat.com (Postfix) id B1F7C5D9CD; Tue, 19 May 2020 17:47:45 +0000 (UTC) Received: from catbus.gsslab.fab.redhat.com (mustard.gsslab.fab.redhat.com [10.33.8.112]) by smtp.corp.redhat.com (Postfix) with ESMTP id 204785D9C5; Tue, 19 May 2020 17:47:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589910490; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=KC0a1zybnr6TqD/D9zvC8kVqJ4QGu8XL1o92Wzmpg/w=; b=XM8B2NFTalMloV3edw4aDhCAXW6hgIpwhgqZr+X14aeK7PuOMj+TNpUev17yH0R3CbgHU0 F2TZTRTQb2H0TsjzEFu+OSDSaVYd2Qp+r9nGk0TG+FDhtr3941La+b8ZUy9Y0ps3bkEMM/ qQkHpQNa/Qb9yhJdfn5NS9JEJbCepYo= X-MC-Unique: s7Y_-tt9NsW6obWCoIx1CA-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Subject: [libvirt PATCH 6/6] src: make virObject inherit from GObject Date: Tue, 19 May 2020 18:41:31 +0100 Message-Id: <20200519174131.91783-7-berrange@redhat.com> In-Reply-To: <20200519174131.91783-1-berrange@redhat.com> References: <20200519174131.91783-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) To avoid bugs with mixing of g_object_(ref|unref) vs virObject(Ref|Unref), we want every virObject to be a GObject. Signed-off-by: Daniel P. Berrang=C3=A9 --- src/util/virobject.c | 141 +++++++++++++++++++++++++------------------ src/util/virobject.h | 25 +++----- 2 files changed, 90 insertions(+), 76 deletions(-) diff --git a/src/util/virobject.c b/src/util/virobject.c index 4060d7307b..3f0bcc38ea 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -39,6 +39,7 @@ static unsigned int magicCounter =3D 0xCAFE0000; struct _virClass { virClassPtr parent; =20 + GType type; unsigned int magic; char *name; size_t objectSize; @@ -46,25 +47,28 @@ struct _virClass { virObjectDisposeCallback dispose; }; =20 -#define VIR_OBJECT_NOTVALID(obj) (!obj || ((obj->u.s.magic & 0xFFFF0000) != =3D 0xCAFE0000)) +typedef struct _virObjectPrivate virObjectPrivate; +struct _virObjectPrivate { + virClassPtr klass; +}; + + +G_DEFINE_TYPE_WITH_PRIVATE(virObject, vir_object, G_TYPE_OBJECT) + +#define VIR_OBJECT_NOTVALID(obj) (!obj || !VIR_IS_OBJECT(obj)) =20 #define VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, objclass) \ do { \ virObjectPtr obj =3D anyobj; \ - if (VIR_OBJECT_NOTVALID(obj)) { \ - if (!obj) \ - VIR_WARN("Object cannot be NULL"); \ - else \ - VIR_WARN("Object %p has a bad magic number %X", \ - obj, obj->u.s.magic); \ - } else { \ + if (!obj) \ + VIR_WARN("Object cannot be NULL"); \ + if (VIR_OBJECT_NOTVALID(obj)) \ VIR_WARN("Object %p (%s) is not a %s instance", \ - anyobj, obj->klass->name, #objclass); \ - } \ + anyobj, g_type_name_from_instance((void*)anyobj), #ob= jclass); \ } while (0) =20 =20 -static virClassPtr virObjectClass; +static virClassPtr virObjectClassImpl; static virClassPtr virObjectLockableClass; static virClassPtr virObjectRWLockableClass; =20 @@ -74,17 +78,17 @@ static void virObjectRWLockableDispose(void *anyobj); static int virObjectOnceInit(void) { - if (!(virObjectClass =3D virClassNew(NULL, - "virObject", - sizeof(virObject), - 0, - NULL))) + if (!(virObjectClassImpl =3D virClassNew(NULL, + "virObject", + sizeof(virObject), + 0, + NULL))) return -1; =20 - if (!VIR_CLASS_NEW(virObjectLockable, virObjectClass)) + if (!VIR_CLASS_NEW(virObjectLockable, virObjectClassImpl)) return -1; =20 - if (!VIR_CLASS_NEW(virObjectRWLockable, virObjectClass)) + if (!VIR_CLASS_NEW(virObjectRWLockable, virObjectClassImpl)) return -1; =20 return 0; @@ -104,7 +108,7 @@ virClassForObject(void) if (virObjectInitialize() < 0) return NULL; =20 - return virObjectClass; + return virObjectClassImpl; } =20 =20 @@ -138,6 +142,14 @@ virClassForObjectRWLockable(void) } =20 =20 +static void virClassDummyInit(void *klass G_GNUC_UNUSED) +{ +} + +static void virObjectDummyInit(void *obj G_GNUC_UNUSED) +{ +} + /** * virClassNew: * @parent: the parent class @@ -177,25 +189,26 @@ virClassNew(virClassPtr parent, return NULL; } =20 - if (VIR_ALLOC(klass) < 0) - goto error; - + klass =3D g_new0(virClass, 1); klass->parent =3D parent; klass->magic =3D g_atomic_int_add(&magicCounter, 1); - if (klass->magic > 0xCAFEFFFF) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("too many object classes defined")); - goto error; - } klass->name =3D g_strdup(name); klass->objectSize =3D objectSize; + if (parent =3D=3D NULL) { + klass->type =3D vir_object_get_type(); + } else { + klass->type =3D + g_type_register_static_simple(parent->type, + name, + sizeof(virObjectClass), + (GClassInitFunc)virClassDummyIni= t, + objectSize, + (GInstanceInitFunc)virObjectDumm= yInit, + 0); + } klass->dispose =3D dispose; =20 return klass; - - error: - VIR_FREE(klass); - return NULL; } =20 =20 @@ -237,17 +250,13 @@ void * virObjectNew(virClassPtr klass) { virObjectPtr obj =3D NULL; + virObjectPrivate *priv; =20 - if (VIR_ALLOC_VAR(obj, - char, - klass->objectSize - sizeof(virObject)) < 0) - return NULL; - - obj->u.s.magic =3D klass->magic; - obj->klass =3D klass; - g_atomic_int_set(&obj->u.s.refs, 1); + obj =3D g_object_new(klass->type, NULL); =20 - PROBE(OBJECT_NEW, "obj=3D%p classname=3D%s", obj, obj->klass->name); + priv =3D vir_object_get_instance_private(obj); + priv->klass =3D klass; + PROBE(OBJECT_NEW, "obj=3D%p classname=3D%s", obj, priv->klass->name); =20 return obj; } @@ -304,6 +313,33 @@ virObjectRWLockableNew(virClassPtr klass) return obj; } =20 +static void vir_object_finalize(GObject *gobj) +{ + PROBE(OBJECT_DISPOSE, "obj=3D%p", gobj); + virObjectPtr obj =3D VIR_OBJECT(gobj); + virObjectPrivate *priv =3D vir_object_get_instance_private(obj); + + virClassPtr klass =3D priv->klass; + while (klass) { + if (klass->dispose) + klass->dispose(obj); + klass =3D klass->parent; + } + + G_OBJECT_CLASS(vir_object_parent_class)->finalize(gobj); +} + +static void vir_object_init(virObject *obj G_GNUC_UNUSED) +{ +} + + +static void vir_object_class_init(virObjectClass *klass) +{ + GObjectClass *obj =3D G_OBJECT_CLASS(klass); + + obj->finalize =3D vir_object_finalize; +} =20 static void virObjectLockableDispose(void *anyobj) @@ -340,23 +376,8 @@ virObjectUnref(void *anyobj) if (VIR_OBJECT_NOTVALID(obj)) return; =20 - bool lastRef =3D !!g_atomic_int_dec_and_test(&obj->u.s.refs); + g_object_unref(anyobj); PROBE(OBJECT_UNREF, "obj=3D%p", obj); - if (lastRef) { - PROBE(OBJECT_DISPOSE, "obj=3D%p", obj); - virClassPtr klass =3D obj->klass; - while (klass) { - if (klass->dispose) - klass->dispose(obj); - klass =3D klass->parent; - } - - /* Clear & poison object */ - memset(obj, 0, obj->klass->objectSize); - obj->u.s.magic =3D 0xDEADBEEF; - obj->klass =3D (void*)0xDEADBEEF; - VIR_FREE(obj); - } } =20 =20 @@ -376,7 +397,8 @@ virObjectRef(void *anyobj) =20 if (VIR_OBJECT_NOTVALID(obj)) return NULL; - g_atomic_int_add(&obj->u.s.refs, 1); + + g_object_ref(obj); PROBE(OBJECT_REF, "obj=3D%p", obj); return anyobj; } @@ -539,10 +561,13 @@ virObjectIsClass(void *anyobj, virClassPtr klass) { virObjectPtr obj =3D anyobj; + virObjectPrivate *priv; + if (VIR_OBJECT_NOTVALID(obj)) return false; =20 - return virClassIsDerivedFrom(obj->klass, klass); + priv =3D vir_object_get_instance_private(obj); + return virClassIsDerivedFrom(priv->klass, klass); } =20 =20 diff --git a/src/util/virobject.h b/src/util/virobject.h index cfedb19b13..18a9f098a6 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -24,6 +24,8 @@ #include "internal.h" #include "virthread.h" =20 +#include + typedef struct _virClass virClass; typedef virClass *virClassPtr; =20 @@ -38,22 +40,11 @@ typedef virObjectRWLockable *virObjectRWLockablePtr; =20 typedef void (*virObjectDisposeCallback)(void *obj); =20 -/* Most code should not play with the contents of this struct; however, - * the struct itself is public so that it can be embedded as the first - * field of a subclassed object. */ -struct _virObject { - /* Ensure correct alignment of this and all subclasses, even on - * platforms where 'long long' or function pointers have stricter - * requirements than 'void *'. */ - union { - long long dummy_align1; - void (*dummy_align2) (void); - struct { - unsigned int magic; - int refs; - } s; - } u; - virClassPtr klass; +#define VIR_TYPE_OBJECT vir_object_get_type() +G_DECLARE_DERIVABLE_TYPE(virObject, vir_object, VIR, OBJECT, GObject); + +struct _virObjectClass { + GObjectClass parent; }; =20 struct _virObjectLockable { @@ -109,8 +100,6 @@ virObjectNew(virClassPtr klass) void virObjectUnref(void *obj); =20 -G_DEFINE_AUTOPTR_CLEANUP_FUNC(virObject, virObjectUnref); - void * virObjectRef(void *obj); =20 --=20 2.24.1