Convert colo-compare to use the iothread_get_aio_context() and iothread_put_aio_context() APIs. This ensures that IOThread references are tracked using the COLO object's canonical QOM path as the holder ID.
Changes: - In colo_compare_iothread(), acquire the AioContext with the object path and pass the context to colo_compare_timer_init() to avoid redundant reference counting. - In colo_compare_finalize(), use the object path to release the IOThread reference. - Properly manage the lifecycle of the canonical path string with g_free() to avoid memory leaks. This refactoring improves IOThread lifecycle traceability and aligns the code with modern QEMU iothread reference management patterns. Signed-off-by: Zhang Chen <[email protected]> --- net/colo-compare.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/net/colo-compare.c b/net/colo-compare.c index c356419d6a..43addb5f00 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -924,10 +924,8 @@ void colo_notify_compares_event(void *opaque, int event, Error **errp) qemu_mutex_unlock(&colo_compare_mutex); } -static void colo_compare_timer_init(CompareState *s) +static void colo_compare_timer_init(CompareState *s, AioContext *ctx) { - AioContext *ctx = iothread_get_aio_context(s->iothread); - s->packet_check_timer = aio_timer_new(ctx, QEMU_CLOCK_HOST, SCALE_MS, check_old_packet_regular, s); @@ -968,8 +966,9 @@ static void colo_compare_handle_event(void *opaque) static void colo_compare_iothread(CompareState *s) { - AioContext *ctx = iothread_get_aio_context(s->iothread); - object_ref(OBJECT(s->iothread)); + char *path = object_get_canonical_path(OBJECT(s)); + AioContext *ctx = iothread_get_aio_context(s->iothread, path); + s->worker_context = iothread_get_g_main_context(s->iothread); qemu_chr_fe_set_handlers(&s->chr_pri_in, compare_chr_can_read, @@ -984,8 +983,10 @@ static void colo_compare_iothread(CompareState *s) s, s->worker_context, true); } - colo_compare_timer_init(s); + colo_compare_timer_init(s, ctx); s->event_bh = aio_bh_new(ctx, colo_compare_handle_event, s); + + g_free(path); } static char *compare_get_pri_indev(Object *obj, Error **errp) @@ -1408,6 +1409,7 @@ static void colo_compare_finalize(Object *obj) { CompareState *s = COLO_COMPARE(obj); CompareState *tmp = NULL; + char *path = object_get_canonical_path(OBJECT(s)); qemu_mutex_lock(&colo_compare_mutex); QTAILQ_FOREACH(tmp, &net_compares, next) { @@ -1434,11 +1436,17 @@ static void colo_compare_finalize(Object *obj) qemu_bh_delete(s->event_bh); - AioContext *ctx = iothread_get_aio_context(s->iothread); + /* + * Use the device's canonical path as the holder ID to track IOThread + * usage and ensure the AioContext remains valid during the device's + * lifecycle. + */ + AioContext *ctx = iothread_get_aio_context(s->iothread, NULL); AIO_WAIT_WHILE(ctx, !s->out_sendco.done); if (s->notify_dev) { AIO_WAIT_WHILE(ctx, !s->notify_sendco.done); } + iothread_put_aio_context(s->iothread, path); /* Release all unhandled packets after compare thead exited */ g_queue_foreach(&s->conn_list, colo_flush_packets, s); @@ -1456,6 +1464,7 @@ static void colo_compare_finalize(Object *obj) object_unref(OBJECT(s->iothread)); + g_free(path); g_free(s->pri_indev); g_free(s->sec_indev); g_free(s->outdev); -- 2.49.0
