An upcoming patch needs to pass more than just sioc as the opaque pointer to an AioContext; but since our AioContext code in general (and its QIO Channel wrapper code) lacks a notify callback present with GSource, we do not have the trivial option of just g_malloc'ing a small struct to hold all that data coupled with a notify of g_free. Instead, the data pointer must outlive the registered handler; in fact, having the data pointer have the same lifetime as QIONetListener is adequate.
But the cleanest way to stick such a helper struct in QIONetListener will be to rearrange internal struct members. And that in turn means that all existing code that currently directly accesses listener->nsioc and listener->sioc[] should instead go through accessor functions, to be immune to the upcoming struct layout changes. So this patch adds accessor methods qio_net_listener_nsioc() and qio_net_listener_sioc(), and puts them to use. Signed-off-by: Eric Blake <[email protected]> --- v2: new patch --- include/io/net-listener.h | 24 ++++++++++++++++++++++++ chardev/char-socket.c | 3 ++- io/net-listener.c | 12 ++++++++++++ migration/socket.c | 5 +++-- ui/vnc.c | 36 +++++++++++++++++++++++------------- 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/include/io/net-listener.h b/include/io/net-listener.h index 42fbfab5467..2605d6aae1e 100644 --- a/include/io/net-listener.h +++ b/include/io/net-listener.h @@ -184,4 +184,28 @@ void qio_net_listener_disconnect(QIONetListener *listener); */ bool qio_net_listener_is_connected(QIONetListener *listener); + +/** + * qio_net_listener_nsioc: + * @listener: the network listener object + * + * Determine the number of listener channels currently owned by the + * given listener. + * + * Returns: number of channels, or 0 if not listening + */ +size_t qio_net_listener_nsioc(QIONetListener *listener); + + +/** + * qio_net_listener_sioc: + * @listener: the network listener object + * @n: index of the sioc to grab + * + * Accessor for the nth sioc owned by the listener. + * + * Returns: the requested listener, or #NULL if not in bounds + */ +QIOChannelSocket *qio_net_listener_sioc(QIONetListener *listener, size_t n); + #endif /* QIO_NET_LISTENER_H */ diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 62852e3caf5..022ae47d726 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -1255,7 +1255,8 @@ static int qmp_chardev_open_socket_server(Chardev *chr, } qapi_free_SocketAddress(s->addr); - s->addr = socket_local_address(s->listener->sioc[0]->fd, errp); + s->addr = socket_local_address(qio_net_listener_sioc(s->listener, 0)->fd, + errp); skip_listen: update_disconnected_filename(s); diff --git a/io/net-listener.c b/io/net-listener.c index dd3522c9b3c..83c977ecca2 100644 --- a/io/net-listener.c +++ b/io/net-listener.c @@ -298,6 +298,18 @@ bool qio_net_listener_is_connected(QIONetListener *listener) return listener->connected; } +size_t qio_net_listener_nsioc(QIONetListener *listener) +{ + return listener->nsioc; +} + +QIOChannelSocket *qio_net_listener_sioc(QIONetListener *listener, size_t n) +{ + if (n > listener->nsioc) { + return NULL; + } + return listener->sioc[n]; +} static void qio_net_listener_finalize(Object *obj) { QIONetListener *listener = QIO_NET_LISTENER(obj); diff --git a/migration/socket.c b/migration/socket.c index 5ec65b8c039..297de3ee156 100644 --- a/migration/socket.c +++ b/migration/socket.c @@ -170,9 +170,10 @@ void socket_start_incoming_migration(SocketAddress *saddr, NULL, NULL, g_main_context_get_thread_default()); - for (i = 0; i < listener->nsioc; i++) { + for (i = 0; i < qio_net_listener_nsioc(listener); i++) { SocketAddress *address = - qio_channel_socket_get_local_address(listener->sioc[i], errp); + qio_channel_socket_get_local_address( + qio_net_listener_sioc(listener, i), errp); if (!address) { return; } diff --git a/ui/vnc.c b/ui/vnc.c index 50016ff7ab4..b5b6f5cd06f 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -235,12 +235,12 @@ static VncServerInfo *vnc_server_info_get(VncDisplay *vd) VncServerInfo *info; Error *err = NULL; - if (!vd->listener || !vd->listener->nsioc) { + if (!vd->listener || !qio_net_listener_nsioc(vd->listener)) { return NULL; } info = g_malloc0(sizeof(*info)); - vnc_init_basic_info_from_server_addr(vd->listener->sioc[0], + vnc_init_basic_info_from_server_addr(qio_net_listener_sioc(vd->listener, 0), qapi_VncServerInfo_base(info), &err); info->auth = g_strdup(vnc_auth_name(vd)); if (err) { @@ -377,7 +377,7 @@ VncInfo *qmp_query_vnc(Error **errp) VncDisplay *vd = vnc_display_find(NULL); SocketAddress *addr = NULL; - if (vd == NULL || !vd->listener || !vd->listener->nsioc) { + if (vd == NULL || !vd->listener || !qio_net_listener_nsioc(vd->listener)) { info->enabled = false; } else { info->enabled = true; @@ -386,8 +386,8 @@ VncInfo *qmp_query_vnc(Error **errp) info->has_clients = true; info->clients = qmp_query_client_list(vd); - addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], - errp); + addr = qio_channel_socket_get_local_address( + qio_net_listener_sioc(vd->listener, 0), errp); if (!addr) { goto out_error; } @@ -549,6 +549,8 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp) size_t i; QTAILQ_FOREACH(vd, &vnc_displays, next) { + size_t nsioc = 0; + info = g_new0(VncInfo2, 1); info->id = g_strdup(vd->id); info->clients = qmp_query_client_list(vd); @@ -559,14 +561,21 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp) "device", &error_abort)); info->display = g_strdup(dev->id); } - for (i = 0; vd->listener != NULL && i < vd->listener->nsioc; i++) { - info->server = qmp_query_server_entry( - vd->listener->sioc[i], false, vd->auth, vd->subauth, - info->server); + if (vd->listener != NULL) { + nsioc = qio_net_listener_nsioc(vd->listener); } - for (i = 0; vd->wslistener != NULL && i < vd->wslistener->nsioc; i++) { + for (i = 0; i < nsioc; i++) { info->server = qmp_query_server_entry( - vd->wslistener->sioc[i], true, vd->ws_auth, + qio_net_listener_sioc(vd->listener, i), false, vd->auth, + vd->subauth, info->server); + } + nsioc = 0; + if (vd->wslistener) { + nsioc = qio_net_listener_nsioc(vd->wslistener); + } + for (i = 0; i < nsioc; i++) { + info->server = qmp_query_server_entry( + qio_net_listener_sioc(vd->wslistener, i), true, vd->ws_auth, vd->ws_subauth, info->server); } @@ -3550,11 +3559,12 @@ static void vnc_display_print_local_addr(VncDisplay *vd) { SocketAddress *addr; - if (!vd->listener || !vd->listener->nsioc) { + if (!vd->listener || !qio_net_listener_nsioc(vd->listener)) { return; } - addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], NULL); + addr = qio_channel_socket_get_local_address( + qio_net_listener_sioc(vd->listener, 0), NULL); if (!addr) { return; } -- 2.51.1
