On Thu, Mar 05, 2026 at 10:24:49PM +0800, Zhang Chen wrote: > Introduce iothread_get_aio_context() with a 'holder' argument and its > counterpart iothread_put_aio_context(). > > Previously, users of an IOThread's AioContext did not explicitly > record their identity, making it difficult to debug which devices or > subsystems were pinning an IOThread. > > This patch enhances the reference counting mechanism by: > 1. Automatically incrementing the object reference count when a context > is retrieved. > 2. Tracking holders by name using iothread_ref() and iothread_unref(). > > In iothread_instance_finalize(), we now retrieve the source name from > the GMainContext to correctly unref the initial internal holder. > > Signed-off-by: Zhang Chen <[email protected]> > --- > include/system/iothread.h | 3 ++- > iothread.c | 28 ++++++++++++++++++++++++++-- > 2 files changed, 28 insertions(+), 3 deletions(-) > > diff --git a/include/system/iothread.h b/include/system/iothread.h > index 21a76bd70d..595abeefbe 100644 > --- a/include/system/iothread.h > +++ b/include/system/iothread.h > @@ -47,7 +47,8 @@ DECLARE_INSTANCE_CHECKER(IOThread, IOTHREAD, > > char *iothread_get_id(IOThread *iothread); > IOThread *iothread_by_id(const char *id); > -AioContext *iothread_get_aio_context(IOThread *iothread); > +AioContext *iothread_get_aio_context(IOThread *iothread, const char *holder); > +void iothread_put_aio_context(IOThread *iothread, const char *holder); > GMainContext *iothread_get_g_main_context(IOThread *iothread); > > /* > diff --git a/iothread.c b/iothread.c > index 80a8cf4b32..da98fbb9ad 100644 > --- a/iothread.c > +++ b/iothread.c > @@ -172,7 +172,8 @@ static void iothread_init_gcontext(IOThread *iothread, > const char *thread_name) > g_autofree char *name = g_strdup_printf("%s aio-context", thread_name); > > iothread->worker_context = g_main_context_new(); > - source = aio_get_g_source(iothread_get_aio_context(iothread)); > + /* No need setup itself as the init holder */ > + source = aio_get_g_source(iothread_get_aio_context(iothread, NULL));
This is cleaner:
source = aio_get_g_source(iothread->ctx);
That way iothread_get_aio_context() doesn't need a special case for
NULL.
> g_source_set_name(source, name);
> g_source_attach(source, iothread->worker_context);
> g_source_unref(source);
> @@ -362,11 +363,34 @@ char *iothread_get_id(IOThread *iothread)
> return g_strdup(object_get_canonical_path_component(OBJECT(iothread)));
> }
>
> -AioContext *iothread_get_aio_context(IOThread *iothread)
> +AioContext *iothread_get_aio_context(IOThread *iothread, const char *holder)
> {
> + /*
> + * In some cases, iothread user need the ctx to clearup other resource.
> + * When holder is empty, back to the legacy way.
> + */
> + if (holder) {
> + /*
> + * This guarantees that the IOThread and its AioContext remain alive
> + * as long as there is a holder.
> + */
> + object_ref(OBJECT(iothread));
Can this be done in iothread_ref()/iothread_unref()? That would ensure
that callers always increment the QOM reference count regardless of
whether the iothread_ref() or iothread_get_aio_context() API is used.
> +
> + /* Add holder device path to the list */
> + iothread_ref(iothread, holder);
> + }
> +
> return iothread->ctx;
> }
>
> +void iothread_put_aio_context(IOThread *iothread, const char *holder)
> +{
> + object_unref(OBJECT(iothread));
> +
> + /* Delete holder device path from the list */
> + iothread_unref(iothread, holder);
> +}
> +
> static int query_one_iothread(Object *object, void *opaque)
> {
> IOThreadInfoList ***tail = opaque;
> --
> 2.49.0
>
signature.asc
Description: PGP signature
