Start to take advantage of QOM, by using object init and finalize
methods to replace monitor_data_init and monitor_data_destroy.
A standalone helper is provided to enable the I/O thread for QMP
where appropriate for the chardev backend.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
monitor/hmp.c | 4 ++--
monitor/monitor-internal.h | 3 +--
monitor/monitor.c | 48 ++++++++++++++------------------------
monitor/qmp-cmds.c | 3 ---
monitor/qmp.c | 21 +++++++++--------
5 files changed, 32 insertions(+), 47 deletions(-)
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 72f8303662..833de0eee8 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -46,6 +46,8 @@ OBJECT_DEFINE_TYPE(MonitorHMP, monitor_hmp, MONITOR_HMP, MONITOR);
static void monitor_hmp_finalize(Object *obj)
{
+ MonitorHMP *mon = MONITOR_HMP(obj);
+ readline_free(mon->rs);
}
static void monitor_hmp_class_init(ObjectClass *cls, const void *data)
@@ -1539,8 +1541,6 @@ void monitor_new_hmp(Chardev *chr, bool use_readline, Error **errp)
return;
}
- monitor_data_init(&mon->parent, false, false);
-
mon->use_readline = use_readline;
if (mon->use_readline) {
mon->rs = readline_init(monitor_readline_printf,
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index 84117805b7..5bfe3b7325 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -182,8 +182,7 @@ extern QmpCommandList qmp_commands, qmp_cap_negotiation_commands;
extern QemuMutex monitor_lock;
extern MonitorList mon_list;
-void monitor_data_init(Monitor *mon, bool is_qmp, bool use_io_thread);
-void monitor_data_destroy(Monitor *mon);
+void monitor_iothread_init(Monitor *mon);
int monitor_can_read(void *opaque);
void monitor_list_append(Monitor *mon);
void monitor_fdsets_cleanup(void);
diff --git a/monitor/monitor.c b/monitor/monitor.c
index f7e3708d2f..f6c90145f6 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -77,6 +77,12 @@ OBJECT_DEFINE_TYPE(Monitor, monitor, MONITOR, OBJECT);
static void monitor_finalize(Object *obj)
{
+ Monitor *mon = MONITOR(obj);
+
+ g_free(mon->mon_cpu_path);
+ qemu_chr_fe_deinit(&mon->chr, false);
+ g_string_free(mon->outbuf, true);
+ qemu_mutex_destroy(&mon->mon_lock);
}
static void monitor_class_init(ObjectClass *cls, const void *data)
@@ -85,6 +91,11 @@ static void monitor_class_init(ObjectClass *cls, const void *data)
static void monitor_init(Object *obj)
{
+ Monitor *mon = MONITOR(obj);
+
+ qemu_mutex_init(&mon->mon_lock);
+ mon->is_qmp = !!object_dynamic_cast(obj, TYPE_MONITOR_QMP);
+ mon->outbuf = g_string_new(NULL);
}
Monitor *monitor_cur(void)
@@ -616,38 +627,16 @@ void monitor_list_append(Monitor *mon)
qemu_mutex_unlock(&monitor_lock);
if (mon) {
- monitor_data_destroy(mon);
object_unref(mon);
}
}
-static void monitor_iothread_init(void)
-{
- mon_iothread = iothread_create("mon_iothread", &error_abort);
-}
-
-void monitor_data_init(Monitor *mon, bool is_qmp, bool use_io_thread)
+void monitor_iothread_init(Monitor *mon)
{
- if (use_io_thread && !mon_iothread) {
- monitor_iothread_init();
+ if (!mon_iothread) {
+ mon_iothread = iothread_create("mon_iothread", &error_abort);
}
- qemu_mutex_init(&mon->mon_lock);
- mon->is_qmp = is_qmp;
- mon->outbuf = g_string_new(NULL);
- mon->use_io_thread = use_io_thread;
-}
-
-void monitor_data_destroy(Monitor *mon)
-{
- g_free(mon->mon_cpu_path);
- qemu_chr_fe_deinit(&mon->chr, false);
- if (monitor_is_qmp(mon)) {
- monitor_data_destroy_qmp(container_of(mon, MonitorQMP, parent));
- } else {
- readline_free(container_of(mon, MonitorHMP, parent)->rs);
- }
- g_string_free(mon->outbuf, true);
- qemu_mutex_destroy(&mon->mon_lock);
+ mon->use_io_thread = true;
}
void monitor_cleanup(void)
@@ -665,7 +654,7 @@ void monitor_cleanup(void)
* Letting the iothread continue while shutting down the dispatcher
* means that new requests may still be coming in. This is okay,
* we'll just leave them in the queue without sending a response
- * and monitor_data_destroy() will free them.
+ * and object finalization will free them.
*/
WITH_QEMU_LOCK_GUARD(&monitor_lock) {
qmp_dispatcher_co_shutdown = true;
@@ -679,8 +668,8 @@ void monitor_cleanup(void)
/*
* We need to explicitly stop the I/O thread (but not destroy it),
* clean up the monitor resources, then destroy the I/O thread since
- * we need to unregister from chardev below in
- * monitor_data_destroy(), and chardev is not thread-safe yet
+ * we need to unregister from chardev below in object
+ * finalization, and chardev is not thread-safe yet
*/
if (mon_iothread) {
iothread_stop(mon_iothread);
@@ -695,7 +684,6 @@ void monitor_cleanup(void)
/* Permit QAPI event emission from character frontend release */
qemu_mutex_unlock(&monitor_lock);
monitor_flush(mon);
- monitor_data_destroy(mon);
qemu_mutex_lock(&monitor_lock);
object_unref(mon);
}
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index be2bd985b7..5be93eff4d 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -168,8 +168,6 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
char *output = NULL;
MonitorHMP *hmp = MONITOR_HMP(object_new(TYPE_MONITOR_HMP));
- monitor_data_init(&hmp->parent, false, false);
-
if (has_cpu_index) {
int ret = monitor_set_cpu(&hmp->parent, cpu_index);
if (ret < 0) {
@@ -186,7 +184,6 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
}
out:
- monitor_data_destroy(&hmp->parent);
object_unref(hmp);
return output;
}
diff --git a/monitor/qmp.c b/monitor/qmp.c
index fe2aec9ce9..0de98b33fe 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -73,8 +73,16 @@ QmpCommandList qmp_commands, qmp_cap_negotiation_commands;
OBJECT_DEFINE_TYPE(MonitorQMP, monitor_qmp, MONITOR_QMP, MONITOR);
+static void monitor_qmp_cleanup_req_queue_locked(MonitorQMP *mon);
+
static void monitor_qmp_finalize(Object *obj)
{
+ MonitorQMP *mon = MONITOR_QMP(obj);
+
+ json_message_parser_destroy(&mon->parser);
+ qemu_mutex_destroy(&mon->qmp_queue_lock);
+ monitor_qmp_cleanup_req_queue_locked(mon);
+ g_queue_free(mon->qmp_requests);
}
static void monitor_qmp_class_init(ObjectClass *cls, const void *data)
@@ -505,14 +513,6 @@ static void monitor_qmp_event(void *opaque, QEMUChrEvent event)
}
}
-void monitor_data_destroy_qmp(MonitorQMP *mon)
-{
- json_message_parser_destroy(&mon->parser);
- qemu_mutex_destroy(&mon->qmp_queue_lock);
- monitor_qmp_cleanup_req_queue_locked(mon);
- g_queue_free(mon->qmp_requests);
-}
-
static void monitor_qmp_setup_handlers_bh(void *opaque)
{
MonitorQMP *mon = opaque;
@@ -538,8 +538,9 @@ void monitor_new_qmp(Chardev *chr, bool pretty, Error **errp)
qemu_chr_fe_set_echo(&mon->parent.chr, true);
/* Note: we run QMP monitor in I/O thread when @chr supports that */
- monitor_data_init(&mon->parent, true,
- qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT));
+ if (qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT)) {
+ monitor_iothread_init(&mon->parent);
+ }
mon->pretty = pretty;
--
2.53.0