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