240 lines
8.8 KiB
Diff
240 lines
8.8 KiB
Diff
|
From 08e7c4a3d0e739b8ff0f236d12e51dc394ec5b88 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||
|
Date: Fri, 8 Jan 2021 07:40:52 -0500
|
||
|
Subject: [PATCH 01/10] qapi: enable use of g_autoptr with QAPI types
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||
|
Message-id: <20210108074101.290008-2-marcandre.lureau@redhat.com>
|
||
|
Patchwork-id: 100520
|
||
|
O-Subject: [RHEL-8.3.0.z qemu-kvm PATCH 01/10] qapi: enable use of g_autoptr with QAPI types
|
||
|
Bugzilla: 1913818
|
||
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||
|
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||
|
|
||
|
From: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||
|
|
||
|
From: Daniel P. Berrangé <berrange@redhat.com>
|
||
|
|
||
|
Currently QAPI generates a type and function for free'ing it:
|
||
|
|
||
|
typedef struct QCryptoBlockCreateOptions QCryptoBlockCreateOptions;
|
||
|
void qapi_free_QCryptoBlockCreateOptions(QCryptoBlockCreateOptions *obj);
|
||
|
|
||
|
This is used in the traditional manner:
|
||
|
|
||
|
QCryptoBlockCreateOptions *opts = NULL;
|
||
|
|
||
|
opts = g_new0(QCryptoBlockCreateOptions, 1);
|
||
|
|
||
|
....do stuff with opts...
|
||
|
|
||
|
qapi_free_QCryptoBlockCreateOptions(opts);
|
||
|
|
||
|
Since bumping the min glib to 2.48, QEMU has incrementally adopted the
|
||
|
use of g_auto/g_autoptr. This allows the compiler to run a function to
|
||
|
free a variable when it goes out of scope, the benefit being the
|
||
|
compiler can guarantee it is freed in all possible code ptahs.
|
||
|
|
||
|
This benefit is applicable to QAPI types too, and given the seriously
|
||
|
long method names for some qapi_free_XXXX() functions, is much less
|
||
|
typing. This change thus makes the code generator emit:
|
||
|
|
||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlockCreateOptions,
|
||
|
qapi_free_QCryptoBlockCreateOptions)
|
||
|
|
||
|
The above code example now becomes
|
||
|
|
||
|
g_autoptr(QCryptoBlockCreateOptions) opts = NULL;
|
||
|
|
||
|
opts = g_new0(QCryptoBlockCreateOptions, 1);
|
||
|
|
||
|
....do stuff with opts...
|
||
|
|
||
|
Note, if the local pointer needs to live beyond the scope holding the
|
||
|
variable, then g_steal_pointer can be used. This is useful to return the
|
||
|
pointer to the caller in the success codepath, while letting it be freed
|
||
|
in all error codepaths.
|
||
|
|
||
|
return g_steal_pointer(&opts);
|
||
|
|
||
|
The crypto/block.h header needs updating to avoid symbol clash now that
|
||
|
the g_autoptr support is a standard QAPI feature.
|
||
|
|
||
|
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||
|
Message-Id: <20200723153845.2934357-1-berrange@redhat.com>
|
||
|
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
||
|
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||
|
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
||
|
|
||
|
(cherry picked from commit 221db5daf6b3666f1c8e4ca06ae45892e99a112f)
|
||
|
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||
|
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||
|
---
|
||
|
docs/devel/qapi-code-gen.txt | 2 ++
|
||
|
scripts/qapi/types.py | 1 +
|
||
|
tests/test-qobject-input-visitor.c | 23 +++++++----------------
|
||
|
3 files changed, 10 insertions(+), 16 deletions(-)
|
||
|
|
||
|
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
|
||
|
index 45c93a43cc3..ca59c695fac 100644
|
||
|
--- a/docs/devel/qapi-code-gen.txt
|
||
|
+++ b/docs/devel/qapi-code-gen.txt
|
||
|
@@ -1278,6 +1278,7 @@ Example:
|
||
|
};
|
||
|
|
||
|
void qapi_free_UserDefOne(UserDefOne *obj);
|
||
|
+ G_DEFINE_AUTOPTR_CLEANUP_FUNC(UserDefOne, qapi_free_UserDefOne)
|
||
|
|
||
|
struct UserDefOneList {
|
||
|
UserDefOneList *next;
|
||
|
@@ -1285,6 +1286,7 @@ Example:
|
||
|
};
|
||
|
|
||
|
void qapi_free_UserDefOneList(UserDefOneList *obj);
|
||
|
+ G_DEFINE_AUTOPTR_CLEANUP_FUNC(UserDefOneList, qapi_free_UserDefOneList)
|
||
|
|
||
|
struct q_obj_my_command_arg {
|
||
|
UserDefOneList *arg1;
|
||
|
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
|
||
|
index d8751daa049..c3be141dc90 100644
|
||
|
--- a/scripts/qapi/types.py
|
||
|
+++ b/scripts/qapi/types.py
|
||
|
@@ -213,6 +213,7 @@ def gen_type_cleanup_decl(name):
|
||
|
ret = mcgen('''
|
||
|
|
||
|
void qapi_free_%(c_name)s(%(c_name)s *obj);
|
||
|
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(%(c_name)s, qapi_free_%(c_name)s)
|
||
|
''',
|
||
|
c_name=c_name(name))
|
||
|
return ret
|
||
|
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
|
||
|
index 6bacabf0632..e41b91a2a6f 100644
|
||
|
--- a/tests/test-qobject-input-visitor.c
|
||
|
+++ b/tests/test-qobject-input-visitor.c
|
||
|
@@ -417,7 +417,7 @@ static void test_visitor_in_struct(TestInputVisitorData *data,
|
||
|
static void test_visitor_in_struct_nested(TestInputVisitorData *data,
|
||
|
const void *unused)
|
||
|
{
|
||
|
- UserDefTwo *udp = NULL;
|
||
|
+ g_autoptr(UserDefTwo) udp = NULL;
|
||
|
Visitor *v;
|
||
|
|
||
|
v = visitor_input_test_init(data, "{ 'string0': 'string0', "
|
||
|
@@ -433,8 +433,6 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
|
||
|
g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
|
||
|
g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
|
||
|
g_assert(udp->dict1->has_dict3 == false);
|
||
|
-
|
||
|
- qapi_free_UserDefTwo(udp);
|
||
|
}
|
||
|
|
||
|
static void test_visitor_in_list(TestInputVisitorData *data,
|
||
|
@@ -546,7 +544,7 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
|
||
|
const void *unused)
|
||
|
{
|
||
|
Visitor *v;
|
||
|
- UserDefFlatUnion *tmp;
|
||
|
+ g_autoptr(UserDefFlatUnion) tmp = NULL;
|
||
|
UserDefUnionBase *base;
|
||
|
|
||
|
v = visitor_input_test_init(data,
|
||
|
@@ -563,8 +561,6 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
|
||
|
|
||
|
base = qapi_UserDefFlatUnion_base(tmp);
|
||
|
g_assert(&base->enum1 == &tmp->enum1);
|
||
|
-
|
||
|
- qapi_free_UserDefFlatUnion(tmp);
|
||
|
}
|
||
|
|
||
|
static void test_visitor_in_alternate(TestInputVisitorData *data,
|
||
|
@@ -690,7 +686,7 @@ static void test_list_union_integer_helper(TestInputVisitorData *data,
|
||
|
const void *unused,
|
||
|
UserDefListUnionKind kind)
|
||
|
{
|
||
|
- UserDefListUnion *cvalue = NULL;
|
||
|
+ g_autoptr(UserDefListUnion) cvalue = NULL;
|
||
|
Visitor *v;
|
||
|
GString *gstr_list = g_string_new("");
|
||
|
GString *gstr_union = g_string_new("");
|
||
|
@@ -782,7 +778,6 @@ static void test_list_union_integer_helper(TestInputVisitorData *data,
|
||
|
|
||
|
g_string_free(gstr_union, true);
|
||
|
g_string_free(gstr_list, true);
|
||
|
- qapi_free_UserDefListUnion(cvalue);
|
||
|
}
|
||
|
|
||
|
static void test_visitor_in_list_union_int(TestInputVisitorData *data,
|
||
|
@@ -851,7 +846,7 @@ static void test_visitor_in_list_union_uint64(TestInputVisitorData *data,
|
||
|
static void test_visitor_in_list_union_bool(TestInputVisitorData *data,
|
||
|
const void *unused)
|
||
|
{
|
||
|
- UserDefListUnion *cvalue = NULL;
|
||
|
+ g_autoptr(UserDefListUnion) cvalue = NULL;
|
||
|
boolList *elem = NULL;
|
||
|
Visitor *v;
|
||
|
GString *gstr_list = g_string_new("");
|
||
|
@@ -879,13 +874,12 @@ static void test_visitor_in_list_union_bool(TestInputVisitorData *data,
|
||
|
|
||
|
g_string_free(gstr_union, true);
|
||
|
g_string_free(gstr_list, true);
|
||
|
- qapi_free_UserDefListUnion(cvalue);
|
||
|
}
|
||
|
|
||
|
static void test_visitor_in_list_union_string(TestInputVisitorData *data,
|
||
|
const void *unused)
|
||
|
{
|
||
|
- UserDefListUnion *cvalue = NULL;
|
||
|
+ g_autoptr(UserDefListUnion) cvalue = NULL;
|
||
|
strList *elem = NULL;
|
||
|
Visitor *v;
|
||
|
GString *gstr_list = g_string_new("");
|
||
|
@@ -914,7 +908,6 @@ static void test_visitor_in_list_union_string(TestInputVisitorData *data,
|
||
|
|
||
|
g_string_free(gstr_union, true);
|
||
|
g_string_free(gstr_list, true);
|
||
|
- qapi_free_UserDefListUnion(cvalue);
|
||
|
}
|
||
|
|
||
|
#define DOUBLE_STR_MAX 16
|
||
|
@@ -922,7 +915,7 @@ static void test_visitor_in_list_union_string(TestInputVisitorData *data,
|
||
|
static void test_visitor_in_list_union_number(TestInputVisitorData *data,
|
||
|
const void *unused)
|
||
|
{
|
||
|
- UserDefListUnion *cvalue = NULL;
|
||
|
+ g_autoptr(UserDefListUnion) cvalue = NULL;
|
||
|
numberList *elem = NULL;
|
||
|
Visitor *v;
|
||
|
GString *gstr_list = g_string_new("");
|
||
|
@@ -957,7 +950,6 @@ static void test_visitor_in_list_union_number(TestInputVisitorData *data,
|
||
|
|
||
|
g_string_free(gstr_union, true);
|
||
|
g_string_free(gstr_list, true);
|
||
|
- qapi_free_UserDefListUnion(cvalue);
|
||
|
}
|
||
|
|
||
|
static void input_visitor_test_add(const char *testpath,
|
||
|
@@ -1253,7 +1245,7 @@ static void test_visitor_in_fail_alternate(TestInputVisitorData *data,
|
||
|
static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
|
||
|
const QLitObject *qlit)
|
||
|
{
|
||
|
- SchemaInfoList *schema = NULL;
|
||
|
+ g_autoptr(SchemaInfoList) schema = NULL;
|
||
|
QObject *obj = qobject_from_qlit(qlit);
|
||
|
Visitor *v;
|
||
|
|
||
|
@@ -1262,7 +1254,6 @@ static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
|
||
|
visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
|
||
|
g_assert(schema);
|
||
|
|
||
|
- qapi_free_SchemaInfoList(schema);
|
||
|
qobject_unref(obj);
|
||
|
visit_free(v);
|
||
|
}
|
||
|
--
|
||
|
2.27.0
|
||
|
|