Based on monitor QOM path tracking iothread users with holder. Introduce the AioContext in the Monitor struct to avoid repeated calls to iothread_get_aio_context() and ensure symmetrical ref/unref during monitor lifecycle.
Signed-off-by: Zhang Chen <[email protected]> --- monitor/monitor-internal.h | 3 +++ monitor/monitor.c | 22 ++++++++++++++++++++-- monitor/qmp.c | 5 +++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index 23829f32f9..caecceec93 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -153,6 +153,9 @@ struct Monitor { guint out_watch; int mux_out; int reset_seen; + + /* iothread context */ + AioContext *ctx; }; struct MonitorHMPClass { diff --git a/monitor/monitor.c b/monitor/monitor.c index ed195fd97b..688bb85c81 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -573,7 +573,7 @@ void monitor_suspend(Monitor *mon) * Kick I/O thread to make sure this takes effect. It'll be * evaluated again in prepare() of the watch object. */ - aio_notify(iothread_get_aio_context(mon_iothread)); + aio_notify(mon->ctx); } trace_monitor_suspend(mon, 1); @@ -668,6 +668,17 @@ void monitor_cleanup(void) qemu_mutex_unlock(&monitor_lock); monitor_flush(mon); qemu_mutex_lock(&monitor_lock); + + if (mon_iothread) { + g_autofree char *path = object_get_canonical_path(OBJECT(mon)); + const IOThreadHolder io_holder = { + .type = IO_THREAD_HOLDER_KIND_QOM_OBJECT, + .u.qom_object.qom_path = path, + }; + + iothread_put_aio_context(mon_iothread, &io_holder); + mon->ctx = NULL; + } object_unparent(OBJECT(mon)); } qemu_mutex_unlock(&monitor_lock); @@ -732,7 +743,14 @@ static void monitor_complete(UserCreatable *uc, Error **errp) mon_iothread = iothread_create("mon_iothread", &error_abort); } - ctx = iothread_get_aio_context(mon_iothread); + g_autofree char *path = object_get_canonical_path(OBJECT(mon)); + const IOThreadHolder io_holder = { + .type = IO_THREAD_HOLDER_KIND_QOM_OBJECT, + .u.qom_object.qom_path = path, + }; + + mon->ctx = iothread_ref_and_get_aio_context(mon_iothread, &io_holder); + ctx = mon->ctx; } else { ctx = qemu_get_aio_context(); } diff --git a/monitor/qmp.c b/monitor/qmp.c index 223e0643c2..b16bd77688 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -732,7 +732,8 @@ static void monitor_qmp_complete(UserCreatable *uc, Error **errp) * thread. Schedule a bottom half. */ mon->setup_pending = true; - aio_bh_schedule_oneshot(iothread_get_aio_context(mon_iothread), + + aio_bh_schedule_oneshot(MONITOR(mon)->ctx, monitor_qmp_setup_handlers_bh, mon); /* The bottom half will add @mon to @mon_list */ } else { @@ -787,7 +788,7 @@ static bool monitor_qmp_prepare_delete(UserCreatable *uc, Error **errp) /* Synchronize with in-flight iothread callbacks. */ if (monitor_requires_iothread(mon)) { - aio_wait_bh_oneshot(iothread_get_aio_context(mon_iothread), + aio_wait_bh_oneshot(MONITOR(mon)->ctx, monitor_qmp_iothread_quiesce, NULL); } -- 2.49.0
