From a95291007b2478fcf32a2d71bf133b688bb4b675 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 18 Dec 2018 19:22:21 +0100 Subject: qapi: Eliminate indirection through qmp_event_get_func_emit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The qapi_event_send_FOO() functions emit events like this: QMPEventFuncEmit emit; emit = qmp_event_get_func_emit(); if (!emit) { return; } qmp = qmp_event_build_dict("FOO"); [put event arguments into @qmp...] emit(QAPI_EVENT_FOO, qmp); The value of qmp_event_get_func_emit() depends only on the program: * In qemu-system-FOO, it's always monitor_qapi_event_queue. * In tests/test-qmp-event, it's always event_test_emit. * In all other programs, it's always null. This is exactly the kind of dependence the linker is supposed to resolve; we don't actually need an indirection. Note that things would fall apart if we linked more than one QAPI schema into a single program: each set of qapi_event_send_FOO() uses its own event enumeration, yet they share a single emit function. Which takes the event enumeration as an argument. Which one if there's more than one? More seriously: how does this work even now? qemu-system-FOO wants QAPIEvent, and passes a function taking that to qmp_event_set_func_emit(). test-qmp-event wants test_QAPIEvent, and passes a function taking that to qmp_event_set_func_emit(). It works by type trickery, of course: typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict); void qmp_event_set_func_emit(QMPEventFuncEmit emit); QMPEventFuncEmit qmp_event_get_func_emit(void); We use unsigned instead of the enumeration type. Relies on both enumerations boiling down to unsigned, which happens to be true for the compilers we use. Clean this up as follows: * Generate qapi_event_send_FOO() that call PREFIX_qapi_event_emit() instead of the value of qmp_event_set_func_emit(). * Generate a prototype for PREFIX_qapi_event_emit() into qapi-events.h. * PREFIX_ is empty for qapi/qapi-schema.json, and test_ for tests/qapi-schema/qapi-schema-test.json. It's qga_ for qga/qapi-schema.json, and doc-good- for tests/qapi-schema/doc-good.json, but those don't define any events. * Rename monitor_qapi_event_queue() to qapi_event_emit() instead of passing it to qmp_event_set_func_emit(). This takes care of qemu-system-FOO. * Rename event_test_emit() to test_qapi_event_emit() instead of passing it to qmp_event_set_func_emit(). This takes care of tests/test-qmp-event. * Add a qapi_event_emit() that does nothing to stubs/monitor.c. This takes care of all other programs that link code emitting QMP events. * Drop qmp_event_set_func_emit(), qmp_event_get_func_emit(). Signed-off-by: Markus Armbruster Message-Id: <20181218182234.28876-3-armbru@redhat.com> Reviewed-by: Marc-André Lureau [Commit message typos fixed] --- docs/devel/qapi-code-gen.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'docs') diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index 418a607..87183d3 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -1385,16 +1385,10 @@ Example: void qapi_event_send_my_event(void) { QDict *qmp; - QMPEventFuncEmit emit; - - emit = qmp_event_get_func_emit(); - if (!emit) { - return; - } qmp = qmp_event_build_dict("MY_EVENT"); - emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp); + example_qapi_event_emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp); qobject_unref(qmp); } -- cgit v1.1