On Tue, Nov 04, 2025 at 11:37:21AM +0000, Daniel P. Berrangé wrote:
> On Mon, Nov 03, 2025 at 02:10:58PM -0600, Eric Blake wrote:
> >      for ( ; i < listener->nsioc; i++) {
> > -        listener->io_source[i] = qio_channel_add_watch_source(
> > -            QIO_CHANNEL(listener->sioc[i]), G_IO_IN,
> > -            qio_net_listener_channel_func,
> > -            listener, NULL, listener->context);
> > +        if (listener->context) {
> > +            /*
> > +             * The user passed a GMainContext with the async callback;
> > +             * they plan on running their own g_main_loop.
> > +             */
> > +            listener->io_source[i] = qio_channel_add_watch_source(
> > +                QIO_CHANNEL(listener->sioc[i]), G_IO_IN,
> > +                qio_net_listener_channel_func,
> > +                listener, NULL, listener->context);
> > +        } else {
> > +            /*
> > +             * The user is fine with the default context. But by doing
> > +             * it in the main thread's AioContext rather than
> > +             * specifically in a GMainContext, we can remain
> > +             * responsive even if another AioContext depends on
> > +             * connecting to this server.
> > +             */
> > +            aio_set_fd_handler(qemu_get_aio_context(), 
> > listener->sioc[i]->fd,
> > +                               qio_net_listener_aio_func, NULL, NULL, NULL,
> > +                               listener->sioc[i]);
> > +        }
> 
> I'm not really happy with the listener directly accessing the 'fd'
> fields in the QIOSocketChannel, as compared to the GSource approach
> where the underlying transport is not exposed to the caller.
> 
> If we want to use an AioContext instead of a GSource, then I think
> we need to add a method to either QIOChannelSocket, or QIOChannel
> base, as an alternative to the GSource watches, and then have the
> listener conditionally use the AioContext APIs.
> 
> 
> Also in QIOChannel base, we have a io_set_aio_fd_handler() method
> that we use elsewhere. Can we perhaps leverage that in some way.

I will explore that idea for v2.

> 
> eg, instead of taking the AioContext code path based off
> "if (listener->context)", take the code path based on whether
> the QIOChannel has had a call qio_channel_set_aio_fd_handler
> to register AIO handlers ? Maybe that method doesn't quite fit,
> but conceptually I would be more comfortable with an approach
> that explicitly associates an AioContext with either the
> channel or the listener object, rather than this heuristic
> of "if (listener->context)".

I wonder if qio_channel_set_follow_coroutine_ctx() might be the
trigger point you are thinking of. NBD code already calls this, but
only AFTER the client has connected.  Would having
ioc->follow_coroutine_ctx is a better witness that the caller
specifically wants the channel behind NetListener to run in an
AioContext, rather than blindly declaring that all NetListeners get
AioContext unless they use qio_net_listener_set_client_func_full(),
and where I change the NBD code to call follow_coroutine_ctx() sooner?


-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org


Reply via email to