mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -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;
 | 
			
		||||
	uint32_t peer_id;
 | 
			
		||||
	uint32_t n_buffers;
 | 
			
		||||
	uint32_t impl_mix_id;
 | 
			
		||||
	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->port = p;
 | 
			
		||||
	mix->n_buffers = 0;
 | 
			
		||||
	mix->impl_mix_id = SPA_ID_INVALID;
 | 
			
		||||
	return mix;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
| 
						 | 
				
			
			@ -1437,6 +1439,7 @@ static int port_init_mix(void *data, struct pw_impl_port_mix *mix)
 | 
			
		|||
	*mix->io = SPA_IO_BUFFERS_INIT;
 | 
			
		||||
 | 
			
		||||
	m->peer_id = mix->peer_id;
 | 
			
		||||
	m->impl_mix_id = mix->id;
 | 
			
		||||
 | 
			
		||||
	if (impl->resource && impl->resource->version >= 4)
 | 
			
		||||
		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",
 | 
			
		||||
			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;
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue