From b70ce1018a251c0c33498d9c927a07cade655a5e Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 9 Jun 2016 10:48:38 -0600 Subject: qmp-input-visitor: Favor new visit_free() function Now that we have a polymorphic visit_free(), we no longer need qmp_input_visitor_cleanup(); which in turn means we no longer need to return a subtype from qmp_input_visitor_new() nor a public upcast function. Generated code changes to qmp-marshal.c look like: |@@ -52,11 +52,10 @@ void qmp_marshal_add_fd(QDict *args, QOb | { | Error *err = NULL; | AddfdInfo *retval; |- QmpInputVisitor *qiv = qmp_input_visitor_new(QOBJECT(args), true); | Visitor *v; | q_obj_add_fd_arg arg = {0}; | |- v = qmp_input_get_visitor(qiv); |+ v = qmp_input_visitor_new(QOBJECT(args), true); | visit_start_struct(v, NULL, NULL, 0, &err); | if (err) { | goto out; Signed-off-by: Eric Blake Message-Id: <1465490926-28625-8-git-send-email-eblake@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- tests/check-qnull.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests/check-qnull.c') diff --git a/tests/check-qnull.c b/tests/check-qnull.c index 05d562d..d0412e4 100644 --- a/tests/check-qnull.c +++ b/tests/check-qnull.c @@ -38,7 +38,7 @@ static void qnull_visit_test(void) { QObject *obj; QmpOutputVisitor *qov; - QmpInputVisitor *qiv; + Visitor *v; /* * Most tests of interactions between QObject and visitors are in @@ -48,10 +48,10 @@ static void qnull_visit_test(void) g_assert(qnull_.refcnt == 1); obj = qnull(); - qiv = qmp_input_visitor_new(obj, true); + v = qmp_input_visitor_new(obj, true); qobject_decref(obj); - visit_type_null(qmp_input_get_visitor(qiv), NULL, &error_abort); - qmp_input_visitor_cleanup(qiv); + visit_type_null(v, NULL, &error_abort); + visit_free(v); qov = qmp_output_visitor_new(); visit_type_null(qmp_output_get_visitor(qov), NULL, &error_abort); -- cgit v1.1 From 1830f22a6777cedaccd67a08f675d30f7a85ebfd Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 9 Jun 2016 10:48:40 -0600 Subject: qmp-output-visitor: Favor new visit_free() function Now that we have a polymorphic visit_free(), we no longer need qmp_output_visitor_cleanup(); however, we still need to expose the subtype for qmp_output_get_qobject(). Signed-off-by: Eric Blake Message-Id: <1465490926-28625-10-git-send-email-eblake@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- tests/check-qnull.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/check-qnull.c') diff --git a/tests/check-qnull.c b/tests/check-qnull.c index d0412e4..6310bf7 100644 --- a/tests/check-qnull.c +++ b/tests/check-qnull.c @@ -58,7 +58,7 @@ static void qnull_visit_test(void) obj = qmp_output_get_qobject(qov); g_assert(obj == &qnull_); qobject_decref(obj); - qmp_output_visitor_cleanup(qov); + visit_free(qmp_output_get_visitor(qov)); g_assert(qnull_.refcnt == 1); } -- cgit v1.1 From 3b098d56979d2f7fd707c5be85555d114353a28d Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 9 Jun 2016 10:48:43 -0600 Subject: qapi: Add new visit_complete() function Making each output visitor provide its own output collection function was the only remaining reason for exposing visitor sub-types to the rest of the code base. Add a polymorphic visit_complete() function which is a no-op for input visitors, and which populates an opaque pointer for output visitors. For maximum type-safety, also add a parameter to the output visitor constructors with a type-correct version of the output pointer, and assert that the two uses match. This approach was considered superior to either passing the output parameter only during construction (action at a distance during visit_free() feels awkward) or only during visit_complete() (defeating type safety makes it easier to use incorrectly). Most callers were function-local, and therefore a mechanical conversion; the testsuite was a bit trickier, but the previous cleanup patch minimized the churn here. The visit_complete() function may be called at most once; doing so lets us use transfer semantics rather than duplication or ref-count semantics to get the just-built output back to the caller, even though it means our behavior is not idempotent. Generated code is simplified as follows for events: |@@ -26,7 +26,7 @@ void qapi_event_send_acpi_device_ost(ACP | QDict *qmp; | Error *err = NULL; | QMPEventFuncEmit emit; |- QmpOutputVisitor *qov; |+ QObject *obj; | Visitor *v; | q_obj_ACPI_DEVICE_OST_arg param = { | info |@@ -39,8 +39,7 @@ void qapi_event_send_acpi_device_ost(ACP | | qmp = qmp_event_build_dict("ACPI_DEVICE_OST"); | |- qov = qmp_output_visitor_new(); |- v = qmp_output_get_visitor(qov); |+ v = qmp_output_visitor_new(&obj); | | visit_start_struct(v, "ACPI_DEVICE_OST", NULL, 0, &err); | if (err) { |@@ -55,7 +54,8 @@ void qapi_event_send_acpi_device_ost(ACP | goto out; | } | |- qdict_put_obj(qmp, "data", qmp_output_get_qobject(qov)); |+ visit_complete(v, &obj); |+ qdict_put_obj(qmp, "data", obj); | emit(QAPI_EVENT_ACPI_DEVICE_OST, qmp, &err); and for commands: | { | Error *err = NULL; |- QmpOutputVisitor *qov = qmp_output_visitor_new(); | Visitor *v; | |- v = qmp_output_get_visitor(qov); |+ v = qmp_output_visitor_new(ret_out); | visit_type_AddfdInfo(v, "unused", &ret_in, &err); |- if (err) { |- goto out; |+ if (!err) { |+ visit_complete(v, ret_out); | } |- *ret_out = qmp_output_get_qobject(qov); |- |-out: | error_propagate(errp, err); Signed-off-by: Eric Blake Message-Id: <1465490926-28625-13-git-send-email-eblake@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- tests/check-qnull.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'tests/check-qnull.c') diff --git a/tests/check-qnull.c b/tests/check-qnull.c index 6310bf7..dc906b1 100644 --- a/tests/check-qnull.c +++ b/tests/check-qnull.c @@ -37,7 +37,6 @@ static void qnull_ref_test(void) static void qnull_visit_test(void) { QObject *obj; - QmpOutputVisitor *qov; Visitor *v; /* @@ -53,12 +52,12 @@ static void qnull_visit_test(void) visit_type_null(v, NULL, &error_abort); visit_free(v); - qov = qmp_output_visitor_new(); - visit_type_null(qmp_output_get_visitor(qov), NULL, &error_abort); - obj = qmp_output_get_qobject(qov); + v = qmp_output_visitor_new(&obj); + visit_type_null(v, NULL, &error_abort); + visit_complete(v, &obj); g_assert(obj == &qnull_); qobject_decref(obj); - visit_free(qmp_output_get_visitor(qov)); + visit_free(v); g_assert(qnull_.refcnt == 1); } -- cgit v1.1