qemu/net
Eric Blake 3b098d5697 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>
2016-07-06 10:52:04 +02:00
..
checksum.c net: handle optional VLAN header in checksum computation. 2016-06-02 10:42:46 +08:00
clients.h net: Permit incremental conversion of init functions to Error 2015-05-27 09:51:04 +01:00
dump.c include/qemu/osdep.h: Don't include qapi/error.h 2016-03-22 22:20:15 +01:00
eth.c net_pkt: Extend packet abstraction as required by e1000e functionality 2016-06-02 10:42:28 +08:00
filter-buffer.c include/qemu/osdep.h: Don't include qapi/error.h 2016-03-22 22:20:15 +01:00
filter-mirror.c net/net: Add SocketReadState for reuse codes 2016-06-01 09:25:29 +08:00
filter.c filter-buffer: fix segfault when starting qemu with status=off property 2016-04-06 09:52:07 +08:00
hub.c qapi: Don't special-case simple union wrappers 2016-03-18 10:29:26 +01:00
hub.h net: fix qemu_flush_queued_packets() in presence of a hub 2013-02-27 16:10:23 +01:00
l2tpv3.c qapi: Don't special-case simple union wrappers 2016-03-18 10:29:26 +01:00
Makefile.objs net/filter-mirror:Add filter-mirror 2016-03-30 08:54:29 +08:00
net.c qapi: Add new visit_complete() function 2016-07-06 10:52:04 +02:00
netmap.c os-posix: include sys/mman.h 2016-06-16 18:39:03 +02:00
queue.c net: Clean up includes 2016-02-04 17:41:30 +00:00
slirp.c slirp: Allow disabling IPv4 or IPv6 2016-04-01 17:51:55 +02:00
socket.c Change net/socket.c to use socket_*() functions 2016-06-28 10:13:57 +08:00
tap_int.h tap: add VNET_LE/VNET_BE operations 2015-06-17 17:12:54 +02:00
tap-aix.c include/qemu/osdep.h: Don't include qapi/error.h 2016-03-22 22:20:15 +01:00
tap-bsd.c util: move declarations out of qemu-common.h 2016-03-22 22:20:17 +01:00
tap-haiku.c include/qemu/osdep.h: Don't include qapi/error.h 2016-03-22 22:20:15 +01:00
tap-linux.c util: move declarations out of qemu-common.h 2016-03-22 22:20:17 +01:00
tap-linux.h all: Clean up includes 2016-02-23 12:43:05 +00:00
tap-solaris.c util: move declarations out of qemu-common.h 2016-03-22 22:20:17 +01:00
tap-win32.c qapi: Don't special-case simple union wrappers 2016-03-18 10:29:26 +01:00
tap.c net/tap: Allocating Large sized arrays to heap 2016-05-25 15:46:07 +08:00
trace-events trace: split out trace events for net/ directory 2016-06-20 17:22:17 +01:00
util.c net: Clean up includes 2016-02-04 17:41:30 +00:00
util.h all: Clean up includes 2016-02-23 12:43:05 +00:00
vde.c qapi: Don't special-case simple union wrappers 2016-03-18 10:29:26 +01:00
vhost-user.c vhost-user: disable chardev handlers on close 2016-06-29 16:49:40 +02:00