mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
client-node: handle releasing mix for destroyed port
The remote end may destroy the port via client_node_port_update(), before corresponding pw_impl_port_mix are released. clear_port() removes all struct mix, but this prevents the pw_impl_port_mix from being removed from io_map, which causes stale mix ids be left in io_map, so we end up continuously allocating new io areas. Make lifecycle of io_map entries match port_init_mix/release_mix exactly, separately from the lifecycle of the port and struct mix. When freeing struct mix in port_release_mix(), make sure it corresponds to the mix being released.
This commit is contained in:
parent
e90b2cb338
commit
1196429c09
1 changed files with 11 additions and 2 deletions
|
|
@ -53,6 +53,7 @@ struct mix {
|
||||||
struct port *port;
|
struct port *port;
|
||||||
uint32_t peer_id;
|
uint32_t peer_id;
|
||||||
uint32_t n_buffers;
|
uint32_t n_buffers;
|
||||||
|
uint32_t impl_mix_id;
|
||||||
struct buffer buffers[MAX_BUFFERS];
|
struct buffer buffers[MAX_BUFFERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -228,6 +229,7 @@ static struct mix *create_mix(struct port *p, uint32_t mix_id)
|
||||||
mix->mix_id = mix_id;
|
mix->mix_id = mix_id;
|
||||||
mix->port = p;
|
mix->port = p;
|
||||||
mix->n_buffers = 0;
|
mix->n_buffers = 0;
|
||||||
|
mix->impl_mix_id = SPA_ID_INVALID;
|
||||||
return mix;
|
return mix;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
@ -1437,6 +1439,7 @@ static int port_init_mix(void *data, struct pw_impl_port_mix *mix)
|
||||||
*mix->io = SPA_IO_BUFFERS_INIT;
|
*mix->io = SPA_IO_BUFFERS_INIT;
|
||||||
|
|
||||||
m->peer_id = mix->peer_id;
|
m->peer_id = mix->peer_id;
|
||||||
|
m->impl_mix_id = mix->id;
|
||||||
|
|
||||||
if (impl->resource && impl->resource->version >= 4)
|
if (impl->resource && impl->resource->version >= 4)
|
||||||
pw_client_node_resource_port_set_mix_info(impl->resource,
|
pw_client_node_resource_port_set_mix_info(impl->resource,
|
||||||
|
|
@ -1462,7 +1465,7 @@ static int port_release_mix(void *data, struct pw_impl_port_mix *mix)
|
||||||
pw_log_debug("%p: remove mix id:%d io:%p",
|
pw_log_debug("%p: remove mix id:%d io:%p",
|
||||||
impl, mix->id, mix->io);
|
impl, mix->id, mix->io);
|
||||||
|
|
||||||
if ((m = find_mix(port, mix->port.port_id)) == NULL)
|
if (!pw_map_has_item(&impl->io_map, mix->id))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (impl->resource && impl->resource->version >= 4)
|
if (impl->resource && impl->resource->version >= 4)
|
||||||
|
|
@ -1471,7 +1474,13 @@ static int port_release_mix(void *data, struct pw_impl_port_mix *mix)
|
||||||
mix->port.port_id, SPA_ID_INVALID, NULL);
|
mix->port.port_id, SPA_ID_INVALID, NULL);
|
||||||
|
|
||||||
pw_map_remove(&impl->io_map, mix->id);
|
pw_map_remove(&impl->io_map, mix->id);
|
||||||
free_mix(port, m);
|
|
||||||
|
m = find_mix(port, mix->port.port_id);
|
||||||
|
if (m && m->impl_mix_id == mix->id)
|
||||||
|
free_mix(port, m);
|
||||||
|
else
|
||||||
|
pw_log_debug("%p: already cleared mix id:%d port-id:%d",
|
||||||
|
impl, mix->id, mix->port.port_id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue