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