qemu-cr16/include/io
Eric Blake b5676493a0 qio: Remember context of qio_net_listener_set_client_func_full
io/net-listener.c has two modes of use: asynchronous (the user calls
qio_net_listener_set_client_func to wake up the callback via the
global GMainContext, or qio_net_listener_set_client_func_full to wake
up the callback via the caller's own alternative GMainContext), and
synchronous (the user calls qio_net_listener_wait_client which creates
its own GMainContext and waits for the first client connection before
returning, with no need for a user's callback).  But commit 938c8b79
has a latent logic flaw: when qio_net_listener_wait_client finishes on
its temporary context, it reverts all of the siocs back to the global
GMainContext rather than the potentially non-NULL context they might
have been originally registered with.  Similarly, if the user creates
a net-listener, adds initial addresses, registers an async callback
with a non-default context (which ties to all siocs for the initial
addresses), then adds more addresses with qio_net_listener_add, the
siocs for later addresses are blindly placed in the global context,
rather than sharing the context of the earlier ones.

In practice, I don't think this has caused issues.  As pointed out by
the original commit, all async callers prior to that commit were
already okay with the NULL default context; and the typical usage
pattern is to first add ALL the addresses the listener will pay
attention to before ever setting the async callback.  Likewise, if a
file uses only qio_net_listener_set_client_func instead of
qio_net_listener_set_client_func_full, then it is never using a custom
context, so later assignments of async callbacks will still be to the
same global context as earlier ones.  Meanwhile, any callers that want
to do the sync operation to grab the first client are unlikely to
register an async callback; altogether bypassing the question of
whether later assignments of a GSource are being tied to a different
context over time.

I do note that chardev/char-socket.c is the only file that calls both
qio_net_listener_wait_client (sync for a single client in
tcp_chr_accept_server_sync), and qio_net_listener_set_client_func_full
(several places, all with chr->gcontext, but sometimes with a NULL
callback function during teardown).  But as far as I can tell, the two
uses are mutually exclusive, based on the is_waitconnect parameter to
qmp_chardev_open_socket_server.

That said, it is more robust to remember when an async callback
function is tied to a non-default context, and have both the sync wait
and any late address additions honor that same context.  That way, the
code will be robust even if a later user performs a sync wait for a
specific client in the middle of servicing a longer-lived
QIONetListener that has an async callback for all other clients.

CC: qemu-stable@nongnu.org
Fixes: 938c8b79 ("qio: store gsources for net listeners", v2.12.0)
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20251113011625.878876-19-eblake@redhat.com>
2025-11-13 08:29:46 -06:00
..
channel-buffer.h io: Fix Lesser GPL version number 2020-10-27 16:48:49 +01:00
channel-command.h io/command: implement support for win32 2022-10-12 19:22:01 +04:00
channel-file.h io: Introduce qio_channel_file_new_dupfd 2024-03-12 15:22:23 -04:00
channel-null.h io: add a QIOChannelNull equivalent to /dev/null 2022-06-22 18:11:21 +01:00
channel-socket.h io: flush zerocopy socket error queue on sendmsg failure due to ENOBUF 2025-11-03 10:45:28 +00:00
channel-tls.h io: tls: Add qio_channel_tls_bye 2025-02-14 15:19:03 -03:00
channel-util.h io: follow coroutine AioContext in qio_channel_yield() 2023-09-07 20:32:11 -05:00
channel-watch.h io: Fix Lesser GPL version number 2020-10-27 16:48:49 +01:00
channel-websock.h io: fix use after free in websocket handshake code 2025-10-24 13:04:31 +01:00
channel.h mem + migration pull for 10.2 2025-11-04 16:19:35 +01:00
dns-resolver.h io: Fix Lesser GPL version number 2020-10-27 16:48:49 +01:00
net-listener.h qio: Remember context of qio_net_listener_set_client_func_full 2025-11-13 08:29:46 -06:00
task.h Rename "QEMU global mutex" to "BQL" in comments and docs 2024-01-08 10:45:43 -05:00