From 6242dab47cbab3cc8be62184414f3f2a52a3f157 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 21 Feb 2024 12:40:00 +0100 Subject: [PATCH] jack: set global_mix safely Keep track of the active number of mixer ports and update the global mix io in sync with the data thread because that is where we will check the state of the global mix io. This is mostly important for output ports. When removing all links from an output port, we first will clear all the mixer io and then remove the global mixer with client_node_port_set_mix_info(). If we don't clear the io before that, the data thread will be using that buffers as they are cleared. See !1915 --- pipewire-jack/src/pipewire-jack.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 60406454c..db2c9381e 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -566,7 +566,15 @@ do_mix_set_io(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) { const struct io_info *info = data; + struct port *port = info->mix->port; info->mix->io = info->data; + if (info->mix->io) { + if (port->n_mix++ == 0 && port->global_mix != NULL) + port->global_mix->io = &port->io; + } else { + if (--port->n_mix == 0 && port->global_mix != NULL) + port->global_mix->io = NULL; + } return 0; } @@ -587,10 +595,11 @@ static void init_mix(struct mix *mix, uint32_t mix_id, struct port *port, uint32 mix->io = NULL; mix->n_buffers = 0; spa_list_init(&mix->queue); - if (mix_id == SPA_ID_INVALID) + if (mix_id == SPA_ID_INVALID) { port->global_mix = mix; - else if (port->n_mix++ == 0 && port->global_mix != NULL) - mix_set_io(port->global_mix, &port->io); + if (port->n_mix > 0) + mix_set_io(port->global_mix, &port->io); + } } static struct mix *find_mix_peer(struct client *c, uint32_t peer_id) { @@ -677,8 +686,6 @@ static void free_mix(struct client *c, struct mix *mix) spa_list_remove(&mix->port_link); if (mix->id == SPA_ID_INVALID) port->global_mix = NULL; - else if (--port->n_mix == 0 && port->global_mix != NULL) - mix_set_io(port->global_mix, NULL); spa_list_remove(&mix->link); spa_list_append(&c->free_mix, &mix->link); }