diff options
author | Eric Blake <eblake@redhat.com> | 2016-06-09 10:48:43 -0600 |
---|---|---|
committer | Markus Armbruster <armbru@redhat.com> | 2016-07-06 10:52:04 +0200 |
commit | 3b098d56979d2f7fd707c5be85555d114353a28d (patch) | |
tree | 85f234e99b363f4417c0b4a09971ad63935031d9 /blockdev.c | |
parent | 23d1705f425ca847f11d92e4363cd7f67f369fd8 (diff) | |
download | qemu-3b098d56979d2f7fd707c5be85555d114353a28d.tar.gz qemu-3b098d56979d2f7fd707c5be85555d114353a28d.tar.bz2 qemu-3b098d56979d2f7fd707c5be85555d114353a28d.zip |
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 <eblake@redhat.com>
Message-Id: <1465490926-28625-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Diffstat (limited to 'blockdev.c')
-rw-r--r-- | blockdev.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/blockdev.c b/blockdev.c index c05aaa6ea6..0f8065c4a5 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3950,10 +3950,10 @@ out: void qmp_blockdev_add(BlockdevOptions *options, Error **errp) { - QmpOutputVisitor *ov = qmp_output_visitor_new(); BlockDriverState *bs; BlockBackend *blk = NULL; QObject *obj; + Visitor *v = qmp_output_visitor_new(&obj); QDict *qdict; Error *local_err = NULL; @@ -3972,14 +3972,13 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) } } - visit_type_BlockdevOptions(qmp_output_get_visitor(ov), NULL, &options, - &local_err); + visit_type_BlockdevOptions(v, NULL, &options, &local_err); if (local_err) { error_propagate(errp, local_err); goto fail; } - obj = qmp_output_get_qobject(ov); + visit_complete(v, &obj); qdict = qobject_to_qdict(obj); qdict_flatten(qdict); @@ -4020,7 +4019,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) } fail: - visit_free(qmp_output_get_visitor(ov)); + visit_free(v); } void qmp_x_blockdev_del(bool has_id, const char *id, |