monitor: use class methods for monitor_qapi_event_emit
This removes the need for using monitor_is_qmp() to check the subclass type, which is an anti-pattern. Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Tested-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Message-ID: <20260706135824.2623960-14-berrange@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
Daniel P. Berrangé committed
Jul 6, 2026 at 14:58 UTC
d5b007ae8d4e5707eda863ff9bd7bc90e26bebf2
4 files changed
+29
-12
include/monitor/monitor.h
+1
@@ -3,6 +3,7 @@
3
4
#include "block/block.h"
5
#include "qapi/qapi-types-misc.h"
6
+#include "qapi/qapi-emit-events.h"
7
#include "qemu/readline.h"
8
#include "exec/hwaddr.h"
9
#include "qom/object.h"
monitor/monitor-internal.h
+5
@@ -111,6 +111,11 @@ struct MonitorClass {
111
*/
112
int (*vprintf)(Monitor *mon, const char *fmt, va_list ap)
113
G_GNUC_PRINTF(2, 0);
114
+ /*
115
+ * If non-NULL, the monitor is able to send event
116
+ * notifications back to the client
117
+ */
118
+ void (*emit_event)(Monitor *mon, QAPIEvent event, QDict *qdict);
119
};
120
121
struct Monitor {
monitor/monitor.c
+3
-12
@@ -348,22 +348,13 @@ static inline QEMUClockType monitor_get_event_clock(void)
348
static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict)
349
{
350
Monitor *mon;
351
- MonitorQMP *qmp_mon;
351
352
trace_monitor_protocol_event_emit(event, qdict);
353
QTAILQ_FOREACH(mon, &mon_list, entry) {
355
- if (!monitor_is_qmp(mon)) {
356
- continue;
354
+ MonitorClass *cls = MONITOR_GET_CLASS(mon);
355
+ if (cls->emit_event) {
356
+ cls->emit_event(mon, event, qdict);
357
}
358
-
359
- qmp_mon = container_of(mon, MonitorQMP, parent_obj);
360
- {
361
- QEMU_LOCK_GUARD(&mon->mon_lock);
362
- if (qmp_mon->commands == &qmp_cap_negotiation_commands) {
363
- continue;
364
- }
365
- }
366
- qmp_send_response(qmp_mon, qdict);
358
}
359
}
360
monitor/qmp.c
+20
@@ -99,11 +99,17 @@ static void monitor_qmp_set_pretty(Object *obj, bool val, Error **errp)
99
mon->pretty = val;
100
}
101
102
+static void monitor_qmp_emit_event(Monitor *mon, QAPIEvent event, QDict *qdict);
103
+
104
static void monitor_qmp_class_init(ObjectClass *cls, const void *data)
105
{
106
+ MonitorClass *moncls = MONITOR_CLASS(cls);
107
+
108
object_class_property_add_bool(cls, "pretty",
109
monitor_qmp_get_pretty,
110
monitor_qmp_set_pretty);
111
+
112
+ moncls->emit_event = monitor_qmp_emit_event;
113
}
114
115
static void handle_qmp_command(void *opaque, QObject *req, Error *err);
@@ -117,6 +123,20 @@ static void monitor_qmp_init(Object *obj)
123
json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL);
124
}
125
126
+static void monitor_qmp_emit_event(Monitor *mon, QAPIEvent event, QDict *qdict)
127
+{
128
+ MonitorQMP *qmp = MONITOR_QMP(mon);
129
+
130
+ WITH_QEMU_LOCK_GUARD(&mon->mon_lock) {
131
+ if (qmp->commands == &qmp_cap_negotiation_commands) {
132
+ return;
133
+ }
134
+ }
135
+
136
+ qmp_send_response(qmp, qdict);
137
+}
138
+
139
+
140
static bool qmp_oob_enabled(MonitorQMP *mon)
141
{
142
return mon->capab[QMP_CAPABILITY_OOB];